Skip to content

Commit 7fd8b57

Browse files
authored
Merge pull request #3374 from kolyshkin/cli-nits
Assorted CLI nitpicks
2 parents 4e0d689 + 40b0088 commit 7fd8b57

File tree

7 files changed

+60
-50
lines changed

7 files changed

+60
-50
lines changed

checkpoint.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,24 @@ checkpointed.`,
6060
return err
6161
}
6262
if status == libcontainer.Created || status == libcontainer.Stopped {
63-
fatal(fmt.Errorf("Container cannot be checkpointed in %s state", status.String()))
63+
return fmt.Errorf("Container cannot be checkpointed in %s state", status.String())
6464
}
65-
options := criuOptions(context)
65+
options, err := criuOptions(context)
66+
if err != nil {
67+
return err
68+
}
69+
6670
if !(options.LeaveRunning || options.PreDump) {
6771
// destroy container unless we tell CRIU to keep it
6872
defer destroy(container)
6973
}
7074
// these are the mandatory criu options for a container
71-
setPageServer(context, options)
72-
setManageCgroupsMode(context, options)
75+
if err := setPageServer(context, options); err != nil {
76+
return err
77+
}
78+
if err := setManageCgroupsMode(context, options); err != nil {
79+
return err
80+
}
7381
if err := setEmptyNsMask(context, options); err != nil {
7482
return err
7583
}
@@ -109,27 +117,28 @@ func prepareImagePaths(context *cli.Context) (string, string, error) {
109117
return imagePath, parentPath, nil
110118
}
111119

112-
func setPageServer(context *cli.Context, options *libcontainer.CriuOpts) {
120+
func setPageServer(context *cli.Context, options *libcontainer.CriuOpts) error {
113121
// xxx following criu opts are optional
114122
// The dump image can be sent to a criu page server
115123
if psOpt := context.String("page-server"); psOpt != "" {
116124
address, port, err := net.SplitHostPort(psOpt)
117125

118126
if err != nil || address == "" || port == "" {
119-
fatal(errors.New("Use --page-server ADDRESS:PORT to specify page server"))
127+
return errors.New("Use --page-server ADDRESS:PORT to specify page server")
120128
}
121129
portInt, err := strconv.Atoi(port)
122130
if err != nil {
123-
fatal(errors.New("Invalid port number"))
131+
return errors.New("Invalid port number")
124132
}
125133
options.PageServer = libcontainer.CriuPageServerInfo{
126134
Address: address,
127135
Port: int32(portInt),
128136
}
129137
}
138+
return nil
130139
}
131140

132-
func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts) {
141+
func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts) error {
133142
if cgOpt := context.String("manage-cgroups-mode"); cgOpt != "" {
134143
switch cgOpt {
135144
case "soft":
@@ -139,9 +148,10 @@ func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts)
139148
case "strict":
140149
options.ManageCgroupsMode = criu.CriuCgMode_STRICT
141150
default:
142-
fatal(errors.New("Invalid manage cgroups mode"))
151+
return errors.New("Invalid manage cgroups mode")
143152
}
144153
}
154+
return nil
145155
}
146156

147157
var namespaceMapping = map[specs.LinuxNamespaceType]int{

list.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"errors"
66
"fmt"
77
"os"
8-
"path/filepath"
98
"syscall"
109
"text/tabwriter"
1110
"time"
@@ -111,18 +110,20 @@ To list containers created using a non-default value for "--root":
111110
}
112111

113112
func getContainers(context *cli.Context) ([]containerState, error) {
114-
factory, err := loadFactory(context)
115-
if err != nil {
116-
return nil, err
117-
}
118113
root := context.GlobalString("root")
119-
absRoot, err := filepath.Abs(root)
114+
list, err := os.ReadDir(root)
120115
if err != nil {
116+
if errors.Is(err, os.ErrNotExist) && context.IsSet("root") {
117+
// Ignore non-existing default root directory
118+
// (no containers created yet).
119+
return nil, nil
120+
}
121+
// Report other errors, including non-existent custom --root.
121122
return nil, err
122123
}
123-
list, err := os.ReadDir(absRoot)
124+
factory, err := libcontainer.New(root)
124125
if err != nil {
125-
fatal(err)
126+
return nil, err
126127
}
127128

128129
var s []containerState
@@ -136,7 +137,7 @@ func getContainers(context *cli.Context) ([]containerState, error) {
136137
// Possible race with runc delete.
137138
continue
138139
}
139-
fatal(err)
140+
return nil, err
140141
}
141142
// This cast is safe on Linux.
142143
uid := st.Sys().(*syscall.Stat_t).Uid

main.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,12 @@ func main() {
7171
}
7272
app.Version = strings.Join(v, "\n")
7373

74-
xdgRuntimeDir := ""
7574
root := "/run/runc"
76-
if shouldHonorXDGRuntimeDir() {
77-
if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" {
78-
root = runtimeDir + "/runc"
79-
xdgRuntimeDir = root
80-
}
75+
xdgDirUsed := false
76+
xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
77+
if xdgRuntimeDir != "" && shouldHonorXDGRuntimeDir() {
78+
root = xdgRuntimeDir + "/runc"
79+
xdgDirUsed = true
8180
}
8281

8382
app.Flags = []cli.Flag{
@@ -135,7 +134,7 @@ func main() {
135134
featuresCommand,
136135
}
137136
app.Before = func(context *cli.Context) error {
138-
if !context.IsSet("root") && xdgRuntimeDir != "" {
137+
if !context.IsSet("root") && xdgDirUsed {
139138
// According to the XDG specification, we need to set anything in
140139
// XDG_RUNTIME_DIR to have a sticky bit if we don't want it to get
141140
// auto-pruned.

restore.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ using the runc checkpoint command.`,
109109
logrus.Warn("runc checkpoint is untested with rootless containers")
110110
}
111111

