forked from genuinetools/img
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
139 lines (119 loc) · 3.42 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/genuinetools/img/internal/binutils"
_ "github.com/genuinetools/img/internal/unshare"
"github.com/genuinetools/img/types"
"github.com/genuinetools/img/version"
"github.com/genuinetools/pkg/cli"
"github.com/sirupsen/logrus"
)
const (
defaultBackend = types.AutoBackend
defaultDockerRegistry = "https://index.docker.io/v1/"
defaultDockerfileName = "Dockerfile"
)
var (
backend string
stateDir string
debug bool
validBackends = []string{types.AutoBackend, types.NativeBackend, types.OverlayFSBackend}
)
// stringSlice is a slice of strings
type stringSlice []string
// implement the flag interface for stringSlice
func (s *stringSlice) String() string {
return fmt.Sprintf("%s", *s)
}
func (s *stringSlice) Set(value string) error {
*s = append(*s, value)
return nil
}
func main() {
// Create a new cli program.
p := cli.NewProgram()
p.Name = "img"
p.Description = "Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder"
// Set the GitCommit and Version.
p.GitCommit = version.GITCOMMIT
p.Version = version.VERSION
// Build the list of available commands.
p.Commands = []cli.Command{
&buildCommand{},
&diskUsageCommand{},
&listCommand{},
&loginCommand{},
&logoutCommand{},
&pruneCommand{},
&pullCommand{},
&pushCommand{},
&removeCommand{},
&saveCommand{},
&tagCommand{},
&unpackCommand{},
}
defaultStateDir := defaultStateDirectory()
// Setup the global flags.
p.FlagSet = flag.NewFlagSet("img", flag.ExitOnError)
p.FlagSet.BoolVar(&debug, "debug", false, "enable debug logging")
p.FlagSet.BoolVar(&debug, "d", false, "enable debug logging")
p.FlagSet.StringVar(&backend, "backend", defaultBackend, fmt.Sprintf("backend for snapshots (%v)", validBackends))
p.FlagSet.StringVar(&backend, "b", defaultBackend, fmt.Sprintf("backend for snapshots (%v)", validBackends))
p.FlagSet.StringVar(&stateDir, "state", defaultStateDir, fmt.Sprintf("directory to hold the global state"))
p.FlagSet.StringVar(&stateDir, "s", defaultStateDir, fmt.Sprintf("directory to hold the global state"))
// Set the before function.
p.Before = func(ctx context.Context) error {
// Set the log level.
if debug {
logrus.SetLevel(logrus.DebugLevel)
}
// Make sure we have a valid backend.
found := false
for _, vb := range validBackends {
if vb == backend {
found = true
break
}
}
if !found {
return fmt.Errorf("%s is not a valid snapshots backend", backend)
}
return nil
}
// Run our program.
p.Run()
}
func defaultStateDirectory() string {
// pam_systemd sets XDG_RUNTIME_DIR but not other dirs.
xdgDataHome := os.Getenv("XDG_DATA_HOME")
if xdgDataHome != "" {
dirs := strings.Split(xdgDataHome, ":")
return filepath.Join(dirs[0], "img")
}
home := os.Getenv("HOME")
if home != "" {
return filepath.Join(home, ".local", "share", "img")
}
return "/tmp/img"
}
// If the command requires runc and we do not have it installed,
// install it from the embedded asset.
func installRuncIfDNE() error {
if binutils.RuncBinaryExists() {
// return early.
return nil
}
if len(os.Getenv("IMG_DISABLE_EMBEDDED_RUNC")) > 0 {
// Fail early with the error to install runc.
return fmt.Errorf("please install `runc`")
}
if _, err := binutils.InstallRuncBinary(); err != nil {
return fmt.Errorf("installing embedded runc binary failed: %v", err)
}
return nil
}