From 9821180548b07546401a17c4d52fde430acfea99 Mon Sep 17 00:00:00 2001 From: Justin Barrick Date: Thu, 7 Jun 2018 15:50:31 -0700 Subject: [PATCH] Add a restart and stop command to service. Signed-off-by: justinbarrick --- pkg/init/cmd/service/{start.go => cmd.go} | 86 +++++++++++++++++++++-- pkg/init/cmd/service/main.go | 11 +++ 2 files changed, 92 insertions(+), 5 deletions(-) rename pkg/init/cmd/service/{start.go => cmd.go} (66%) diff --git a/pkg/init/cmd/service/start.go b/pkg/init/cmd/service/cmd.go similarity index 66% rename from pkg/init/cmd/service/start.go rename to pkg/init/cmd/service/cmd.go index 0e0341846..c5b9b6364 100644 --- a/pkg/init/cmd/service/start.go +++ b/pkg/init/cmd/service/cmd.go @@ -16,11 +16,11 @@ import ( log "github.com/sirupsen/logrus" ) -func startCmd(ctx context.Context, args []string) { +func parseCmd(ctx context.Context, command string, args []string) (*log.Entry, string, string, string, string) { invoked := filepath.Base(os.Args[0]) - flags := flag.NewFlagSet("start", flag.ExitOnError) + flags := flag.NewFlagSet(command, flag.ExitOnError) flags.Usage = func() { - fmt.Printf("USAGE: %s start [service]\n\n", invoked) + fmt.Printf("USAGE: %s %s [service]\n\n", invoked, command) fmt.Printf("Options:\n") flags.PrintDefaults() } @@ -43,12 +43,30 @@ func startCmd(ctx context.Context, args []string) { service := args[0] - log.Infof("Starting service: %q", service) log := log.WithFields(log.Fields{ "service": service, }) - id, pid, msg, err := start(ctx, service, *sock, *path, *dumpSpec) + return log, service, *sock, *path, *dumpSpec +} + +func stopCmd(ctx context.Context, args []string) { + log, service, sock, path, _ := parseCmd(ctx, "stop", args) + + log.Infof("Stopping service: %q", service) + id, pid, msg, err := stop(ctx, service, sock, path) + if err != nil { + log.WithError(err).Fatal(msg) + } + + log.Debugf("Stopped %s pid %d", id, pid) +} + +func startCmd(ctx context.Context, args []string) { + log, service, sock, path, dumpSpec := parseCmd(ctx, "start", args) + + log.Infof("Starting service: %q", service) + id, pid, msg, err := start(ctx, service, sock, path, dumpSpec) if err != nil { log.WithError(err).Fatal(msg) } @@ -56,6 +74,14 @@ func startCmd(ctx context.Context, args []string) { log.Debugf("Started %s pid %d", id, pid) } +func restartCmd(ctx context.Context, args []string) { + // validate arguments with the command as "restart" + parseCmd(ctx, "restart", args) + + stopCmd(ctx, args) + startCmd(ctx, args) +} + type logio struct { config cio.Config } @@ -74,6 +100,56 @@ func (c *logio) Close() error { return nil } +func stop(ctx context.Context, service, sock, basePath string) (string, uint32, string, error) { + path := filepath.Join(basePath, service) + + runtimeConfig := getRuntimeConfig(path) + + client, err := containerd.New(sock) + if err != nil { + return "", 0, "creating containerd client", err + } + + if runtimeConfig.Namespace != "" { + ctx = namespaces.WithNamespace(ctx, runtimeConfig.Namespace) + } + + ctr, err := client.LoadContainer(ctx, service) + if err != nil { + return "", 0, "loading container", err + } + + task, err := ctr.Task(ctx, nil) + if err != nil { + return "", 0, "fetching task", err + } + + id := ctr.ID() + pid := task.Pid() + + err = task.Kill(ctx, 9) + if err != nil { + return "", 0, "killing task", err + } + + _, err = task.Wait(ctx) + if err != nil { + return "", 0, "waiting for task to exit", err + } + + _, err = task.Delete(ctx) + if err != nil { + return "", 0, "deleting task", err + } + + err = ctr.Delete(ctx) + if err != nil { + return "", 0, "deleting container", err + } + + return id, pid, "", nil +} + func start(ctx context.Context, service, sock, basePath, dumpSpec string) (string, uint32, string, error) { path := filepath.Join(basePath, service) diff --git a/pkg/init/cmd/service/main.go b/pkg/init/cmd/service/main.go index d4816980c..1c03e3e13 100644 --- a/pkg/init/cmd/service/main.go +++ b/pkg/init/cmd/service/main.go @@ -43,7 +43,9 @@ func main() { fmt.Printf("USAGE: %s [options] COMMAND\n\n", filepath.Base(os.Args[0])) fmt.Printf("Commands:\n") fmt.Printf(" system-init Prepare the system at start of day\n") + fmt.Printf(" stop Stop a service\n") fmt.Printf(" start Start a service\n") + fmt.Printf(" restart Restart a service\n") fmt.Printf(" help Print this message\n") fmt.Printf("\n") fmt.Printf("Run '%s COMMAND --help' for more information on the command\n", filepath.Base(os.Args[0])) @@ -92,9 +94,18 @@ func main() { } } + if len(args) < 1 { + flag.Usage() + os.Exit(1) + } + switch args[0] { + case "stop": + stopCmd(ctx, args[1:]) case "start": startCmd(ctx, args[1:]) + case "restart": + restartCmd(ctx, args[1:]) case "system-init": systemInitCmd(ctx, args[1:]) default: