@@ -92,7 +92,7 @@ func Run(ctx context.Context, opts options.Options) error {
92
92
93
93
opts .Logger (log .LevelInfo , "%s %s - Build development environments from repositories in a container" , newColor (color .Bold ).Sprintf ("envbuilder" ), buildinfo .Version ())
94
94
95
- cleanupDockerConfigJSON , err := initDockerConfigJSON (opts .DockerConfigBase64 )
95
+ cleanupDockerConfigJSON , err := initDockerConfigJSON (opts .Logger , opts . MagicDir , opts . DockerConfigBase64 )
96
96
if err != nil {
97
97
return err
98
98
}
@@ -168,7 +168,7 @@ func Run(ctx context.Context, opts options.Options) error {
168
168
}
169
169
170
170
defaultBuildParams := func () (* devcontainer.Compiled , error ) {
171
- dockerfile := filepath .Join (constants .MagicDir , "Dockerfile" )
171
+ dockerfile := filepath .Join (opts .MagicDir . String () , "Dockerfile" )
172
172
file , err := opts .Filesystem .OpenFile (dockerfile , os .O_CREATE | os .O_WRONLY , 0o644 )
173
173
if err != nil {
174
174
return nil , err
@@ -190,7 +190,7 @@ func Run(ctx context.Context, opts options.Options) error {
190
190
return & devcontainer.Compiled {
191
191
DockerfilePath : dockerfile ,
192
192
DockerfileContent : content ,
193
- BuildContext : constants .MagicDir ,
193
+ BuildContext : opts .MagicDir . String () ,
194
194
}, nil
195
195
}
196
196
@@ -232,7 +232,7 @@ func Run(ctx context.Context, opts options.Options) error {
232
232
opts .Logger (log .LevelInfo , "No Dockerfile or image specified; falling back to the default image..." )
233
233
fallbackDockerfile = defaultParams .DockerfilePath
234
234
}
235
- buildParams , err = devContainer .Compile (opts .Filesystem , devcontainerDir , constants .MagicDir , fallbackDockerfile , opts .WorkspaceFolder , false , os .LookupEnv )
235
+ buildParams , err = devContainer .Compile (opts .Filesystem , devcontainerDir , opts .MagicDir . String () , fallbackDockerfile , opts .WorkspaceFolder , false , os .LookupEnv )
236
236
if err != nil {
237
237
return fmt .Errorf ("compile devcontainer.json: %w" , err )
238
238
}
@@ -304,7 +304,7 @@ func Run(ctx context.Context, opts options.Options) error {
304
304
// So we add them to the default ignore list. See:
305
305
// https://github.com/GoogleContainerTools/kaniko/blob/63be4990ca5a60bdf06ddc4d10aa4eca0c0bc714/cmd/executor/cmd/root.go#L136
306
306
ignorePaths := append ([]string {
307
- constants .MagicDir ,
307
+ opts .MagicDir . String () ,
308
308
opts .WorkspaceFolder ,
309
309
// See: https://github.com/coder/envbuilder/issues/37
310
310
"/etc/resolv.conf" ,
@@ -332,31 +332,26 @@ func Run(ctx context.Context, opts options.Options) error {
332
332
if err := util .AddAllowedPathToDefaultIgnoreList (opts .BinaryPath ); err != nil {
333
333
return fmt .Errorf ("add envbuilder binary to ignore list: %w" , err )
334
334
}
335
- if err := util .AddAllowedPathToDefaultIgnoreList (constants . MagicImage ); err != nil {
335
+ if err := util .AddAllowedPathToDefaultIgnoreList (opts . MagicDir . Image () ); err != nil {
336
336
return fmt .Errorf ("add magic image file to ignore list: %w" , err )
337
337
}
338
- magicTempDir := filepath .Join (buildParams .BuildContext , constants .MagicTempDir )
339
- if err := opts .Filesystem .MkdirAll (magicTempDir , 0o755 ); err != nil {
338
+ magicTempDir := constants . MagicDir ( filepath .Join (buildParams .BuildContext , constants .MagicTempDir ) )
339
+ if err := opts .Filesystem .MkdirAll (magicTempDir . String () , 0o755 ); err != nil {
340
340
return fmt .Errorf ("create magic temp dir in build context: %w" , err )
341
341
}
342
342
// Add the magic directives that embed the binary into the built image.
343
343
buildParams .DockerfileContent += constants .MagicDirectives
344
344
// Copy the envbuilder binary into the build context.
345
345
// External callers will need to specify the path to the desired envbuilder binary.
346
- envbuilderBinDest := filepath .Join (
347
- magicTempDir ,
348
- filepath .Base (constants .MagicBinaryLocation ),
349
- )
346
+ envbuilderBinDest := filepath .Join (magicTempDir .String (), "envbuilder" )
350
347
// Also touch the magic file that signifies the image has been built!
351
- magicImageDest := filepath .Join (
352
- magicTempDir ,
353
- filepath .Base (constants .MagicImage ),
354
- )
348
+ // magicImageDest := filepath.Join(magicTempDir, "image")
349
+ magicImageDest := magicTempDir .Image ()
355
350
// Clean up after build!
356
351
var cleanupOnce sync.Once
357
352
cleanupBuildContext = func () {
358
353
cleanupOnce .Do (func () {
359
- for _ , path := range []string {magicImageDest , envbuilderBinDest , magicTempDir } {
354
+ for _ , path := range []string {magicImageDest , envbuilderBinDest , magicTempDir . String () } {
360
355
if err := opts .Filesystem .Remove (path ); err != nil {
361
356
opts .Logger (log .LevelWarn , "failed to clean up magic temp dir from build context: %w" , err )
362
357
}
@@ -370,15 +365,14 @@ func Run(ctx context.Context, opts options.Options) error {
370
365
return fmt .Errorf ("copy envbuilder binary to build context: %w" , err )
371
366
}
372
367
373
- opts .Logger (log .LevelDebug , "touching magic image file at %q in build context %q" , magicImageDest , buildParams . BuildContext )
368
+ opts .Logger (log .LevelDebug , "touching magic image file at %q in build context %q" , magicImageDest , magicTempDir )
374
369
if err := touchFile (opts .Filesystem , magicImageDest , 0o755 ); err != nil {
375
370
return fmt .Errorf ("touch magic image file in build context: %w" , err )
376
371
}
377
-
378
372
}
379
373
380
374
// temp move of all ro mounts
381
- tempRemountDest := filepath .Join ("/" , constants .MagicDir , "mnt" )
375
+ tempRemountDest := filepath .Join (opts .MagicDir . String () , "mnt" )
382
376
// ignorePrefixes is a superset of ignorePaths that we pass to kaniko's
383
377
// IgnoreList.
384
378
ignorePrefixes := append ([]string {"/dev" , "/proc" , "/sys" }, ignorePaths ... )
@@ -399,8 +393,8 @@ func Run(ctx context.Context, opts options.Options) error {
399
393
defer closeStderr ()
400
394
build := func () (v1.Image , error ) {
401
395
defer cleanupBuildContext ()
402
- _ , alreadyBuiltErr := opts .Filesystem .Stat (constants . MagicFile )
403
- _ , isImageErr := opts .Filesystem .Stat (constants . MagicImage )
396
+ _ , alreadyBuiltErr := opts .Filesystem .Stat (opts . MagicDir . Built () )
397
+ _ , isImageErr := opts .Filesystem .Stat (opts . MagicDir . Image () )
404
398
if (alreadyBuiltErr == nil && opts .SkipRebuild ) || isImageErr == nil {
405
399
endStage := startStage ("🏗️ Skipping build because of cache..." )
406
400
imageRef , err := devcontainer .ImageFromDockerfile (buildParams .DockerfileContent )
@@ -545,7 +539,7 @@ func Run(ctx context.Context, opts options.Options) error {
545
539
546
540
// Create the magic file to indicate that this build
547
541
// has already been ran before!
548
- file , err := opts .Filesystem .Create (constants . MagicFile )
542
+ file , err := opts .Filesystem .Create (opts . MagicDir . Built () )
549
543
if err != nil {
550
544
return fmt .Errorf ("create magic file: %w" , err )
551
545
}
@@ -752,7 +746,7 @@ func Run(ctx context.Context, opts options.Options) error {
752
746
opts .Logger (log .LevelInfo , "=== Running the setup command %q as the root user..." , opts .SetupScript )
753
747
754
748
envKey := "ENVBUILDER_ENV"
755
- envFile := filepath .Join ("/" , constants .MagicDir , "environ" )
749
+ envFile := filepath .Join (opts .MagicDir . String () , "environ" )
756
750
file , err := os .Create (envFile )
757
751
if err != nil {
758
752
return fmt .Errorf ("create environ file: %w" , err )
@@ -876,7 +870,7 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
876
870
877
871
opts .Logger (log .LevelInfo , "%s %s - Build development environments from repositories in a container" , newColor (color .Bold ).Sprintf ("envbuilder" ), buildinfo .Version ())
878
872
879
- cleanupDockerConfigJSON , err := initDockerConfigJSON (opts .DockerConfigBase64 )
873
+ cleanupDockerConfigJSON , err := initDockerConfigJSON (opts .Logger , opts . MagicDir , opts . DockerConfigBase64 )
880
874
if err != nil {
881
875
return nil , err
882
876
}
@@ -1080,7 +1074,7 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
1080
1074
// So we add them to the default ignore list. See:
1081
1075
// https://github.com/GoogleContainerTools/kaniko/blob/63be4990ca5a60bdf06ddc4d10aa4eca0c0bc714/cmd/executor/cmd/root.go#L136
1082
1076
ignorePaths := append ([]string {
1083
- constants .MagicDir ,
1077
+ opts .MagicDir . String () ,
1084
1078
opts .WorkspaceFolder ,
1085
1079
// See: https://github.com/coder/envbuilder/issues/37
1086
1080
"/etc/resolv.conf" ,
@@ -1103,29 +1097,25 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
1103
1097
// build via executor.RunCacheProbe we need to have the *exact* copy of the
1104
1098
// envbuilder binary available used to build the image and we also need to
1105
1099
// add the magic directives to the Dockerfile content.
1100
+ // MAGICDIR
1106
1101
buildParams .DockerfileContent += constants .MagicDirectives
1107
1102
magicTempDir := filepath .Join (buildParams .BuildContext , constants .MagicTempDir )
1108
1103
if err := opts .Filesystem .MkdirAll (magicTempDir , 0o755 ); err != nil {
1109
1104
return nil , fmt .Errorf ("create magic temp dir in build context: %w" , err )
1110
1105
}
1111
- envbuilderBinDest := filepath .Join (
1112
- magicTempDir ,
1113
- filepath .Base (constants .MagicBinaryLocation ),
1114
- )
1106
+ envbuilderBinDest := filepath .Join (magicTempDir , "envbuilder" )
1115
1107
1116
1108
// Copy the envbuilder binary into the build context.
1117
- opts .Logger (log .LevelDebug , "copying envbuilder binary at %q to build context %q" , opts .BinaryPath , buildParams . BuildContext )
1109
+ opts .Logger (log .LevelDebug , "copying envbuilder binary at %q to build context %q" , opts .BinaryPath , envbuilderBinDest )
1118
1110
if err := copyFile (opts .Filesystem , opts .BinaryPath , envbuilderBinDest , 0o755 ); err != nil {
1119
1111
return nil , xerrors .Errorf ("copy envbuilder binary to build context: %w" , err )
1120
1112
}
1121
1113
1122
- // Also touch the magic file that signifies the image has been built!
1123
- magicImageDest := filepath .Join (
1124
- magicTempDir ,
1125
- filepath .Base (constants .MagicImage ),
1126
- )
1114
+ // Also touch the magic file that signifies the image has been built!A
1115
+ magicImageDest := filepath .Join (magicTempDir , "image" )
1116
+ opts .Logger (log .LevelDebug , "touching magic image file at %q in build context %q" , magicImageDest , magicTempDir )
1127
1117
if err := touchFile (opts .Filesystem , magicImageDest , 0o755 ); err != nil {
1128
- return nil , fmt .Errorf ("touch magic image file in build context : %w" , err )
1118
+ return nil , fmt .Errorf ("touch magic image file at %q : %w" , magicImageDest , err )
1129
1119
}
1130
1120
defer func () {
1131
1121
// Clean up after we're done!
@@ -1417,21 +1407,24 @@ func findDevcontainerJSON(workspaceFolder string, options options.Options) (stri
1417
1407
// maybeDeleteFilesystem wraps util.DeleteFilesystem with a guard to hopefully stop
1418
1408
// folks from unwittingly deleting their entire root directory.
1419
1409
func maybeDeleteFilesystem (logger log.Func , force bool ) error {
1410
+ // We always expect the magic directory to be set to the default, signifying that
1411
+ // the user is running envbuilder in a container.
1412
+ // If this is set to anything else we should bail out to prevent accidental data loss.
1413
+ defaultMagicDir := constants .MagicDir ("" )
1420
1414
kanikoDir , ok := os .LookupEnv ("KANIKO_DIR" )
1421
- if ! ok || strings .TrimSpace (kanikoDir ) != constants .MagicDir {
1422
- if force {
1423
- bailoutSecs := 10
1424
- logger (log .LevelWarn , "WARNING! BYPASSING SAFETY CHECK! THIS WILL DELETE YOUR ROOT FILESYSTEM!" )
1425
- logger (log .LevelWarn , "You have %d seconds to bail out!" , bailoutSecs )
1426
- for i := bailoutSecs ; i > 0 ; i -- {
1427
- logger (log .LevelWarn , "%d..." , i )
1428
- <- time .After (time .Second )
1429
- }
1430
- } else {
1431
- logger (log .LevelError , "KANIKO_DIR is not set to %s. Bailing!\n " , constants .MagicDir )
1415
+ if ! ok || strings .TrimSpace (kanikoDir ) != defaultMagicDir .String () {
1416
+ if ! force {
1417
+ logger (log .LevelError , "KANIKO_DIR is not set to %s. Bailing!\n " , defaultMagicDir .String ())
1432
1418
logger (log .LevelError , "To bypass this check, set FORCE_SAFE=true." )
1433
1419
return errors .New ("safety check failed" )
1434
1420
}
1421
+ bailoutSecs := 10
1422
+ logger (log .LevelWarn , "WARNING! BYPASSING SAFETY CHECK! THIS WILL DELETE YOUR ROOT FILESYSTEM!" )
1423
+ logger (log .LevelWarn , "You have %d seconds to bail out!" , bailoutSecs )
1424
+ for i := bailoutSecs ; i > 0 ; i -- {
1425
+ logger (log .LevelWarn , "%d..." , i )
1426
+ <- time .After (time .Second )
1427
+ }
1435
1428
}
1436
1429
1437
1430
return util .DeleteFilesystem ()
@@ -1469,13 +1462,13 @@ func touchFile(fs billy.Filesystem, dst string, mode fs.FileMode) error {
1469
1462
return f .Close ()
1470
1463
}
1471
1464
1472
- func initDockerConfigJSON (dockerConfigBase64 string ) (func () error , error ) {
1465
+ func initDockerConfigJSON (logf log. Func , magicDir constants. MagicDir , dockerConfigBase64 string ) (func () error , error ) {
1473
1466
var cleanupOnce sync.Once
1474
1467
noop := func () error { return nil }
1475
1468
if dockerConfigBase64 == "" {
1476
1469
return noop , nil
1477
1470
}
1478
- cfgPath := filepath .Join (constants . MagicDir , "config.json" )
1471
+ cfgPath := filepath .Join (magicDir . String () , "config.json" )
1479
1472
decoded , err := base64 .StdEncoding .DecodeString (dockerConfigBase64 )
1480
1473
if err != nil {
1481
1474
return noop , fmt .Errorf ("decode docker config: %w" , err )
@@ -1489,10 +1482,14 @@ func initDockerConfigJSON(dockerConfigBase64 string) (func() error, error) {
1489
1482
if err != nil {
1490
1483
return noop , fmt .Errorf ("parse docker config: %w" , err )
1491
1484
}
1485
+ for k := range configFile .AuthConfigs {
1486
+ logf (log .LevelInfo , "Docker config contains auth for registry %q" , k )
1487
+ }
1492
1488
err = os .WriteFile (cfgPath , decoded , 0o644 )
1493
1489
if err != nil {
1494
1490
return noop , fmt .Errorf ("write docker config: %w" , err )
1495
1491
}
1492
+ logf (log .LevelInfo , "Wrote Docker config JSON to %s" , cfgPath )
1496
1493
cleanup := func () error {
1497
1494
var cleanupErr error
1498
1495
cleanupOnce .Do (func () {
@@ -1501,7 +1498,7 @@ func initDockerConfigJSON(dockerConfigBase64 string) (func() error, error) {
1501
1498
if ! errors .Is (err , fs .ErrNotExist ) {
1502
1499
cleanupErr = fmt .Errorf ("remove docker config: %w" , cleanupErr )
1503
1500
}
1504
- _ , _ = fmt . Fprintf ( os . Stderr , "failed to remove the Docker config secret file: %s\n " , cleanupErr )
1501
+ logf ( log . LevelError , "failed to remove the Docker config secret file: %s" , cleanupErr )
1505
1502
}
1506
1503
})
1507
1504
return cleanupErr
0 commit comments