gitpod/components/image-builder/cmd/bob-init-base.go
2021-05-26 13:10:54 +02:00

112 lines
3.3 KiB
Go

// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
package cmd
import (
"context"
"encoding/base64"
"fmt"
"os"
"os/exec"
"path/filepath"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/protobuf/proto"
"github.com/gitpod-io/gitpod/common-go/log"
"github.com/gitpod-io/gitpod/content-service/pkg/initializer"
"github.com/gitpod-io/gitpod/content-service/pkg/storage"
"github.com/gitpod-io/gitpod/image-builder/api"
)
// bobInitBase represents the init command
var bobInitBase = &cobra.Command{
Use: "init-base <location> <base64:source>",
Short: "Assembles the base image context of a build.",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
wd := args[0]
inpt := args[1]
rawinit := make([]byte, base64.RawStdEncoding.DecodedLen(len(inpt)))
_, err := base64.RawStdEncoding.Decode(rawinit, []byte(inpt))
if err != nil {
log.Fatalf("cannot decode initializer: %v", err)
}
var src api.BuildSourceDockerfile
err = proto.Unmarshal(rawinit, &src)
if err != nil {
log.Fatalf("cannot unmarshal initializer: %v", err)
}
initwd := filepath.Join(wd, "init")
ctx := context.Background()
rms := &storage.DirectNoopStorage{}
ilr, err := initializer.NewFromRequest(ctx, initwd, rms, src.Source, initializer.NewFromRequestOpts{ForceGitpodUserForGit: false})
if err != nil {
log.Fatalf("cannot create initializer: %v", err)
}
_, err = initializer.InitializeWorkspace(ctx, initwd, rms, initializer.WithInitializer(ilr), initializer.WithCleanSlate)
if err != nil {
log.WithError(err).Fatal("init failed")
}
ctxwd := filepath.Join(wd, "context")
err = os.MkdirAll(ctxwd, 0755)
if err != nil {
log.WithError(err).Fatal("init failed")
}
err = os.Chown(ctxwd, 33333, 33333)
if err != nil {
log.WithError(err).Fatal("init failed")
}
initctx, err := securejoin.SecureJoin(initwd, src.ContextPath)
if err != nil {
log.WithError(err).Fatal("init failed")
}
if stat, err := os.Stat(initctx); os.IsNotExist(err) {
log.Fatalf("Context directory \"%s\" does not exist", src.ContextPath)
} else if err != nil {
log.Fatalf("Context directory error: %v", err)
} else if !stat.IsDir() {
log.Fatalf("Context path \"%s\" is not a directory", src.ContextPath)
}
initdf, err := securejoin.SecureJoin(initwd, src.DockerfilePath)
if err != nil {
log.WithError(err).Fatal("init failed")
}
if stat, err := os.Stat(initdf); os.IsNotExist(err) {
log.Fatalf("Dockerfile \"%s\" does not exist", src.DockerfilePath)
} else if err != nil {
log.Fatalf("Dockerfile error: %v", err)
} else if stat.IsDir() {
log.Fatalf("Dockerfile \"%s\" is a directory", src.DockerfilePath)
}
var cmds [][]string
cmds = append(cmds, []string{"sh", "-c", fmt.Sprintf("cp -Rf %s/. .", initctx)})
cmds = append(cmds, []string{"mv", "-f", initdf, "Dockerfile"})
for _, cmd := range cmds {
c := exec.Command(cmd[0], cmd[1:]...)
c.Dir = ctxwd
c.Stdout = log.Log.WriterLevel(logrus.InfoLevel)
c.Stderr = log.Log.WriterLevel(logrus.ErrorLevel)
_ = c.Run()
}
},
}
func init() {
bobCmd.AddCommand(bobInitBase)
}