Compare commits

...

8 Commits
0.2.3 ... 0.2.9

Author SHA1 Message Date
f76432f60a Add use of template to Install command
The template name wasnt used, so the command gave an error saying
that no template was used.

Signed-off-by: Alistair Hey <alistair@heyal.co.uk>
2019-12-29 11:28:16 +00:00
38f26b213f Clear snapshot when container doesn't exist
This clears up a scenario where a container can be deleted but
its snapshot is not.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 20:01:01 +00:00
6c3fe813fd Extract PrepareImage
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 19:09:42 +00:00
13d28bd2db Extract Service struct
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 18:32:13 +00:00
f3f6225674 Bump faasd version
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 16:46:53 +00:00
e4ed9e5b91 Fix typo
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 16:46:08 +00:00
5a28f3e231 Add error handling for when template not found
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 16:41:06 +00:00
a042be5477 Mention where to run the install
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
2019-12-28 16:38:12 +00:00
6 changed files with 137 additions and 117 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/faasd /faasd
hosts hosts
/resolv.conf /resolv.conf
.idea/

View File

@ -86,17 +86,17 @@ go build
```sh ```sh
# For x86_64 # For x86_64
sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.2/faasd" \ sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.5/faasd" \
-o "/usr/local/bin/faasd" \ -o "/usr/local/bin/faasd" \
&& sudo chmod a+x "/usr/local/bin/faasd" && sudo chmod a+x "/usr/local/bin/faasd"
# armhf # armhf
sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.2/faasd-armhf" \ sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.5/faasd-armhf" \
-o "/usr/local/bin/faasd" \ -o "/usr/local/bin/faasd" \
&& sudo chmod a+x "/usr/local/bin/faasd" && sudo chmod a+x "/usr/local/bin/faasd"
# arm64 # arm64
sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.2/faasd-arm64" \ sudo curl -fSLs "https://github.com/alexellis/faasd/releases/download/0.2.5/faasd-arm64" \
-o "/usr/local/bin/faasd" \ -o "/usr/local/bin/faasd" \
&& sudo chmod a+x "/usr/local/bin/faasd" && sudo chmod a+x "/usr/local/bin/faasd"
``` ```
@ -125,7 +125,7 @@ Since faas-containerd uses containerd heavily it is not running as a container,
#### Installation with systemd #### Installation with systemd
* `faasd install` - install faasd and containerd with systemd * `faasd install` - install faasd and containerd with systemd, run in `$GOPATH/src/github.com/alexellis/faasd`
* `journalctl -u faasd` - faasd systemd logs * `journalctl -u faasd` - faasd systemd logs
* `journalctl -u faas-containerd` - faas-containerd systemd logs * `journalctl -u faas-containerd` - faas-containerd systemd logs
@ -134,11 +134,11 @@ Since faas-containerd uses containerd heavily it is not running as a container,
Removing containers: Removing containers:
```sh ```sh
echo faas-containerd gateway prometheus |xargs sudo ctr task rm -f echo faas-containerd gateway prometheus | xargs sudo ctr task rm -f
echo faas-containerd gateway prometheus |xargs sudo ctr container rm echo faas-containerd gateway prometheus | xargs sudo ctr container rm
echo faas-containerd gateway prometheus |xargs sudo ctr snapshot rm echo faas-containerd gateway prometheus | xargs sudo ctr snapshot rm
``` ```
## Links ## Links
@ -151,4 +151,3 @@ https://github.com/containernetworking/plugins
https://github.com/containerd/go-cni https://github.com/containerd/go-cni

View File

@ -23,7 +23,7 @@ func runInstall(_ *cobra.Command, _ []string) error {
return err return err
} }
err := binExists("/usr/local/bin/", "faasd") err = binExists("/usr/local/bin/", "faasd")
if err != nil { if err != nil {
return err return err
} }

117
pkg/service/service.go Normal file
View File

@ -0,0 +1,117 @@
package service
import (
"context"
"fmt"
"log"
"sync"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
"golang.org/x/sys/unix"
)
// Remove removes a container
func Remove(ctx context.Context, client *containerd.Client, name string) error {
container, containerErr := client.LoadContainer(ctx, name)
if containerErr == nil {
found := true
t, err := container.Task(ctx, nil)
if err != nil {
if errdefs.IsNotFound(err) {
found = false
} else {
return fmt.Errorf("unable to get task %s: ", err)
}
}
if found {
status, _ := t.Status(ctx)
fmt.Printf("Status of %s is: %s\n", name, status.Status)
log.Printf("Need to kill %s\n", name)
err := killTask(ctx, t)
if err != nil {
return fmt.Errorf("error killing task %s, %s, %s", container.ID(), name, err)
}
}
err = container.Delete(ctx, containerd.WithSnapshotCleanup)
if err != nil {
return fmt.Errorf("error deleting container %s, %s, %s", container.ID(), name, err)
}
} else {
service := client.SnapshotService("")
key := name + "snapshot"
if _, err := client.SnapshotService("").Stat(ctx, key); err == nil {
service.Remove(ctx, key)
}
}
return nil
}
// From Stellar
func killTask(ctx context.Context, task containerd.Task) error {
wg := &sync.WaitGroup{}
wg.Add(1)
var err error
go func() {
defer wg.Done()
if task != nil {
wait, err := task.Wait(ctx)
if err != nil {
err = fmt.Errorf("error waiting on task: %s", err)
return
}
if err := task.Kill(ctx, unix.SIGTERM, containerd.WithKillAll); err != nil {
log.Printf("error killing container task: %s", err)
}
select {
case <-wait:
task.Delete(ctx)
return
case <-time.After(5 * time.Second):
if err := task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil {
log.Printf("error force killing container task: %s", err)
}
return
}
}
}()
wg.Wait()
return err
}
func PrepareImage(ctx context.Context, client *containerd.Client, imageName, snapshotter string) (containerd.Image, error) {
var empty containerd.Image
image, err := client.GetImage(ctx, imageName)
if err != nil {
if !errdefs.IsNotFound(err) {
return empty, err
}
img, err := client.Pull(ctx, imageName, containerd.WithPullUnpack)
if err != nil {
return empty, fmt.Errorf("cannot pull: %s", err)
}
image = img
}
unpacked, err := image.IsUnpacked(ctx, snapshotter)
if err != nil {
return empty, fmt.Errorf("cannot check if unpacked: %s", err)
}
if !unpacked {
if err := image.Unpack(ctx, snapshotter); err != nil {
return empty, fmt.Errorf("cannot unpack: %s", err)
}
}
return image, nil
}

View File

