4
4
"bufio"
5
5
"bytes"
6
6
"context"
7
+ "encoding/json"
7
8
"errors"
8
9
"fmt"
9
10
"io"
@@ -130,18 +131,21 @@ func Run(ctx context.Context, options Options) error {
130
131
}
131
132
}
132
133
133
- logf ("%s - Build development environments from repositories in a container" , color . New (color .Bold ).Sprintf ("envbuilder" ))
134
+ logf (codersdk . LogLevelInfo , "%s - Build development environments from repositories in a container" , newColor (color .Bold ).Sprintf ("envbuilder" ))
134
135
135
136
if options .GitURL != "" {
136
- endStage := startStage ("Cloning Repository %s to %s..." , options .GitURL , options .WorkspaceFolder )
137
+ endStage := startStage ("📦 Cloning %s to %s..." ,
138
+ newColor (color .FgCyan ).Sprintf (options .GitURL ),
139
+ newColor (color .FgCyan ).Sprintf (options .WorkspaceFolder ),
140
+ )
137
141
138
142
reader , writer := io .Pipe ()
139
143
defer reader .Close ()
140
144
defer writer .Close ()
141
145
go func () {
142
146
scanner := bufio .NewScanner (reader )
143
147
for scanner .Scan () {
144
- logf ("git : %s" , scanner .Text ())
148
+ logf (codersdk . LogLevelInfo , "#1 : %s" , scanner .Text ())
145
149
}
146
150
}()
147
151
@@ -165,7 +169,7 @@ func Run(ctx context.Context, options Options) error {
165
169
return err
166
170
}
167
171
168
- endStage ("Cloned Repository " )
172
+ endStage ("📦 Cloned repository! " )
169
173
}
170
174
171
175
var buildParams * BuildParameters
@@ -210,12 +214,14 @@ func Run(ctx context.Context, options Options) error {
210
214
return fmt .Errorf ("read devcontainer.json: %w" , err )
211
215
}
212
216
devContainer , err := ParseDevcontainer (content )
213
- if err != nil {
214
- return fmt .Errorf ("parse devcontainer.json: %w" , err )
215
- }
216
- buildParams , err = devContainer .Compile (options .Filesystem , devcontainerDir , MagicDir )
217
- if err != nil {
218
- return fmt .Errorf ("compile devcontainer.json: %w" , err )
217
+ if err == nil {
218
+ buildParams , err = devContainer .Compile (options .Filesystem , devcontainerDir , MagicDir )
219
+ if err != nil {
220
+ return fmt .Errorf ("compile devcontainer.json: %w" , err )
221
+ }
222
+ } else {
223
+ logf (codersdk .LogLevelError , "Failed to parse devcontainer.json: %s" , err .Error ())
224
+ logf (codersdk .LogLevelError , "Falling back to the default image..." )
219
225
}
220
226
}
221
227
} else {
@@ -241,10 +247,12 @@ func Run(ctx context.Context, options Options) error {
241
247
}
242
248
243
249
HijackLogrus (func (entry * logrus.Entry ) {
244
- logf (codersdk .LogLevelInfo , "#2: %s" , entry .Message )
250
+ logf (codersdk .LogLevelInfo , "#2: %s" , color . HiBlackString ( entry .Message ) )
245
251
})
246
252
247
253
build := func () (v1.Image , error ) {
254
+ endStage := startStage ("🏗️ Building image..." )
255
+ defer endStage ("🏗️ Built image!" )
248
256
// At this point we have all the context, we can now build!
249
257
return executor .DoBuild (& config.KanikoOptions {
250
258
// Boilerplate!
@@ -301,6 +309,29 @@ func Run(ctx context.Context, options Options) error {
301
309
return fmt .Errorf ("get image config: %w" , err )
302
310
}
303
311
312
+ // devcontainer metadata can be persisted through a standard label
313
+ devContainerMetadata , exists := configFile .Config .Labels ["devcontainer.metadata" ]
314
+ if exists {
315
+ var devContainer []* DevContainer
316
+ err := json .Unmarshal ([]byte (devContainerMetadata ), & devContainer )
317
+ if err != nil {
318
+ return fmt .Errorf ("unmarshal metadata: %w" , err )
319
+ }
320
+ logf (codersdk .LogLevelInfo , "#3: 👀 Found devcontainer.json label metadata in image..." )
321
+ for _ , container := range devContainer {
322
+ if container .RemoteUser != "" {
323
+ logf (codersdk .LogLevelInfo , "#3: 🧑 Updating the user to %q!" , container .RemoteUser )
324
+
325
+ configFile .Config .User = container .RemoteUser
326
+ }
327
+ if container .RemoteEnv != nil {
328
+ for key , value := range container .RemoteEnv {
329
+ os .Setenv (key , value )
330
+ }
331
+ }
332
+ }
333
+ }
334
+
304
335
username := configFile .Config .User
305
336
if buildParams .User != "" {
306
337
username = buildParams .User
@@ -326,6 +357,7 @@ func Run(ctx context.Context, options Options) error {
326
357
// in the syscall is what matters.
327
358
user .Username = "root"
328
359
}
360
+ os .Setenv ("HOME" , user .HomeDir )
329
361
330
362
// It must be set in this parent process otherwise nothing will be found!
331
363
for _ , env := range configFile .Config .Env {
@@ -445,7 +477,7 @@ func unsetOptionsEnv() {
445
477
}
446
478
}
447
479
448
- func printOptions (logf func (format string , args ... interface {}), options Options ) {
480
+ func printOptions (logf func (level codersdk. LogLevel , format string , args ... interface {}), options Options ) {
449
481
val := reflect .ValueOf (& options ).Elem ()
450
482
typ := val .Type ()
451
483
@@ -458,13 +490,15 @@ func printOptions(logf func(format string, args ...interface{}), options Options
458
490
}
459
491
switch fieldTyp .Type .Kind () {
460
492
case reflect .String :
461
- logf ("option %s: %q" , fieldTyp .Name , field .String ())
493
+ logf (codersdk . LogLevelDebug , "option %s: %q" , fieldTyp .Name , field .String ())
462
494
case reflect .Bool :
463
495
field .Bool ()
464
496
}
465
497
}
466
498
}
467
499
468
- func stage () {
469
-
500
+ func newColor (value ... color.Attribute ) * color.Color {
501
+ c := color .New (value ... )
502
+ c .EnableColor ()
503
+ return c
470
504
}
0 commit comments