Compare commits

...

3 Commits
0.7.9 ... 0.8.0

Author SHA1 Message Date
70e7e0d25a Apply gofmt
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2020-03-01 20:13:18 +00:00
be8574ecd0 Always pull images by default
The behaviour prior to this patch caused some confusion for
users since they expected a behaviour like Swarm / Kubernetes
which always pulls images by default, even if cached. I've tested
the change and it is working as expected. By default images are
always pulled upon deployment.

To revert to the prior behaviour, simply add to faasd up:
--pull-policy=IfNotPresent

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2020-03-01 20:13:18 +00:00
a0110b3019 Makefile: added labels to test-e2e
Signed-off-by: kadern0 <kaderno@gmail.com>
2020-02-27 21:56:43 +00:00
9 changed files with 157 additions and 114 deletions

View File

@ -37,9 +37,10 @@ prepare-test:
.PHONY: test-e2e
test-e2e:
sudo cat /var/lib/faasd/secrets/basic-auth-password | /usr/local/bin/faas-cli login --password-stdin
/usr/local/bin/faas-cli store deploy figlet --env write_timeout=1s --env read_timeout=1s
/usr/local/bin/faas-cli store deploy figlet --env write_timeout=1s --env read_timeout=1s --label testing=true
sleep 5
/usr/local/bin/faas-cli list -v
/usr/local/bin/faas-cli describe figlet | grep testing
uname | /usr/local/bin/faas-cli invoke figlet
uname | /usr/local/bin/faas-cli invoke figlet --async
sleep 10

View File