112-
options := criuOptions(context)
112+
options, err := criuOptions(context)
113+
if err != nil {
114+
return err
115+
}
113116
if err := setEmptyNsMask(context, options); err != nil {
114117
return err
115118
}
@@ -124,10 +127,10 @@ using the runc checkpoint command.`,
124127
},
125128
}
126129

127-
func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
130+
func criuOptions(context *cli.Context) (*libcontainer.CriuOpts, error) {
128131
imagePath, parentPath, err := prepareImagePaths(context)
129132
if err != nil {
130-
fatal(err)
133+
return nil, err
131134
}
132135

133136
return &libcontainer.CriuOpts{
@@ -145,5 +148,5 @@ func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
145148
StatusFd: context.Int("status-fd"),
146149
LsmProfile: context.String("lsm-profile"),
147150
LsmMountContext: context.String("lsm-mount-context"),
148-
}
151+
}, nil
149152
}

rootless_linux.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ func shouldUseRootlessCgroupManager(context *cli.Context) (bool, error) {
5252
}
5353

5454
func shouldHonorXDGRuntimeDir() bool {
55-
if os.Getenv("XDG_RUNTIME_DIR") == "" {
56-
return false
57-
}
5855
if os.Geteuid() != 0 {
5956
return true
6057
}

utils.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
67
"path/filepath"
@@ -96,17 +97,25 @@ func revisePidFile(context *cli.Context) error {
9697
return context.Set("pid-file", pidFile)
9798
}
9899

99-
// reviseRootDir convert the root to absolute path
100+
// reviseRootDir ensures that the --root option argument,
101+
// if specified, is converted to an absolute and cleaned path,
102+
// and that this path is sane.
100103
func reviseRootDir(context *cli.Context) error {
101-
root := context.GlobalString("root")
102-
if root == "" {
104+
if !context.IsSet("root") {
103105
return nil
104106
}
105-
106-
root, err := filepath.Abs(root)
107+
root, err := filepath.Abs(context.GlobalString("root"))
107108
if err != nil {
108109
return err
109110
}
111+
if root == "/" {
112+
// This can happen if --root argument is
113+
// - "" (i.e. empty);
114+
// - "." (and the CWD is /);
115+
// - "../../.." (enough to get to /);
116+
// - "/" (the actual /).
117+
return errors.New("Option --root argument should not be set to /")
118+
}
110119

111120
return context.GlobalSet("root", root)
112121
}

utils_linux.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,15 @@ import (
2323

2424
var errEmptyID = errors.New("container id cannot be empty")
2525

26-
// loadFactory returns the configured factory instance for execing containers.
27-
func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
28-
root := context.GlobalString("root")
29-
abs, err := filepath.Abs(root)
30-
if err != nil {
31-
return nil, err
32-
}
33-
34-
return libcontainer.New(abs)
35-
}
36-
3726
// getContainer returns the specified container instance by loading it from state
3827
// with the default factory.
3928
func getContainer(context *cli.Context) (libcontainer.Container, error) {
4029
id := context.Args().First()
4130
if id == "" {
4231
return nil, errEmptyID
4332
}
44-
factory, err := loadFactory(context)
33+
root := context.GlobalString("root")
34+
factory, err := libcontainer.New(root)
4535
if err != nil {
4636
return nil, err
4737
}
@@ -194,7 +184,8 @@ func createContainer(context *cli.Context, id string, spec *specs.Spec) (libcont
194184
return nil, err
195185
}
196186

197-
factory, err := loadFactory(context)
187+
root := context.GlobalString("root")
188+
factory, err := libcontainer.New(root)
198189
if err != nil {
199190
return nil, err
200191
}

0 commit comments

Comments
 (0)