mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-20 04:56:37 +00:00
Compare commits
11 Commits
openfaaslt
...
0.11.3
Author | SHA1 | Date | |
---|---|---|---|
dca036ee51 | |||
583f5ad1b0 | |||
659f98cc0d | |||
c7d9353991 | |||
29bb5ad9cc | |||
6262ff2f4a | |||
1d86c62792 | |||
0bf221b286 | |||
e8c2eeb052 | |||
6c0f91e810 | |||
27ba86fb52 |
@ -18,8 +18,8 @@ runcmd:
|
|||||||
- mkdir -p /opt/cni/bin
|
- mkdir -p /opt/cni/bin
|
||||||
- curl -sSL https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz | tar -xz -C /opt/cni/bin
|
- curl -sSL https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz | tar -xz -C /opt/cni/bin
|
||||||
- mkdir -p /go/src/github.com/openfaas/
|
- mkdir -p /go/src/github.com/openfaas/
|
||||||
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
|
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd
|
||||||
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
||||||
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
||||||
- systemctl status -l containerd --no-pager
|
- systemctl status -l containerd --no-pager
|
||||||
- journalctl -u faasd-provider --no-pager
|
- journalctl -u faasd-provider --no-pager
|
||||||
|
@ -46,7 +46,12 @@ var rootCommand = &cobra.Command{
|
|||||||
Use: "faasd",
|
Use: "faasd",
|
||||||
Short: "Start faasd",
|
Short: "Start faasd",
|
||||||
Long: `
|
Long: `
|
||||||
faasd - serverless without Kubernetes
|
faasd - Serverless For Everyone Else
|
||||||
|
|
||||||
|
Learn how to build, secure, and monitor functions with faasd with
|
||||||
|
the eBook:
|
||||||
|
|
||||||
|
https://gumroad.com/l/serverless-for-everyone-else
|
||||||
`,
|
`,
|
||||||
RunE: runRootCommand,
|
RunE: runRootCommand,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
|
@ -41,7 +41,7 @@ services:
|
|||||||
- "127.0.0.1:9090:9090"
|
- "127.0.0.1:9090:9090"
|
||||||
|
|
||||||
gateway:
|
gateway:
|
||||||
image: ghcr.io/openfaas/gateway:0.20.8
|
image: ghcr.io/openfaas/gateway:0.20.11
|
||||||
environment:
|
environment:
|
||||||
- basic_auth=true
|
- basic_auth=true
|
||||||
- functions_provider_url=http://faasd-provider:8081/
|
- functions_provider_url=http://faasd-provider:8081/
|
||||||
|
@ -169,7 +169,7 @@ You may find alternative package names for CentOS and other Linux distributions.
|
|||||||
#### Install Go 1.13 (x86_64)
|
#### Install Go 1.13 (x86_64)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sSLf https://dl.google.com/go/go1.13.6.linux-amd64.tar.gz > /tmp/go.tgz
|
curl -SLf https://golang.org/dl/go1.16.linux-amd64.tar.gz > /tmp/go.tgz
|
||||||
sudo rm -rf /usr/local/go/
|
sudo rm -rf /usr/local/go/
|
||||||
sudo mkdir -p /usr/local/go/
|
sudo mkdir -p /usr/local/go/
|
||||||
sudo tar -xvf /tmp/go.tgz -C /usr/local/go/ --strip-components=1
|
sudo tar -xvf /tmp/go.tgz -C /usr/local/go/ --strip-components=1
|
||||||
@ -190,7 +190,7 @@ echo "export PATH=\$PATH:/usr/local/go/bin/" | tee -a $HOME/.bash_profile
|
|||||||
#### Or on Raspberry Pi (armhf)
|
#### Or on Raspberry Pi (armhf)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -SLsf https://dl.google.com/go/go1.13.6.linux-armv6l.tar.gz > go.tgz
|
curl -SLsf https://golang.org/dl/go1.16.linux-armv6l.tar.gz > go.tgz
|
||||||
sudo rm -rf /usr/local/go/
|
sudo rm -rf /usr/local/go/
|
||||||
sudo mkdir -p /usr/local/go/
|
sudo mkdir -p /usr/local/go/
|
||||||
sudo tar -xvf go.tgz -C /usr/local/go/ --strip-components=1
|
sudo tar -xvf go.tgz -C /usr/local/go/ --strip-components=1
|
||||||
@ -233,7 +233,7 @@ export SUFFIX="-armhf"
|
|||||||
export SUFFIX="-arm64"
|
export SUFFIX="-arm64"
|
||||||
|
|
||||||
# Then download
|
# Then download
|
||||||
curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd$SUFFIX" \
|
curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd$SUFFIX" \
|
||||||
-o "/tmp/faasd" \
|
-o "/tmp/faasd" \
|
||||||
&& chmod +x "/tmp/faasd"
|
&& chmod +x "/tmp/faasd"
|
||||||
sudo mv /tmp/faasd /usr/local/bin/
|
sudo mv /tmp/faasd /usr/local/bin/
|
||||||
|
@ -20,8 +20,8 @@ runcmd:
|
|||||||
- mkdir -p /var/lib/faasd/secrets/
|
- mkdir -p /var/lib/faasd/secrets/
|
||||||
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
|
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
|
||||||
- echo admin > /var/lib/faasd/secrets/basic-auth-user
|
- echo admin > /var/lib/faasd/secrets/basic-auth-user
|
||||||
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
|
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd
|
||||||
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
||||||
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
||||||
- systemctl status -l containerd --no-pager
|
- systemctl status -l containerd --no-pager
|
||||||
- journalctl -u faasd-provider --no-pager
|
- journalctl -u faasd-provider --no-pager
|
||||||
|
@ -41,8 +41,8 @@ runcmd:
|
|||||||
- mkdir -p /var/lib/faasd/secrets/
|
- mkdir -p /var/lib/faasd/secrets/
|
||||||
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
|
- echo ${gw_password} > /var/lib/faasd/secrets/basic-auth-password
|
||||||
- echo admin > /var/lib/faasd/secrets/basic-auth-user
|
- echo admin > /var/lib/faasd/secrets/basic-auth-user
|
||||||
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.10.2 https://github.com/openfaas/faasd
|
- cd /go/src/github.com/openfaas/ && git clone --depth 1 --branch 0.11.0 https://github.com/openfaas/faasd
|
||||||
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.10.2/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
- curl -fSLs "https://github.com/openfaas/faasd/releases/download/0.11.0/faasd" --output "/usr/local/bin/faasd" && chmod a+x "/usr/local/bin/faasd"
|
||||||
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
- cd /go/src/github.com/openfaas/faasd/ && /usr/local/bin/faasd install
|
||||||
- systemctl status -l containerd --no-pager
|
- systemctl status -l containerd --no-pager
|
||||||
- journalctl -u faasd-provider --no-pager
|
- journalctl -u faasd-provider --no-pager
|
||||||
|
2
go.mod
2
go.mod
@ -30,7 +30,7 @@ require (
|
|||||||
github.com/opencontainers/runc v1.0.0-rc9 // indirect
|
github.com/opencontainers/runc v1.0.0-rc9 // indirect
|
||||||
github.com/opencontainers/runtime-spec v1.0.2
|
github.com/opencontainers/runtime-spec v1.0.2
|
||||||
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
|
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
|
||||||
github.com/openfaas/faas-provider v0.16.2
|
github.com/openfaas/faas-provider v0.17.3
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prometheus/procfs v0.2.0 // indirect
|
github.com/prometheus/procfs v0.2.0 // indirect
|
||||||
github.com/sethvargo/go-password v0.1.3
|
github.com/sethvargo/go-password v0.1.3
|
||||||
|
10
go.sum
10
go.sum
@ -181,8 +181,14 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
|
|||||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||||
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 h1:JJjthDw7WziZQ7sC5C+M2872mIdud5R+s6Cb0cXyPuA=
|
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4 h1:JJjthDw7WziZQ7sC5C+M2872mIdud5R+s6Cb0cXyPuA=
|
||||||
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14=
|
github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4/go.mod h1:E0m2rLup0Vvxg53BKxGgaYAGcZa3Xl+vvL7vSi5yQ14=
|
||||||
github.com/openfaas/faas-provider v0.16.2 h1:ChpiZh1RM8zFIzvp31OPlKpTbh5Lcm7f91WCFcpW4gA=
|
github.com/openfaas/faas-provider v0.17.0 h1:4rT8CosKhI5xaAMqbyihEgR6KefO/ViJdF0a8THTgwM=
|
||||||
github.com/openfaas/faas-provider v0.16.2/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
github.com/openfaas/faas-provider v0.17.0/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
||||||
|
github.com/openfaas/faas-provider v0.17.1 h1:P5xTLN+/08PLLh4auIlO/PaUD/J3BUTmaC3en8N5zbs=
|
||||||
|
github.com/openfaas/faas-provider v0.17.1/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
||||||
|
github.com/openfaas/faas-provider v0.17.2 h1:jZ+Z83A/tyJoI1AnpyLN3o0B4K0UEsz1YJ3erASMu+s=
|
||||||
|
github.com/openfaas/faas-provider v0.17.2/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
||||||
|
github.com/openfaas/faas-provider v0.17.3 h1:LN76lrXUKAx27o5X8l+daKWEzsdiW2E99jMOlI1SO5Q=
|
||||||
|
github.com/openfaas/faas-provider v0.17.3/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cninetwork
|
package cninetwork
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
gocni "github.com/containerd/go-cni"
|
gocni "github.com/containerd/go-cni"
|
||||||
@ -19,21 +21,31 @@ import (
|
|||||||
const (
|
const (
|
||||||
// CNIBinDir describes the directory where the CNI binaries are stored
|
// CNIBinDir describes the directory where the CNI binaries are stored
|
||||||
CNIBinDir = "/opt/cni/bin"
|
CNIBinDir = "/opt/cni/bin"
|
||||||
|
|
||||||
// CNIConfDir describes the directory where the CNI plugin's configuration is stored
|
// CNIConfDir describes the directory where the CNI plugin's configuration is stored
|
||||||
CNIConfDir = "/etc/cni/net.d"
|
CNIConfDir = "/etc/cni/net.d"
|
||||||
|
|
||||||
// NetNSPathFmt gives the path to the a process network namespace, given the pid
|
// NetNSPathFmt gives the path to the a process network namespace, given the pid
|
||||||
NetNSPathFmt = "/proc/%d/ns/net"
|
NetNSPathFmt = "/proc/%d/ns/net"
|
||||||
// CNIResultsDir is the directory CNI stores allocated IP for containers
|
|
||||||
CNIResultsDir = "/var/lib/cni/results"
|
// CNIDataDir is the directory CNI stores allocated IP for containers
|
||||||
|
CNIDataDir = "/var/run/cni"
|
||||||
|
|
||||||
// defaultCNIConfFilename is the vanity filename of default CNI configuration file
|
// defaultCNIConfFilename is the vanity filename of default CNI configuration file
|
||||||
defaultCNIConfFilename = "10-openfaas.conflist"
|
defaultCNIConfFilename = "10-openfaas.conflist"
|
||||||
|
|
||||||
// defaultNetworkName names the "docker-bridge"-like CNI plugin-chain installed when no other CNI configuration is present.
|
// defaultNetworkName names the "docker-bridge"-like CNI plugin-chain installed when no other CNI configuration is present.
|
||||||
// This value appears in iptables comments created by CNI.
|
// This value appears in iptables comments created by CNI.
|
||||||
defaultNetworkName = "openfaas-cni-bridge"
|
defaultNetworkName = "openfaas-cni-bridge"
|
||||||
|
|
||||||
// defaultBridgeName is the default bridge device name used in the defaultCNIConf
|
// defaultBridgeName is the default bridge device name used in the defaultCNIConf
|
||||||
defaultBridgeName = "openfaas0"
|
defaultBridgeName = "openfaas0"
|
||||||
|
|
||||||
// defaultSubnet is the default subnet used in the defaultCNIConf -- this value is set to not collide with common container networking subnets:
|
// defaultSubnet is the default subnet used in the defaultCNIConf -- this value is set to not collide with common container networking subnets:
|
||||||
defaultSubnet = "10.62.0.0/16"
|
defaultSubnet = "10.62.0.0/16"
|
||||||
|
|
||||||
|
// defaultIfPrefix is the interface name to be created in the container
|
||||||
|
defaultIfPrefix = "eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultCNIConf is a CNI configuration that enables network access to containers (docker-bridge style)
|
// defaultCNIConf is a CNI configuration that enables network access to containers (docker-bridge style)
|
||||||
@ -50,6 +62,7 @@ var defaultCNIConf = fmt.Sprintf(`
|
|||||||
"ipam": {
|
"ipam": {
|
||||||
"type": "host-local",
|
"type": "host-local",
|
||||||
"subnet": "%s",
|
"subnet": "%s",
|
||||||
|
"dataDir": "%s",
|
||||||
"routes": [
|
"routes": [
|
||||||
{ "dst": "0.0.0.0/0" }
|
{ "dst": "0.0.0.0/0" }
|
||||||
]
|
]
|
||||||
@ -60,7 +73,7 @@ var defaultCNIConf = fmt.Sprintf(`
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
`, defaultNetworkName, defaultBridgeName, defaultSubnet)
|
`, defaultNetworkName, defaultBridgeName, defaultSubnet, CNIDataDir)
|
||||||
|
|
||||||
// InitNetwork writes configlist file and initializes CNI network
|
// InitNetwork writes configlist file and initializes CNI network
|
||||||
func InitNetwork() (gocni.CNI, error) {
|
func InitNetwork() (gocni.CNI, error) {
|
||||||
@ -75,11 +88,14 @@ func InitNetwork() (gocni.CNI, error) {
|
|||||||
netConfig := path.Join(CNIConfDir, defaultCNIConfFilename)
|
netConfig := path.Join(CNIConfDir, defaultCNIConfFilename)
|
||||||
if err := ioutil.WriteFile(netConfig, []byte(defaultCNIConf), 644); err != nil {
|
if err := ioutil.WriteFile(netConfig, []byte(defaultCNIConf), 644); err != nil {
|
||||||
return nil, fmt.Errorf("cannot write network config: %s", defaultCNIConfFilename)
|
return nil, fmt.Errorf("cannot write network config: %s", defaultCNIConfFilename)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize CNI library
|
// Initialize CNI library
|
||||||
cni, err := gocni.New(gocni.WithPluginConfDir(CNIConfDir),
|
cni, err := gocni.New(
|
||||||
gocni.WithPluginDir([]string{CNIBinDir}))
|
gocni.WithPluginConfDir(CNIConfDir),
|
||||||
|
gocni.WithPluginDir([]string{CNIBinDir}),
|
||||||
|
gocni.WithInterfacePrefix(defaultIfPrefix),
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error initializing cni: %s", err)
|
return nil, fmt.Errorf("error initializing cni: %s", err)
|
||||||
@ -131,43 +147,61 @@ func DeleteCNINetwork(ctx context.Context, cni gocni.CNI, client *containerd.Cli
|
|||||||
return errors.Wrapf(containerErr, "Unable to find container: %s, error: %s", name, containerErr)
|
return errors.Wrapf(containerErr, "Unable to find container: %s, error: %s", name, containerErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIPAddress returns the IP address of the created container
|
// GetIPAddress returns the IP address from container based on container name and PID
|
||||||
func GetIPAddress(result *gocni.CNIResult, task containerd.Task) (net.IP, error) {
|
func GetIPAddress(container string, PID uint32) (string, error) {
|
||||||
// Get the IP of the created interface
|
CNIDir := path.Join(CNIDataDir, defaultNetworkName)
|
||||||
var ip net.IP
|
|
||||||
for ifName, config := range result.Interfaces {
|
files, err := ioutil.ReadDir(CNIDir)
|
||||||
if config.Sandbox == netNamespace(task) {
|
if err != nil {
|
||||||
for _, ipConfig := range config.IPConfigs {
|
return "", fmt.Errorf("failed to read CNI dir for container %s: %v", container, err)
|
||||||
if ifName != "lo" && ipConfig.IP.To4() != nil {
|
}
|
||||||
ip = ipConfig.IP
|
|
||||||
}
|
for _, file := range files {
|
||||||
}
|
// each fileName is an IP address
|
||||||
|
fileName := file.Name()
|
||||||
|
|
||||||
|
resultsFile := filepath.Join(CNIDir, fileName)
|
||||||
|
found, err := isCNIResultForPID(resultsFile, container, PID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
return fileName, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ip == nil {
|
|
||||||
return nil, fmt.Errorf("unable to get IP address for: %s", task.ID())
|
return "", fmt.Errorf("unable to get IP address for container: %s", container)
|
||||||
}
|
|
||||||
return ip, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIPfromPID(pid int) (*net.IP, error) {
|
// isCNIResultForPID confirms if the CNI result file contains the
|
||||||
// https://github.com/weaveworks/weave/blob/master/net/netdev.go
|
// process name, PID and interface name
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// /var/run/cni/openfaas-cni-bridge/10.62.0.2
|
||||||
|
//
|
||||||
|
// nats-621
|
||||||
|
// eth1
|
||||||
|
func isCNIResultForPID(fileName, container string, PID uint32) (bool, error) {
|
||||||
|
found := false
|
||||||
|
|
||||||
peerIDs, err := ConnectedToBridgeVethPeerIds(defaultBridgeName)
|
f, err := os.Open(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to find peers on: %s %s", defaultBridgeName, err)
|
return false, fmt.Errorf("failed to open CNI IP file for %s: %v", fileName, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
reader := bufio.NewReader(f)
|
||||||
|
processLine, _ := reader.ReadString('\n')
|
||||||
|
if strings.Contains(processLine, fmt.Sprintf("%s-%d", container, PID)) {
|
||||||
|
ethNameLine, _ := reader.ReadString('\n')
|
||||||
|
if strings.Contains(ethNameLine, defaultIfPrefix) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs, addrsErr := GetNetDevsByVethPeerIds(pid, peerIDs)
|
return found, nil
|
||||||
if addrsErr != nil {
|
|
||||||
return nil, fmt.Errorf("unable to find address for veth pair using: %v %s", peerIDs, addrsErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(addrs) > 0 && len(addrs[0].CIDRs) > 0 {
|
|
||||||
return &addrs[0].CIDRs[0].IP, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("no IP found for function")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CNIGateway returns the gateway for default subnet
|
// CNIGateway returns the gateway for default subnet
|
||||||
|
63
pkg/cninetwork/cni_network_test.go
Normal file
63
pkg/cninetwork/cni_network_test.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package cninetwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_isCNIResultForPID_Found(t *testing.T) {
|
||||||
|
body := `nats-621
|
||||||
|
eth1`
|
||||||
|
fileName := `10.62.0.2`
|
||||||
|
container := "nats"
|
||||||
|
PID := uint32(621)
|
||||||
|
fullPath := filepath.Join(os.TempDir(), fileName)
|
||||||
|
|
||||||
|
err := ioutil.WriteFile(fullPath, []byte(body), 0700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
os.Remove(fullPath)
|
||||||
|
}()
|
||||||
|
|
||||||
|
got, err := isCNIResultForPID(fullPath, container, PID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
want := true
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("want %v, but got %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_isCNIResultForPID_NoMatch(t *testing.T) {
|
||||||
|
body := `nats-621
|
||||||
|
eth1`
|
||||||
|
fileName := `10.62.0.3`
|
||||||
|
container := "gateway"
|
||||||
|
PID := uint32(621)
|
||||||
|
fullPath := filepath.Join(os.TempDir(), fileName)
|
||||||
|
|
||||||
|
err := ioutil.WriteFile(fullPath, []byte(body), 0700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
os.Remove(fullPath)
|
||||||
|
}()
|
||||||
|
|
||||||
|
got, err := isCNIResultForPID(fullPath, container, PID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
want := false
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("want %v, but got %v", want, got)
|
||||||
|
}
|
||||||
|
}
|
@ -1,118 +0,0 @@
|
|||||||
// Copyright Weaveworks
|
|
||||||
// github.com/weaveworks/weave/net
|
|
||||||
|
|
||||||
package cninetwork
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
|
||||||
"github.com/vishvananda/netns"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Dev struct {
|
|
||||||
Name string `json:"Name,omitempty"`
|
|
||||||
MAC net.HardwareAddr `json:"MAC,omitempty"`
|
|
||||||
CIDRs []*net.IPNet `json:"CIDRs,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConnectedToBridgeVethPeerIds returns peer indexes of veth links connected to
|
|
||||||
// the given bridge. The peer index is used to query from a container netns
|
|
||||||
// whether the container is connected to the bridge.
|
|
||||||
func ConnectedToBridgeVethPeerIds(bridgeName string) ([]int, error) {
|
|
||||||
var ids []int
|
|
||||||
|
|
||||||
br, err := netlink.LinkByName(bridgeName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
links, err := netlink.LinkList()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, link := range links {
|
|
||||||
if _, isveth := link.(*netlink.Veth); isveth && link.Attrs().MasterIndex == br.Attrs().Index {
|
|
||||||
peerID := link.Attrs().ParentIndex
|
|
||||||
if peerID == 0 {
|
|
||||||
// perhaps running on an older kernel where ParentIndex doesn't work.
|
|
||||||
// as fall-back, assume the peers are consecutive
|
|
||||||
peerID = link.Attrs().Index - 1
|
|
||||||
}
|
|
||||||
ids = append(ids, peerID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ids, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup the weave interface of a container
|
|
||||||
func GetWeaveNetDevs(processID int) ([]Dev, error) {
|
|
||||||
peerIDs, err := ConnectedToBridgeVethPeerIds("weave")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetNetDevsByVethPeerIds(processID, peerIDs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetNetDevsByVethPeerIds(processID int, peerIDs []int) ([]Dev, error) {
|
|
||||||
// Bail out if this container is running in the root namespace
|
|
||||||
netnsRoot, err := netns.GetFromPid(1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to open root namespace: %s", err)
|
|
||||||
}
|
|
||||||
defer netnsRoot.Close()
|
|
||||||
netnsContainer, err := netns.GetFromPid(processID)
|
|
||||||
if err != nil {
|
|
||||||
// Unable to find a namespace for this process - just return nothing
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
|
|
||||||
}
|
|
||||||
defer netnsContainer.Close()
|
|
||||||
if netnsRoot.Equal(netnsContainer) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert list of peerIDs into a map for faster lookup
|
|
||||||
indexes := make(map[int]struct{})
|
|
||||||
for _, id := range peerIDs {
|
|
||||||
indexes[id] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var netdevs []Dev
|
|
||||||
err = WithNetNS(netnsContainer, func() error {
|
|
||||||
links, err := netlink.LinkList()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, link := range links {
|
|
||||||
if _, found := indexes[link.Attrs().Index]; found {
|
|
||||||
netdev, err := linkToNetDev(link)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
netdevs = append(netdevs, netdev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return netdevs, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the weave bridge interface.
|
|
||||||
// NB: Should be called from the root network namespace.
|
|
||||||
func GetBridgeNetDev(bridgeName string) (Dev, error) {
|
|
||||||
link, err := netlink.LinkByName(bridgeName)
|
|
||||||
if err != nil {
|
|
||||||
return Dev{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return linkToNetDev(link)
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
// +build darwin
|
|
||||||
|
|
||||||
package cninetwork
|
|
||||||
|
|
||||||
import "github.com/vishvananda/netlink"
|
|
||||||
|
|
||||||
func linkToNetDev(link netlink.Link) (Dev, error) {
|
|
||||||
|
|
||||||
return Dev{}, nil
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
// +build linux
|
|
||||||
|
|
||||||
package cninetwork
|
|
||||||
|
|
||||||
import "github.com/vishvananda/netlink"
|
|
||||||
|
|
||||||
func linkToNetDev(link netlink.Link) (Dev, error) {
|
|
||||||
|
|
||||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
|
||||||
if err != nil {
|
|
||||||
return Dev{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
netDev := Dev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
netDev.CIDRs = append(netDev.CIDRs, addr.IPNet)
|
|
||||||
}
|
|
||||||
return netDev, nil
|
|
||||||
}
|
|
@ -29,8 +29,8 @@ import (
|
|||||||
|
|
||||||
const annotationLabelPrefix = "com.openfaas.annotations."
|
const annotationLabelPrefix = "com.openfaas.annotations."
|
||||||
|
|
||||||
|
// MakeDeployHandler returns a handler to deploy a function
|
||||||
func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string, alwaysPull bool) func(w http.ResponseWriter, r *http.Request) {
|
func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string, alwaysPull bool) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
if r.Body == nil {
|
if r.Body == nil {
|
||||||
@ -147,6 +147,7 @@ func deploy(ctx context.Context, req types.FunctionDeployment, client *container
|
|||||||
containerd.WithSnapshotter(snapshotter),
|
containerd.WithSnapshotter(snapshotter),
|
||||||
containerd.WithNewSnapshot(name+"-snapshot", image),
|
containerd.WithNewSnapshot(name+"-snapshot", image),
|
||||||
containerd.WithNewSpec(oci.WithImageConfig(image),
|
containerd.WithNewSpec(oci.WithImageConfig(image),
|
||||||
|
oci.WithHostname(name),
|
||||||
oci.WithCapabilities([]string{"CAP_NET_RAW"}),
|
oci.WithCapabilities([]string{"CAP_NET_RAW"}),
|
||||||
oci.WithMounts(mounts),
|
oci.WithMounts(mounts),
|
||||||
oci.WithEnv(envs),
|
oci.WithEnv(envs),
|
||||||
@ -199,17 +200,18 @@ func createTask(ctx context.Context, client *containerd.Client, container contai
|
|||||||
log.Printf("Container ID: %s\tTask ID %s:\tTask PID: %d\t\n", name, task.ID(), task.Pid())
|
log.Printf("Container ID: %s\tTask ID %s:\tTask PID: %d\t\n", name, task.ID(), task.Pid())
|
||||||
|
|
||||||
labels := map[string]string{}
|
labels := map[string]string{}
|
||||||
network, err := cninetwork.CreateCNINetwork(ctx, cni, task, labels)
|
_, err := cninetwork.CreateCNINetwork(ctx, cni, task, labels)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := cninetwork.GetIPAddress(network, task)
|
ip, err := cninetwork.GetIPAddress(name, task.Pid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("%s has IP: %s.\n", name, ip.String())
|
|
||||||
|
log.Printf("%s has IP: %s.\n", name, ip)
|
||||||
|
|
||||||
_, waitErr := task.Wait(ctx)
|
_, waitErr := task.Wait(ctx)
|
||||||
if waitErr != nil {
|
if waitErr != nil {
|
||||||
|
@ -3,9 +3,11 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
@ -26,6 +28,7 @@ type Function struct {
|
|||||||
secrets []string
|
secrets []string
|
||||||
envVars map[string]string
|
envVars map[string]string
|
||||||
envProcess string
|
envProcess string
|
||||||
|
createdAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListFunctions returns a map of all functions with running tasks on namespace
|
// ListFunctions returns a map of all functions with running tasks on namespace
|
||||||
@ -80,6 +83,11 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
|
|||||||
return Function{}, fmt.Errorf("unable to load function spec for reading secrets: %s, error %s", name, err)
|
return Function{}, fmt.Errorf("unable to load function spec for reading secrets: %s, error %s", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info, err := c.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return Function{}, fmt.Errorf("can't load info for: %s, error %s", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
envVars, envProcess := readEnvFromProcessEnv(spec.Process.Env)
|
envVars, envProcess := readEnvFromProcessEnv(spec.Process.Env)
|
||||||
secrets := readSecretsFromMounts(spec.Mounts)
|
secrets := readSecretsFromMounts(spec.Mounts)
|
||||||
|
|
||||||
@ -91,6 +99,7 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
|
|||||||
fn.secrets = secrets
|
fn.secrets = secrets
|
||||||
fn.envVars = envVars
|
fn.envVars = envVars
|
||||||
fn.envProcess = envProcess
|
fn.envProcess = envProcess
|
||||||
|
fn.createdAt = info.CreatedAt
|
||||||
|
|
||||||
replicas := 0
|
replicas := 0
|
||||||
task, err := c.Task(ctx, nil)
|
task, err := c.Task(ctx, nil)
|
||||||
@ -106,11 +115,11 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
|
|||||||
fn.pid = task.Pid()
|
fn.pid = task.Pid()
|
||||||
|
|
||||||
// Get container IP address
|
// Get container IP address
|
||||||
ip, err := cninetwork.GetIPfromPID(int(task.Pid()))
|
ip, err := cninetwork.GetIPAddress(name, task.Pid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Function{}, err
|
return Function{}, err
|
||||||
}
|
}
|
||||||
fn.IP = ip.String()
|
fn.IP = ip
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
replicas = 0
|
replicas = 0
|
||||||
|
@ -34,6 +34,7 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h
|
|||||||
Secrets: fn.secrets,
|
Secrets: fn.secrets,
|
||||||
EnvVars: fn.envVars,
|
EnvVars: fn.envVars,
|
||||||
EnvProcess: fn.envProcess,
|
EnvProcess: fn.envProcess,
|
||||||
|
CreatedAt: fn.createdAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +42,5 @@ func MakeReadHandler(client *containerd.Client) func(w http.ResponseWriter, r *h
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.Write(body)
|
w.Write(body)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ func MakeReplicaReaderHandler(client *containerd.Client) func(w http.ResponseWri
|
|||||||
Secrets: f.secrets,
|
Secrets: f.secrets,
|
||||||
EnvVars: f.envVars,
|
EnvVars: f.envVars,
|
||||||
EnvProcess: f.envProcess,
|
EnvProcess: f.envProcess,
|
||||||
|
CreatedAt: f.createdAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
functionBytes, _ := json.Marshal(found)
|
functionBytes, _ := json.Marshal(found)
|
||||||
|
@ -172,6 +172,7 @@ func (s *Supervisor) Start(svcs []Service) error {
|
|||||||
containerd.WithImage(image),
|
containerd.WithImage(image),
|
||||||
containerd.WithNewSnapshot(svc.Name+"-snapshot", image),
|
containerd.WithNewSnapshot(svc.Name+"-snapshot", image),
|
||||||
containerd.WithNewSpec(oci.WithImageConfig(image),
|
containerd.WithNewSpec(oci.WithImageConfig(image),
|
||||||
|
oci.WithHostname(svc.Name),
|
||||||
withUserOrDefault(svc.User),
|
withUserOrDefault(svc.User),
|
||||||
oci.WithCapabilities(svc.Caps),
|
oci.WithCapabilities(svc.Caps),
|
||||||
oci.WithMounts(mounts),
|
oci.WithMounts(mounts),
|
||||||
@ -193,19 +194,19 @@ func (s *Supervisor) Start(svcs []Service) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
labels := map[string]string{}
|
labels := map[string]string{}
|
||||||
network, err := cninetwork.CreateCNINetwork(ctx, s.cni, task, labels)
|
_, err = cninetwork.CreateCNINetwork(ctx, s.cni, task, labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error creating CNI for %s: %s", svc.Name, err)
|
log.Printf("Error creating CNI for %s: %s", svc.Name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := cninetwork.GetIPAddress(network, task)
|
ip, err := cninetwork.GetIPAddress(svc.Name, task.Pid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error getting IP for %s: %s", svc.Name, err)
|
log.Printf("Error getting IP for %s: %s", svc.Name, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("%s has IP: %s\n", newContainer.ID(), ip.String())
|
log.Printf("%s has IP: %s\n", newContainer.ID(), ip)
|
||||||
|
|
||||||
hosts, err := ioutil.ReadFile("hosts")
|
hosts, err := ioutil.ReadFile("hosts")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
26
vendor/github.com/openfaas/faas-provider/proxy/proxy.go
generated
vendored
26
vendor/github.com/openfaas/faas-provider/proxy/proxy.go
generated
vendored
@ -34,9 +34,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
watchdogPort = "8080"
|
watchdogPort = "8080"
|
||||||
defaultContentType = "text/plain"
|
defaultContentType = "text/plain"
|
||||||
errMissingFunctionName = "Please provide a valid route /function/function_name."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BaseURLResolver URL resolver for proxy requests
|
// BaseURLResolver URL resolver for proxy requests
|
||||||
@ -75,8 +74,9 @@ func NewHandlerFunc(config types.FaaSConfig, resolver BaseURLResolver) http.Hand
|
|||||||
http.MethodPut,
|
http.MethodPut,
|
||||||
http.MethodPatch,
|
http.MethodPatch,
|
||||||
http.MethodDelete,
|
http.MethodDelete,
|
||||||
http.MethodGet:
|
http.MethodGet,
|
||||||
|
http.MethodOptions,
|
||||||
|
http.MethodHead:
|
||||||
proxyRequest(w, r, proxyClient, resolver)
|
proxyRequest(w, r, proxyClient, resolver)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -136,15 +136,15 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
|
|||||||
pathVars := mux.Vars(originalReq)
|
pathVars := mux.Vars(originalReq)
|
||||||
functionName := pathVars["name"]
|
functionName := pathVars["name"]
|
||||||
if functionName == "" {
|
if functionName == "" {
|
||||||
httputil.Errorf(w, http.StatusBadRequest, errMissingFunctionName)
|
httputil.Errorf(w, http.StatusBadRequest, "Provide function name in the request path")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
functionAddr, resolveErr := resolver.Resolve(functionName)
|
functionAddr, resolveErr := resolver.Resolve(functionName)
|
||||||
if resolveErr != nil {
|
if resolveErr != nil {
|
||||||
// TODO: Should record the 404/not found error in Prometheus.
|
// TODO: Should record the 404/not found error in Prometheus.
|
||||||
log.Printf("resolver error: cannot find %s: %s\n", functionName, resolveErr.Error())
|
log.Printf("resolver error: no endpoints for %s: %s\n", functionName, resolveErr.Error())
|
||||||
httputil.Errorf(w, http.StatusNotFound, "Cannot find service: %s.", functionName)
|
httputil.Errorf(w, http.StatusServiceUnavailable, "No endpoints available for: %s.", functionName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +153,7 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
|
|||||||
httputil.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName)
|
httputil.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if proxyReq.Body != nil {
|
if proxyReq.Body != nil {
|
||||||
defer proxyReq.Body.Close()
|
defer proxyReq.Body.Close()
|
||||||
}
|
}
|
||||||
@ -167,7 +168,10 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
|
|||||||
httputil.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName)
|
httputil.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
|
||||||
|
if response.Body != nil {
|
||||||
|
defer response.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("%s took %f seconds\n", functionName, seconds.Seconds())
|
log.Printf("%s took %f seconds\n", functionName, seconds.Seconds())
|
||||||
|
|
||||||
@ -176,7 +180,9 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
|
|||||||
w.Header().Set("Content-Type", getContentType(originalReq.Header, response.Header))
|
w.Header().Set("Content-Type", getContentType(originalReq.Header, response.Header))
|
||||||
|
|
||||||
w.WriteHeader(response.StatusCode)
|
w.WriteHeader(response.StatusCode)
|
||||||
io.Copy(w, response.Body)
|
if response.Body != nil {
|
||||||
|
io.Copy(w, response.Body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildProxyRequest creates a request object for the proxy request, it will ensure that
|
// buildProxyRequest creates a request object for the proxy request, it will ensure that
|
||||||
|
10
vendor/github.com/openfaas/faas-provider/types/model.go
generated
vendored
10
vendor/github.com/openfaas/faas-provider/types/model.go
generated
vendored
@ -1,5 +1,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// FunctionDeployment represents a request to create or update a Function.
|
// FunctionDeployment represents a request to create or update a Function.
|
||||||
type FunctionDeployment struct {
|
type FunctionDeployment struct {
|
||||||
|
|
||||||
@ -100,7 +102,9 @@ type FunctionStatus struct {
|
|||||||
// mount-point.
|
// mount-point.
|
||||||
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"`
|
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"`
|
||||||
|
|
||||||
// ** Status fields *8
|
// ================
|
||||||
|
// Fields for status
|
||||||
|
// ================
|
||||||
|
|
||||||
// InvocationCount count of invocations
|
// InvocationCount count of invocations
|
||||||
InvocationCount float64 `json:"invocationCount,omitempty"`
|
InvocationCount float64 `json:"invocationCount,omitempty"`
|
||||||
@ -111,4 +115,8 @@ type FunctionStatus struct {
|
|||||||
// AvailableReplicas is the count of replicas ready to receive
|
// AvailableReplicas is the count of replicas ready to receive
|
||||||
// invocations as reported by the faas-provider
|
// invocations as reported by the faas-provider
|
||||||
AvailableReplicas uint64 `json:"availableReplicas,omitempty"`
|
AvailableReplicas uint64 `json:"availableReplicas,omitempty"`
|
||||||
|
|
||||||
|
// CreatedAt is the time read back from the faas backend's
|
||||||
|
// data store for when the function or its container was created.
|
||||||
|
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||||
}
|
}
|
||||||
|
2
vendor/modules.txt
generated
vendored
2
vendor/modules.txt
generated
vendored
@ -195,7 +195,7 @@ github.com/opencontainers/runtime-spec/specs-go
|
|||||||
# github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
|
# github.com/openfaas/faas v0.0.0-20201205125747-9bbb25e3c7c4
|
||||||
## explicit
|
## explicit
|
||||||
github.com/openfaas/faas/gateway/requests
|
github.com/openfaas/faas/gateway/requests
|
||||||
# github.com/openfaas/faas-provider v0.16.2
|
# github.com/openfaas/faas-provider v0.17.3
|
||||||
## explicit
|
## explicit
|
||||||
github.com/openfaas/faas-provider
|
github.com/openfaas/faas-provider
|
||||||
github.com/openfaas/faas-provider/auth
|
github.com/openfaas/faas-provider/auth
|
||||||
|
Reference in New Issue
Block a user