@ -19,13 +19,25 @@ import (
"github.com/spf13/cobra"
)
var providerCmd = &cobra.Command{
func makeProviderCmd() *cobra.Command {
var command = &cobra.Command{
Use: "provider",
Short: "Run the faasd-provider",
RunE: runProvider,
}
}
func runProvider(_ *cobra.Command, _ []string) error {
command.Flags().String("pull-policy", "Always", `Set to "Always" to force a pull of images upon deployment, or "IfNotPresent" to try to use a cached image.`)
command.RunE = func(_ *cobra.Command, _ []string) error {
pullPolicy, flagErr := command.Flags().GetString("pull-policy")
if flagErr != nil {
return flagErr
}
alwaysPull := false
if pullPolicy == "Always" {
alwaysPull = true
}
config, providerConfig, err := config.ReadFromEnv(types.OsEnv{})
if err != nil {
@ -72,11 +84,11 @@ func runProvider(_ *cobra.Command, _ []string) error {
bootstrapHandlers := types.FaaSHandlers{
FunctionProxy: proxy.NewHandlerFunc(*config, invokeResolver),
DeleteHandler: handlers.MakeDeleteHandler(client, cni),
DeployHandler: handlers.MakeDeployHandler(client, cni, userSecretPath),
DeployHandler: handlers.MakeDeployHandler(client, cni, userSecretPath, alwaysPull),
FunctionReader: handlers.MakeReadHandler(client),
ReplicaReader: handlers.MakeReplicaReaderHandler(client),
ReplicaUpdater: handlers.MakeReplicaUpdateHandler(client, cni),
UpdateHandler: handlers.MakeUpdateHandler(client, cni, userSecretPath),
UpdateHandler: handlers.MakeUpdateHandler(client, cni, userSecretPath, alwaysPull),
HealthHandler: func(w http.ResponseWriter, r *http.Request) {},
InfoHandler: handlers.MakeInfoHandler(Version, GitCommit),
ListNamespaceHandler: listNamespaces(),
@ -93,8 +105,10 @@ func runProvider(_ *cobra.Command, _ []string) error {
log.Printf("Listening on TCP port: %d\n", *config.TCPPort)
bootstrap.Serve(&bootstrapHandlers, config)
return nil
}
return command
}
func listNamespaces() func(w http.ResponseWriter, r *http.Request) {

View File

@ -14,7 +14,7 @@ func init() {
rootCommand.AddCommand(versionCmd)
rootCommand.AddCommand(upCmd)
rootCommand.AddCommand(installCmd)
rootCommand.AddCommand(providerCmd)
rootCommand.AddCommand(makeProviderCmd())
rootCommand.AddCommand(collectCmd)
}

View File

@ -14,8 +14,8 @@ import (
"github.com/pkg/errors"
"github.com/openfaas/faasd/pkg"
"github.com/alexellis/k3sup/pkg/env"
"github.com/openfaas/faasd/pkg"
"github.com/sethvargo/go-password/password"
"github.com/spf13/cobra"
)
@ -116,6 +116,7 @@ func runUp(_ *cobra.Command, _ []string) error {
log.Println(fileErr)
return
}
host := ""
lines := strings.Split(string(fileData), "\n")
for _, line := range lines {
@ -172,7 +173,7 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
wd, _ := os.Getwd()
return []pkg.Service{
pkg.Service{
{
Name: "basic-auth-plugin",
Image: "docker.io/openfaas/basic-auth-plugin:0.18.10" + archSuffix,
Env: []string{
@ -182,11 +183,11 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
"pass_filename=basic-auth-password",
},
Mounts: []pkg.Mount{
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-password"),
Dest: path.Join(containerSecretMountDir, "basic-auth-password"),
},
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-user"),
Dest: path.Join(containerSecretMountDir, "basic-auth-user"),
},
@ -194,26 +195,26 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
Caps: []string{"CAP_NET_RAW"},
Args: nil,
},
pkg.Service{
{
Name: "nats",
Env: []string{""},
Image: "docker.io/library/nats-streaming:0.11.2",
Caps: []string{},
Args: []string{"/nats-streaming-server", "-m", "8222", "--store=memory", "--cluster_id=faas-cluster"},
},
pkg.Service{
{
Name: "prometheus",
Env: []string{},
Image: "docker.io/prom/prometheus:v2.14.0",
Mounts: []pkg.Mount{
pkg.Mount{
{
Src: path.Join(wd, "prometheus.yml"),
Dest: "/etc/prometheus/prometheus.yml",
},
},
Caps: []string{"CAP_NET_RAW"},
},
pkg.Service{
{
Name: "gateway",
Env: []string{
"basic_auth=true",
@ -231,18 +232,18 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
},
Image: "docker.io/openfaas/gateway:0.18.8" + archSuffix,
Mounts: []pkg.Mount{
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-password"),
Dest: path.Join(containerSecretMountDir, "basic-auth-password"),
},
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-user"),
Dest: path.Join(containerSecretMountDir, "basic-auth-user"),
},
},
Caps: []string{"CAP_NET_RAW"},
},
pkg.Service{
{
Name: "queue-worker",
Env: []string{
"faas_nats_address=nats",
@ -257,11 +258,11 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
},
Image: "docker.io/openfaas/queue-worker:0.9.0",
Mounts: []pkg.Mount{
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-password"),
Dest: path.Join(containerSecretMountDir, "basic-auth-password"),
},
pkg.Mount{
{
Src: path.Join(path.Join(wd, "secrets"), "basic-auth-user"),
Dest: path.Join(containerSecretMountDir, "basic-auth-user"),
},

View File

@ -8,12 +8,12 @@ import (
"log"
"net/http"
cninetwork "github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
"github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces"
gocni "github.com/containerd/go-cni"
"github.com/openfaas/faas/gateway/requests"
cninetwork "github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
)
func MakeDeleteHandler(client *containerd.Client, cni gocni.CNI) func(w http.ResponseWriter, r *http.Request) {

View File

@ -23,7 +23,7 @@ import (
"github.com/pkg/errors"
)
func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string) 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) {
@ -54,7 +54,7 @@ func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
name := req.Service
ctx := namespaces.WithNamespace(context.Background(), FunctionNamespace)
deployErr := deploy(ctx, req, client, cni, secretMountPath)
deployErr := deploy(ctx, req, client, cni, secretMountPath, alwaysPull)
if deployErr != nil {
log.Printf("[Deploy] error deploying %s, error: %s\n", name, deployErr)
http.Error(w, deployErr.Error(), http.StatusBadRequest)
@ -63,7 +63,7 @@ func MakeDeployHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
}
}
func deploy(ctx context.Context, req types.FunctionDeployment, client *containerd.Client, cni gocni.CNI, secretMountPath string) error {
func deploy(ctx context.Context, req types.FunctionDeployment, client *containerd.Client, cni gocni.CNI, secretMountPath string, alwaysPull bool) error {
r, err := reference.ParseNormalizedNamed(req.Image)
if err != nil {
return err
@ -75,7 +75,7 @@ func deploy(ctx context.Context, req types.FunctionDeployment, client *container
snapshotter = val
}
image, err := service.PrepareImage(ctx, client, imgRef, snapshotter)
image, err := service.PrepareImage(ctx, client, imgRef, snapshotter, alwaysPull)
if err != nil {
return errors.Wrapf(err, "unable to pull image %s", imgRef)
}

View File

@ -8,15 +8,15 @@ import (
"log"
"net/http"
"github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
"github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces"
gocni "github.com/containerd/go-cni"
"github.com/openfaas/faas-provider/types"
"github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
)
func MakeUpdateHandler(client *containerd.Client, cni gocni.CNI, secretMountPath string) func(w http.ResponseWriter, r *http.Request) {
func MakeUpdateHandler(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) {
@ -68,7 +68,7 @@ func MakeUpdateHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
return
}
deployErr := deploy(ctx, req, client, cni, secretMountPath)
deployErr := deploy(ctx, req, client, cni, secretMountPath, alwaysPull)
if deployErr != nil {
log.Printf("[Update] error deploying %s, error: %s\n", name, deployErr)
http.Error(w, deployErr.Error(), http.StatusBadRequest)

View File

@ -122,11 +122,12 @@ func getResolver(ctx context.Context, configFile *configfile.ConfigFile) (remote
return docker.NewResolver(opts), nil
}
func PrepareImage(ctx context.Context, client *containerd.Client, imageName, snapshotter string) (containerd.Image, error) {
func PrepareImage(ctx context.Context, client *containerd.Client, imageName, snapshotter string, pullAlways bool) (containerd.Image, error) {
var (
empty containerd.Image
resolver remotes.Resolver
)
if _, stErr := os.Stat(filepath.Join(dockerConfigDir, config.ConfigFileName)); stErr == nil {
configFile, err := config.Load(dockerConfigDir)
if err != nil {
@ -140,22 +141,29 @@ func PrepareImage(ctx context.Context, client *containerd.Client, imageName, sna
return empty, stErr
}
image, err := client.GetImage(ctx, imageName)
var image containerd.Image
if pullAlways {
img, err := pullImage(ctx, client, resolver, imageName)
if err != nil {
return empty, err
}
image = img
} else {
img, err := client.GetImage(ctx, imageName)
if err != nil {
if !errdefs.IsNotFound(err) {
return empty, err
}
rOpts := []containerd.RemoteOpt{
containerd.WithPullUnpack,
}
if resolver != nil {
rOpts = append(rOpts, containerd.WithResolver(resolver))
}
img, err := client.Pull(ctx, imageName, rOpts...)
img, err := pullImage(ctx, client, resolver, imageName)
if err != nil {
return empty, fmt.Errorf("cannot pull: %s", err)
return empty, err
}
image = img
} else {
image = img
}
}
unpacked, err := image.IsUnpacked(ctx, snapshotter)
@ -171,3 +179,21 @@ func PrepareImage(ctx context.Context, client *containerd.Client, imageName, sna
return image, nil
}
func pullImage(ctx context.Context, client *containerd.Client, resolver remotes.Resolver, imageName string) (containerd.Image, error) {
var empty containerd.Image
rOpts := []containerd.RemoteOpt{
containerd.WithPullUnpack,
}
if resolver != nil {
rOpts = append(rOpts, containerd.WithResolver(resolver))
}
img, err := client.Pull(ctx, imageName, rOpts...)
if err != nil {
return empty, fmt.Errorf("cannot pull: %s", err)
}
return img, nil
}

View File

@ -8,13 +8,13 @@ import (
"os"
"path"
"github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/oci"
gocni "github.com/containerd/go-cni"
"github.com/openfaas/faasd/pkg/cninetwork"
"github.com/openfaas/faasd/pkg/service"
"github.com/containerd/containerd/namespaces"
"github.com/opencontainers/runtime-spec/specs-go"
@ -25,6 +25,7 @@ const (
workingDirectoryPermission = 0644
// faasdNamespace is the containerd namespace services are created
faasdNamespace = "default"
faasServicesPullAlways = false
)
type Service struct {
@ -88,7 +89,7 @@ func (s *Supervisor) Start(svcs []Service) error {
for _, svc := range svcs {
fmt.Printf("Preparing: %s with image: %s\n", svc.Name, svc.Image)
img, err := service.PrepareImage(ctx, s.client, svc.Image, defaultSnapshotter)
img, err := service.PrepareImage(ctx, s.client, svc.Image, defaultSnapshotter, faasServicesPullAlways)
if err != nil {
return err
}