@@ -20,6 +20,7 @@ import (
20
20
"os"
21
21
"path/filepath"
22
22
"runtime"
23
+ "syscall"
23
24
"time"
24
25
25
26
"github.com/uber/makisu/lib/builder"
@@ -66,14 +67,15 @@ type buildCmd struct {
66
67
compressionLevel string
67
68
68
69
preserveRoot bool
70
+ chroot string
69
71
}
70
72
71
73
func getBuildCmd () * buildCmd {
72
74
buildCmd := & buildCmd {
73
75
Command : & cobra.Command {
74
- Use : "build -t=<image_tag> [flags] <context_path>" ,
76
+ Use : "build -t=<image_tag> [flags] <context_path>" ,
75
77
DisableFlagsInUseLine : true ,
76
- Short : "Build docker image, optionally push to registries and/or load into docker daemon" ,
78
+ Short : "Build docker image, optionally push to registries and/or load into docker daemon" ,
77
79
},
78
80
}
79
81
buildCmd .Args = func (cmd * cobra.Command , args []string ) error {
@@ -87,7 +89,6 @@ func getBuildCmd() *buildCmd {
87
89
log .Errorf ("failed to process flags: %s" , err )
88
90
os .Exit (1 )
89
91
}
90
-
91
92
if err := buildCmd .Build (args [0 ]); err != nil {
92
93
log .Error (err )
93
94
os .Exit (1 )
@@ -122,6 +123,7 @@ func getBuildCmd() *buildCmd {
122
123
buildCmd .PersistentFlags ().StringVar (& buildCmd .compressionLevel , "compression" , "default" , "Image compression level, could be 'no', 'speed', 'size', 'default'" )
123
124
124
125
buildCmd .PersistentFlags ().BoolVar (& buildCmd .preserveRoot , "preserve-root" , false , "Copy / in the storage dir and copy it back after build." )
126
+ rootCmd .PersistentFlags ().StringVar (& buildCmd .chroot , "chroot" , "" , "Executes the command in a chrooted environment." )
125
127
126
128
buildCmd .MarkFlagRequired ("tag" )
127
129
buildCmd .Flags ().SortFlags = false
@@ -214,6 +216,12 @@ func (cmd *buildCmd) newBuildPlan(
214
216
func (cmd * buildCmd ) Build (contextDir string ) error {
215
217
log .Infof ("Starting Makisu build (version=%s)" , utils .BuildHash )
216
218
219
+ if cmd .chroot != "" {
220
+ if err := cmd .prepareChroot (contextDir ); err != nil {
221
+ return fmt .Errorf ("failed to prepare chroot environment: %s" , err )
222
+ }
223
+ }
224
+
217
225
// Create BuildContext.
218
226
contextDirAbs , err := filepath .Abs (contextDir )
219
227
if err != nil {
@@ -297,3 +305,29 @@ func (cmd *buildCmd) Build(contextDir string) error {
297
305
log .Infof ("Finished building %s" , imageName .ShortName ())
298
306
return nil
299
307
}
308
+
309
+ func (cmd * buildCmd ) prepareChroot (context string ) error {
310
+ if runtime .GOOS != "linux" {
311
+ return fmt .Errorf ("cannot prepare chroot on %s" , runtime .GOOS )
312
+ }
313
+
314
+ dest , err := filepath .Abs (cmd .chroot )
315
+ if err != nil {
316
+ return fmt .Errorf ("failed to convert chroot path to absolute: %s" , err )
317
+ } else if _ , err := os .Lstat (dest ); err == nil || ! os .IsNotExist (err ) {
318
+ return fmt .Errorf ("chroot target must not exist: %s" , err )
319
+ }
320
+
321
+ certs := filepath .Join (cmd .chroot , pathutils .DefaultInternalDir , "certs" )
322
+ if err := os .MkdirAll (certs , 0644 ); err != nil {
323
+ return fmt .Errorf ("failed to create chroot cert dir: %s" , err )
324
+ }
325
+ // TODO: copy all certs into the chroot environment.
326
+
327
+ dev := filepath .Join (cmd .chroot , "dev" )
328
+ if err := os .MkdirAll (dev , 0644 ); err != nil {
329
+ return fmt .Errorf ("failed to create chroot /dev dir: %s" , err )
330
+ }
331
+ // TODO: Create all nods
332
+ return syscall .Chroot (dest )
333
+ }
0 commit comments