Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/image-builder-bob/cmd/daemon.go
2498 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cmd
6
7
import (
8
"context"
9
"encoding/json"
10
"fmt"
11
"os"
12
"os/signal"
13
"syscall"
14
15
log "github.com/gitpod-io/gitpod/common-go/log"
16
"github.com/gitpod-io/gitpod/image-builder/bob/pkg/builder"
17
18
"github.com/containerd/console"
19
"github.com/moby/buildkit/client"
20
"github.com/moby/buildkit/client/llb"
21
"github.com/moby/buildkit/util/progress/progressui"
22
"github.com/spf13/cobra"
23
"golang.org/x/sync/errgroup"
24
)
25
26
// daemonCmd represents the build command
27
var daemonCmd = &cobra.Command{
28
Use: "daemon <socket-path>",
29
Short: "Starts a buildkitd and pre-caches images",
30
Args: cobra.ExactArgs(1),
31
Run: func(cmd *cobra.Command, args []string) {
32
if os.Geteuid() != 0 {
33
log.Fatal("must run as root")
34
}
35
36
skt := args[0]
37
cl, teardown, err := builder.StartBuildkit(skt)
38
if err != nil {
39
log.WithError(err).Fatal("cannot start daemon")
40
}
41
defer teardown()
42
43
rawimgs := os.Getenv("BOB_CACHE_IMAGES")
44
if rawimgs != "" {
45
var images []string
46
err = json.Unmarshal([]byte(rawimgs), &images)
47
if err != nil {
48
log.WithError(err).Error("cannot unmarshal BOB_CACHE_IMAGES")
49
}
50
51
if len(images) > 0 {
52
err = prewarmCache(cl, images)
53
if err != nil {
54
log.WithError(err).Error("cannot prewarm cache")
55
}
56
}
57
}
58
59
// run until we're told to stop
60
sigChan := make(chan os.Signal, 1)
61
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
62
log.Info("👷 image-builder daemon is up and running. Stop with SIGINT or CTRL+C")
63
<-sigChan
64
log.Info("Received SIGINT - shutting down")
65
},
66
}
67
68
func prewarmCache(cl *client.Client, images []string) error {
69
for _, img := range images {
70
bld := llb.Image(img).Run(llb.Shlex("echo"))
71
for idx, img := range images {
72
bld = bld.AddMount(fmt.Sprintf("/mnt/%03d", idx), llb.Image(img)).Run(llb.Shlex("echo"))
73
}
74
pulllb, err := bld.Marshal(context.Background())
75
if err != nil {
76
log.WithError(err).Fatal("cannot produce image pull LLB")
77
}
78
79
log.Info("pulling images")
80
var (
81
ch = make(chan *client.SolveStatus)
82
eg, ctx = errgroup.WithContext(context.Background())
83
)
84
eg.Go(func() error {
85
_, err := cl.Solve(ctx, pulllb, client.SolveOpt{}, ch)
86
return err
87
})
88
eg.Go(func() error {
89
var c console.Console
90
// not using shared context to not disrupt display but let is finish reporting errors
91
_, err := progressui.DisplaySolveStatus(context.TODO(), c, os.Stderr, ch)
92
return err
93
})
94
err = eg.Wait()
95
if err != nil {
96
return err
97
}
98
}
99
log.Info("done pulling images")
100
return nil
101
}
102
103
func init() {
104
rootCmd.AddCommand(daemonCmd)
105
}
106
107