summaryrefslogtreecommitdiff
path: root/cmd/podman/libpodruntime/runtime.go
blob: be15d138dd4acbe7aa5d24717cc6715a85d64642 (plain)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package libpodruntime

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/containers/libpod/libpod"
	"github.com/containers/libpod/pkg/rootless"
	"github.com/containers/libpod/pkg/util"
	"github.com/containers/storage"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
	storageOpts, err := GetDefaultStoreOptions()
	if err != nil {
		return nil, err
	}
	return GetRuntimeWithStorageOpts(c, &storageOpts)
}

// GetContainerRuntime generates a new libpod runtime configured by command line options for containers
func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) {
	mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
	if err != nil {
		return nil, err
	}
	storageOpts, err := GetDefaultStoreOptions()
	if err != nil {
		return nil, err
	}
	storageOpts.UIDMap = mappings.UIDMap
	storageOpts.GIDMap = mappings.GIDMap
	return GetRuntimeWithStorageOpts(c, &storageOpts)
}

func GetRootlessStorageOpts() (storage.StoreOptions, error) {
	var opts storage.StoreOptions

	rootlessRuntime, err := libpod.GetRootlessRuntimeDir()
	if err != nil {
		return opts, err
	}
	opts.RunRoot = filepath.Join(rootlessRuntime, "run")

	dataDir := os.Getenv("XDG_DATA_HOME")
	if dataDir == "" {
		home := os.Getenv("HOME")
		if home == "" {
			return opts, fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty")
		}
		// runc doesn't like symlinks in the rootfs path, and at least
		// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
		resolvedHome, err := filepath.EvalSymlinks(home)
		if err != nil {
			return opts, errors.Wrapf(err, "cannot resolve %s", home)
		}
		dataDir = filepath.Join(resolvedHome, ".local", "share")
	}
	opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
	opts.GraphDriverName = "vfs"
	return opts, nil
}

func GetDefaultStoreOptions() (storage.StoreOptions, error) {
	storageOpts := storage.DefaultStoreOptions
	if rootless.IsRootless() {
		var err error
		storageOpts, err = GetRootlessStorageOpts()
		if err != nil {
			return storageOpts, err
		}

		storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf")
		if _, err := os.Stat(storageConf); err == nil {
			storage.ReloadConfigurationFile(storageConf, &storageOpts)
		}
	}
	return storageOpts, nil
}

// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
	options := []libpod.RuntimeOption{}

	if c.GlobalIsSet("root") {
		storageOpts.GraphRoot = c.GlobalString("root")
	}
	if c.GlobalIsSet("runroot") {
		storageOpts.RunRoot = c.GlobalString("runroot")
	}
	if c.GlobalIsSet("storage-driver") {
		storageOpts.GraphDriverName = c.GlobalString("storage-driver")
	}
	if c.GlobalIsSet("storage-opt") {
		storageOpts.GraphDriverOptions = c.GlobalStringSlice("storage-opt")
	}

	options = append(options, libpod.WithStorageConfig(*storageOpts))

	// TODO CLI flags for image config?
	// TODO CLI flag for signature policy?

	if c.GlobalIsSet("namespace") {
		options = append(options, libpod.WithNamespace(c.GlobalString("namespace")))
	}

	if c.GlobalIsSet("runtime") {
		options = append(options, libpod.WithOCIRuntime(c.GlobalString("runtime")))
	}

	if c.GlobalIsSet("conmon") {
		options = append(options, libpod.WithConmonPath(c.GlobalString("conmon")))
	}
	if c.GlobalIsSet("tmpdir") {
		options = append(options, libpod.WithTmpDir(c.GlobalString("tmpdir")))
	}

	if c.GlobalIsSet("cgroup-manager") {
		options = append(options, libpod.WithCgroupManager(c.GlobalString("cgroup-manager")))
	} else {
		if rootless.IsRootless() {
			options = append(options, libpod.WithCgroupManager("cgroupfs"))
		}
	}

	// TODO flag to set libpod static dir?
	// TODO flag to set libpod tmp dir?

	if c.GlobalIsSet("cni-config-dir") {
		options = append(options, libpod.WithCNIConfigDir(c.GlobalString("cni-config-dir")))
	}
	if c.GlobalIsSet("default-mounts-file") {
		options = append(options, libpod.WithDefaultMountsFile(c.GlobalString("default-mounts-file")))
	}
	options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path"), c.GlobalIsSet("hooks-dir-path")))

	// TODO flag to set CNI plugins dir?

	// Pod create options
	if c.IsSet("infra-image") {
		options = append(options, libpod.WithDefaultInfraImage(c.String("infra-image")))
	}

	if c.IsSet("infra-command") {
		options = append(options, libpod.WithDefaultInfraCommand(c.String("infra-command")))
	}
	if c.IsSet("config") {
		return libpod.NewRuntimeFromConfig(c.String("config"), options...)
	}
	return libpod.NewRuntime(options...)
}