Path: blob/main/components/image-builder-bob/cmd/daemon.go
2498 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package cmd56import (7"context"8"encoding/json"9"fmt"10"os"11"os/signal"12"syscall"1314log "github.com/gitpod-io/gitpod/common-go/log"15"github.com/gitpod-io/gitpod/image-builder/bob/pkg/builder"1617"github.com/containerd/console"18"github.com/moby/buildkit/client"19"github.com/moby/buildkit/client/llb"20"github.com/moby/buildkit/util/progress/progressui"21"github.com/spf13/cobra"22"golang.org/x/sync/errgroup"23)2425// daemonCmd represents the build command26var daemonCmd = &cobra.Command{27Use: "daemon <socket-path>",28Short: "Starts a buildkitd and pre-caches images",29Args: cobra.ExactArgs(1),30Run: func(cmd *cobra.Command, args []string) {31if os.Geteuid() != 0 {32log.Fatal("must run as root")33}3435skt := args[0]36cl, teardown, err := builder.StartBuildkit(skt)37if err != nil {38log.WithError(err).Fatal("cannot start daemon")39}40defer teardown()4142rawimgs := os.Getenv("BOB_CACHE_IMAGES")43if rawimgs != "" {44var images []string45err = json.Unmarshal([]byte(rawimgs), &images)46if err != nil {47log.WithError(err).Error("cannot unmarshal BOB_CACHE_IMAGES")48}4950if len(images) > 0 {51err = prewarmCache(cl, images)52if err != nil {53log.WithError(err).Error("cannot prewarm cache")54}55}56}5758// run until we're told to stop59sigChan := make(chan os.Signal, 1)60signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)61log.Info("👷 image-builder daemon is up and running. Stop with SIGINT or CTRL+C")62<-sigChan63log.Info("Received SIGINT - shutting down")64},65}6667func prewarmCache(cl *client.Client, images []string) error {68for _, img := range images {69bld := llb.Image(img).Run(llb.Shlex("echo"))70for idx, img := range images {71bld = bld.AddMount(fmt.Sprintf("/mnt/%03d", idx), llb.Image(img)).Run(llb.Shlex("echo"))72}73pulllb, err := bld.Marshal(context.Background())74if err != nil {75log.WithError(err).Fatal("cannot produce image pull LLB")76}7778log.Info("pulling images")79var (80ch = make(chan *client.SolveStatus)81eg, ctx = errgroup.WithContext(context.Background())82)83eg.Go(func() error {84_, err := cl.Solve(ctx, pulllb, client.SolveOpt{}, ch)85return err86})87eg.Go(func() error {88var c console.Console89// not using shared context to not disrupt display but let is finish reporting errors90_, err := progressui.DisplaySolveStatus(context.TODO(), c, os.Stderr, ch)91return err92})93err = eg.Wait()94if err != nil {95return err96}97}98log.Info("done pulling images")99return nil100}101102func init() {103rootCmd.AddCommand(daemonCmd)104}105106107