-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
97 lines (92 loc) · 2.63 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path"
"github.com/bottlerocketlabs/localpod/pkg/config"
"github.com/bottlerocketlabs/localpod/pkg/docker"
)
// main
func main() {
err := Run(os.Args, config.NewEnv(os.Environ()), os.Stdin, os.Stdout, os.Stderr)
if err != nil {
log.Fatalf("ERROR: %s", err)
}
}
// Run is the main thread but separated out so easier to test
func Run(args []string, env config.Env, stdin io.Reader, stdout, stderr io.Writer) error {
flags := flag.NewFlagSet(args[0], flag.ExitOnError)
err := flags.Parse(args[1:])
if err != nil {
return err
}
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("could not get current working directory: %w", err)
}
if !docker.HasDocker() {
return fmt.Errorf("could not find 'docker' on PATH")
}
env.Set("localWorkspaceFolder", wd)
var cfg *config.DevContainer
dotConfig := path.Join(wd, ".devcontainer.json")
_, err = os.Stat(dotConfig)
if os.IsNotExist(err) {
cfg, err = config.DevContainerFromEnv(env)
if err != nil {
return fmt.Errorf("could not get config from environment: %w", err)
}
b, err := json.MarshalIndent(&cfg, "", "\t")
if err != nil {
return fmt.Errorf("could not marshal defaultConfig: %w", err)
}
fmt.Printf("DEBUG: writing config file: %s\n", dotConfig)
ioutil.WriteFile(dotConfig, b, 0664)
}
fmt.Printf("DEBUG: reading config file: %s\n", dotConfig)
f, err := os.Open(dotConfig)
if err != nil {
return fmt.Errorf("could not open file %s: %w", dotConfig, err)
}
cfg, err = config.DevContainerFromFile(f)
if err != nil {
return fmt.Errorf("could not process config file %s: %w", dotConfig, err)
}
err = cfg.AddConfigFromEnv(env)
if err != nil {
return fmt.Errorf("could not load environment into config: %w", err)
}
err = docker.BuildImage(cfg, env, stdout, stderr)
if err != nil {
return fmt.Errorf("could not build image from configured dockerfile: %w", err)
}
container, err := docker.CreateContainer(cfg.Name, env, cfg, stdout, stderr)
if err != nil {
return fmt.Errorf("could not create container: %w", err)
}
fmt.Printf("DEBUG: container: %s\n", container.Name)
err = container.Start()
if err != nil {
return fmt.Errorf("could not start container: %w", err)
}
err = container.Setup()
if err != nil {
return fmt.Errorf("could not setup container: %w", err)
}
err = container.Exec(env, stdin, stdout, stderr)
if err != nil {
return fmt.Errorf("could not exec container: %w", err)
}
if container.Config.ShutdownAction == config.StopContainer {
err := container.Stop()
if err != nil {
return fmt.Errorf("could not stop container: %w", err)
}
}
return nil
}