mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-10-31 03:59:48 +00:00 
			
		
		
		
	Currently it supports only `service start <SERVICE>`, but it could grow e.g. `stop`, `exec` etc in the future (although you can still use `ctr` for those). In order to be able to use go-compile.sh the containerd build needs to move from /root/go to /go as the GOPATH. The vendoring situation is not ideal, but since this tool wants to be an exact match for the containerd it seems tollerable to reuse its vendoring. Signed-off-by: Ian Campbell <ian.campbell@docker.com>
		
			
				
	
	
		
			114 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 
 | |
| 	log "github.com/Sirupsen/logrus"
 | |
| 	"github.com/containerd/containerd"
 | |
| 	"github.com/containerd/containerd/namespaces"
 | |
| 	specs "github.com/opencontainers/runtime-spec/specs-go"
 | |
| )
 | |
| 
 | |
| func start(args []string) {
 | |
| 	invoked := filepath.Base(os.Args[0])
 | |
| 	flags := flag.NewFlagSet("start", flag.ExitOnError)
 | |
| 	flags.Usage = func() {
 | |
| 		fmt.Printf("USAGE: %s start [service]\n\n", invoked)
 | |
| 		fmt.Printf("Options:\n")
 | |
| 		flags.PrintDefaults()
 | |
| 	}
 | |
| 
 | |
| 	sock := flags.String("sock", "/run/containerd/containerd.sock", "Path to containerd socket")
 | |
| 
 | |
| 	dumpSpec := flags.String("dump-spec", "", "Dump container spec to file before start")
 | |
| 
 | |
| 	if err := flags.Parse(args); err != nil {
 | |
| 		log.Fatal("Unable to parse args")
 | |
| 	}
 | |
| 	args = flags.Args()
 | |
| 
 | |
| 	if len(args) != 1 {
 | |
| 		fmt.Println("Please specify the service")
 | |
| 		flags.Usage()
 | |
| 		os.Exit(1)
 | |
| 	}
 | |
| 
 | |
| 	service := args[0]
 | |
| 	rootfs := filepath.Join("/containers/services", service, "rootfs")
 | |
| 	log.Infof("Starting service: %q", service)
 | |
| 	log := log.WithFields(log.Fields{
 | |
| 		"service": service,
 | |
| 	})
 | |
| 
 | |
| 	client, err := containerd.New(*sock)
 | |
| 	if err != nil {
 | |
| 		log.WithError(err).Fatal("creating containerd client")
 | |
| 	}
 | |
| 
 | |
| 	ctx := namespaces.WithNamespace(context.Background(), "default")
 | |
| 
 | |
| 	var spec *specs.Spec
 | |
| 	specf, err := os.Open(filepath.Join("/containers/services", service, "config.json"))
 | |
| 	if err != nil {
 | |
| 		log.WithError(err).Fatal("failed to read service spec")
 | |
| 	}
 | |
| 	if err := json.NewDecoder(specf).Decode(&spec); err != nil {
 | |
| 		log.WithError(err).Fatal("failed to parse service spec")
 | |
| 	}
 | |
| 
 | |
| 	log.Debugf("Rootfs is %s", rootfs)
 | |
| 
 | |
| 	spec.Root.Path = rootfs
 | |
| 
 | |
| 	if *dumpSpec != "" {
 | |
| 		d, err := os.Create(*dumpSpec)
 | |
| 		if err != nil {
 | |
| 			log.WithError(err).Fatal("failed to open file for spec dump")
 | |
| 		}
 | |
| 		enc := json.NewEncoder(d)
 | |
| 		enc.SetIndent("", "    ")
 | |
| 		if err := enc.Encode(&spec); err != nil {
 | |
| 			log.WithError(err).Fatal("failed to write spec dump")
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	ctr, err := client.NewContainer(ctx, service, containerd.WithSpec(spec))
 | |
| 	if err != nil {
 | |
| 		log.WithError(err).Fatal("failed to create container")
 | |
| 	}
 | |
| 
 | |
| 	io := func() (*containerd.IO, error) {
 | |
| 		logfile := filepath.Join("/var/log", service+".log")
 | |
| 		// We just need this to exist.
 | |
| 		if err := ioutil.WriteFile(logfile, []byte{}, 0666); err != nil {
 | |
| 			log.WithError(err).Fatal("failed to touch logfile")
 | |
| 		}
 | |
| 		return &containerd.IO{
 | |
| 			Stdin:    "/dev/null",
 | |
| 			Stdout:   logfile,
 | |
| 			Stderr:   logfile,
 | |
| 			Terminal: false,
 | |
| 		}, nil
 | |
| 	}
 | |
| 
 | |
| 	task, err := ctr.NewTask(ctx, io)
 | |
| 	if err != nil {
 | |
| 		// Don't bother to destroy the container here.
 | |
| 		log.WithError(err).Fatal("failed to create task")
 | |
| 	}
 | |
| 
 | |
| 	if err := task.Start(ctx); err != nil {
 | |
| 		// Don't destroy the container here so it can be inspected for debugging.
 | |
| 		log.WithError(err).Fatal("failed to start task")
 | |
| 	}
 | |
| 
 | |
| 	log.Debugf("Started %s pid %d", ctr.ID(), task.Pid())
 | |
| }
 |