@ -8,15 +8,12 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"sync"
"time"
"github.com/alexellis/faasd/pkg/service"
"github.com/alexellis/faasd/pkg/weave" "github.com/alexellis/faasd/pkg/weave"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/cio" "github.com/containerd/containerd/cio"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"golang.org/x/sys/unix"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
@ -48,7 +45,7 @@ func (s *Supervisor) Remove(svcs []Service) error {
ctx := namespaces.WithNamespace(context.Background(), "default") ctx := namespaces.WithNamespace(context.Background(), "default")
for _, svc := range svcs { for _, svc := range svcs {
err := removeContainer(ctx, s.client, svc.Name) err := service.Remove(ctx, s.client, svc.Name)
if err != nil { if err != nil {
return err return err
} }
@ -75,7 +72,7 @@ func (s *Supervisor) Start(svcs []Service) error {
for _, svc := range svcs { for _, svc := range svcs {
fmt.Printf("Preparing: %s with image: %s\n", svc.Name, svc.Image) fmt.Printf("Preparing: %s with image: %s\n", svc.Name, svc.Image)
img, err := prepareImage(ctx, s.client, svc.Image) img, err := service.PrepareImage(ctx, s.client, svc.Image, defaultSnapshotter)
if err != nil { if err != nil {
return err return err
} }
@ -87,13 +84,13 @@ func (s *Supervisor) Start(svcs []Service) error {
for _, svc := range svcs { for _, svc := range svcs {
fmt.Printf("Reconciling: %s\n", svc.Name) fmt.Printf("Reconciling: %s\n", svc.Name)
image := images[svc.Name] containerErr := service.Remove(ctx, s.client, svc.Name)
containerErr := removeContainer(ctx, s.client, svc.Name)
if containerErr != nil { if containerErr != nil {
return containerErr return containerErr
} }
image := images[svc.Name]
mounts := []specs.Mount{} mounts := []specs.Mount{}
if len(svc.Mounts) > 0 { if len(svc.Mounts) > 0 {
for _, mnt := range svc.Mounts { for _, mnt := range svc.Mounts {
@ -199,37 +196,6 @@ func (s *Supervisor) Start(svcs []Service) error {
return nil return nil
} }
func prepareImage(ctx context.Context, client *containerd.Client, imageName string) (containerd.Image, error) {
snapshotter := defaultSnapshotter
var empty containerd.Image
image, err := client.GetImage(ctx, imageName)
if err != nil {
if !errdefs.IsNotFound(err) {
return empty, err
}
img, err := client.Pull(ctx, imageName, containerd.WithPullUnpack)
if err != nil {
return empty, fmt.Errorf("cannot pull: %s", err)
}
image = img
}
unpacked, err := image.IsUnpacked(ctx, snapshotter)
if err != nil {
return empty, fmt.Errorf("cannot check if unpacked: %s", err)
}
if !unpacked {
if err := image.Unpack(ctx, snapshotter); err != nil {
return empty, fmt.Errorf("cannot unpack: %s", err)
}
}
return image, nil
}
func getIP(containerID string, taskPID uint32) string { func getIP(containerID string, taskPID uint32) string {
// https://github.com/weaveworks/weave/blob/master/net/netdev.go // https://github.com/weaveworks/weave/blob/master/net/netdev.go
@ -274,70 +240,3 @@ func withOCIArgs(args []string) oci.SpecOpts {
} }
} }
// From Stellar
func killTask(ctx context.Context, task containerd.Task) error {
wg := &sync.WaitGroup{}
wg.Add(1)
var err error
go func() {
defer wg.Done()
if task != nil {
wait, err := task.Wait(ctx)
if err != nil {
err = fmt.Errorf("error waiting on task: %s", err)
return
}
if err := task.Kill(ctx, unix.SIGTERM, containerd.WithKillAll); err != nil {
log.Printf("error killing container task: %s", err)
}
select {
case <-wait:
task.Delete(ctx)
return
case <-time.After(5 * time.Second):
if err := task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil {
log.Printf("error force killing container task: %s", err)
}
return
}
}
}()
wg.Wait()
return err
}
func removeContainer(ctx context.Context, client *containerd.Client, name string) error {
container, containerErr := client.LoadContainer(ctx, name)
if containerErr == nil {
found := true
t, err := container.Task(ctx, nil)
if err != nil {
if errdefs.IsNotFound(err) {
found = false
} else {
return fmt.Errorf("unable to get task %s: ", err)
}
}
if found {
status, _ := t.Status(ctx)
fmt.Printf("Status of %s is: %s\n", name, status.Status)
log.Printf("Need to kill %s\n", name)
err := killTask(ctx, t)
if err != nil {
return fmt.Errorf("error killing task %s, %s, %s", container.ID(), name, err)
}
}
err = container.Delete(ctx, containerd.WithSnapshotCleanup)
if err != nil {
return fmt.Errorf("error deleting container %s, %s, %s", container.ID(), name, err)
}
}
return nil
}

View File

@ -65,8 +65,12 @@ func DaemonReload() error {
} }
func InstallUnit(name string) error { func InstallUnit(name string) error {
tmplName := "./hack/" + name + ".service"
tmpl, err := template.ParseFiles(tmplName)
tmpl, err := template.ParseFiles("./hack/" + name + ".service") if err != nil {
return fmt.Errorf("error loading template %s, error %s", tmplName, err)
}
wd, _ := os.Getwd() wd, _ := os.Getwd()
var tpl bytes.Buffer var tpl bytes.Buffer