package main import ( "context" "flag" "fmt" "os" "path/filepath" "syscall" log "github.com/Sirupsen/logrus" "github.com/containerd/containerd" "github.com/containerd/containerd/namespaces" "github.com/pkg/errors" ) func cleanupTask(ctx context.Context, ctr containerd.Container) error { task, err := ctr.Task(ctx, nil) if err != nil { if err == containerd.ErrNoRunningTask { return nil } return errors.Wrap(err, "getting task") } deleteErr := make(chan error, 1) deleteCtx, deleteCancel := context.WithCancel(ctx) defer deleteCancel() go func(ctx context.Context, ch chan error) { _, err := task.Delete(ctx) if err != nil { ch <- errors.Wrap(err, "killing task") } ch <- nil }(deleteCtx, deleteErr) sig := syscall.SIGKILL if err := task.Kill(ctx, sig); err != nil && err != containerd.ErrProcessExited { return errors.Wrapf(err, "killing task with %q", sig) } select { case err := <-deleteErr: return err case <-ctx.Done(): return ctx.Err() } } func systemInit(args []string) { invoked := filepath.Base(os.Args[0]) flags := flag.NewFlagSet("system-init", flag.ExitOnError) flags.Usage = func() { fmt.Printf("USAGE: %s system-init\n\n", invoked) fmt.Printf("Options:\n") flags.PrintDefaults() } sock := flags.String("sock", "/run/containerd/containerd.sock", "Path to containerd socket") if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") } args = flags.Args() if len(args) != 0 { fmt.Println("Unexpected argument") flags.Usage() os.Exit(1) } client, err := containerd.New(*sock) if err != nil { log.WithError(err).Fatal("creating containerd client") } ctx := namespaces.WithNamespace(context.Background(), "default") ctrs, err := client.Containers(ctx) if err != nil { log.WithError(err).Fatal("listing containers") } // None of the errors in this loop are fatal since we want to // keep trying. for _, ctr := range ctrs { log.Infof("Cleaning up stale service: %q", ctr.ID()) log := log.WithFields(log.Fields{ "service": ctr.ID(), }) if err := cleanupTask(ctx, ctr); err != nil { log.WithError(err).Error("cleaning up task") } if err := ctr.Delete(ctx); err != nil { log.WithError(err).Error("deleting container") } } }