Skip to content

Commit

Permalink
Remove tasks and containers on SIGINT/SIGTERM
Browse files Browse the repository at this point in the history
* Cleans-up and removes faasd containers/tasks when receiving
SIGINT/SIGTERM

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
  • Loading branch information
alexellis committed Dec 24, 2019
1 parent da16bde commit 3ee52c6
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 35 deletions.
26 changes: 25 additions & 1 deletion cmd/up.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package cmd

import (
"fmt"
"log"
"os"
"os/signal"
"path"
"sync"
"syscall"
"time"

"github.com/alexellis/faasd/pkg"
Expand Down Expand Up @@ -40,8 +44,28 @@ func runUp(_ *cobra.Command, _ []string) error {

log.Printf("Supervisor init done in: %s\n", time.Since(start).String())

time.Sleep(time.Minute * 120)
shutdownTimeout := time.Second * 1

wg := sync.WaitGroup{}
wg.Add(1)
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)

log.Printf("faasd: waiting for SIGTERM or SIGINT\n")
<-sig

log.Printf("Signal received.. shutting down server in %s\n", shutdownTimeout.String())
err := supervisor.Remove(services)
if err != nil {
fmt.Println(err)
}
time.AfterFunc(shutdownTimeout, func() {
wg.Done()
})
}()

wg.Wait()
return nil
}

Expand Down
85 changes: 51 additions & 34 deletions pkg/supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ func (s *Supervisor) Close() {
defer s.client.Close()
}

func (s *Supervisor) Remove(svcs []Service) error {
ctx := namespaces.WithNamespace(context.Background(), "default")

for _, svc := range svcs {
err := removeContainer(ctx, s.client, svc.Name)
if err != nil {
return err
}
}
return nil
}

func (s *Supervisor) Start(svcs []Service) error {
ctx := namespaces.WithNamespace(context.Background(), "default")

Expand All @@ -61,7 +73,7 @@ func (s *Supervisor) Start(svcs []Service) error {
images := map[string]containerd.Image{}

for _, svc := range svcs {
fmt.Printf("Preparing: %s\n", svc.Name)
fmt.Printf("Preparing: %s with image: %s\n", svc.Name, svc.Image)

img, err := prepareImage(ctx, s.client, svc.Image)
if err != nil {
Expand All @@ -70,45 +82,16 @@ func (s *Supervisor) Start(svcs []Service) error {
images[svc.Name] = img
size, _ := img.Size(ctx)
fmt.Printf("Prepare done for: %s, %d bytes\n", svc.Image, size)

}

for _, svc := range svcs {
fmt.Printf("Reconciling: %s\n", svc.Name)

image := images[svc.Name]

container, containerErr := s.client.LoadContainer(ctx, svc.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.Println("Status:", status.Status)

// if status.Status == containerd.Running {
log.Println("need to kill", svc.Name)
err := killTask(ctx, t)
if err != nil {
return fmt.Errorf("error killing task %s, %s, %s", container.ID(), svc.Name, err)
}
// }
}

err = container.Delete(ctx, containerd.WithSnapshotCleanup)
if err != nil {
return fmt.Errorf("error deleting container %s, %s, %s", container.ID(), svc.Name, err)
}

containerErr := removeContainer(ctx, s.client, svc.Name)
if containerErr != nil {
return containerErr
}

mounts := []specs.Mount{}
Expand Down Expand Up @@ -185,7 +168,7 @@ func (s *Supervisor) Start(svcs []Service) error {
return err
}

ip := getIP(container.ID(), task.Pid())
ip := getIP(newContainer.ID(), task.Pid())

hosts, _ := ioutil.ReadFile("hosts")

Expand Down Expand Up @@ -324,3 +307,37 @@ func killTask(ctx context.Context, task containerd.Task) error {

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
}

0 comments on commit 3ee52c6

Please sign in to comment.