From b97da9b0092a09d5abf71bba07afe2fa6aae2ae1 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Thu, 22 Apr 2021 14:46:01 -0700 Subject: inject a script for init Once we will be ready to boot our VM, we will need an init script in place. For this, we create a simple shell script which we populate using the environment variables and command extracted from the container. The init script is stored in /init.sh within the new image, and we will configure the boot parameter to find it there. --- cmd/c2vm/main.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'cmd') diff --git a/cmd/c2vm/main.go b/cmd/c2vm/main.go index c416e47..544293e 100644 --- a/cmd/c2vm/main.go +++ b/cmd/c2vm/main.go @@ -1,13 +1,17 @@ package main import ( + "bufio" "context" + "encoding/json" "flag" "fmt" "io/ioutil" "log" + "os" "os/exec" "path/filepath" + "strings" "github.com/containerd/containerd" "github.com/containerd/containerd/content" @@ -81,6 +85,10 @@ func main() { log.Fatalf("failed to extract the container: %v\n", err) } + if err = initScript(ctx, client, image, mntDir); err != nil { + log.Fatalf("failed to create init script: %s\n", err) + } + if err = extraFiles(mntDir); err != nil { log.Fatalf("failed to add extra files to the image: %v\n", err) } @@ -172,6 +180,41 @@ func extraFiles(mntDir string) error { return nil } +func initScript(ctx context.Context, client *containerd.Client, image containerd.Image, mntDir string) error { + config, err := images.Config(ctx, client.ContentStore(), image.Target(), platform) + if err != nil { + return err + } + + configBlob, err := content.ReadBlob(ctx, client.ContentStore(), config) + var imageSpec ocispec.Image + json.Unmarshal(configBlob, &imageSpec) + initCmd := strings.Join(imageSpec.Config.Cmd, " ") + initEnvs := imageSpec.Config.Env + + initPath := filepath.Join(mntDir, "init.sh") + f, err := renameio.TempFile("", initPath) + if err != nil { + return err + } + defer f.Cleanup() + + writer := bufio.NewWriter(f) + fmt.Fprintf(writer, "#!/bin/sh\n") + for _, env := range initEnvs { + fmt.Fprintf(writer, "export %s\n", env) + } + fmt.Fprintf(writer, "%s\n", initCmd) + writer.Flush() + + f.CloseAtomicallyReplace() + + mode := int(0755) + os.Chmod(initPath, os.FileMode(mode)) + log.Printf("init script created") + return nil +} + func writeToFile(filepath string, content string) error { if err := ioutil.WriteFile(filepath, []byte(content), 0644); err != nil { return fmt.Errorf("writeToFile %s: %v", filepath, err) -- cgit 1.4.1