This repository has been archived by the owner on Feb 24, 2020. It is now read-only.
/
run_prepared.go
182 lines (158 loc) · 5.72 KB
/
run_prepared.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright 2015 The rkt Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//+build linux
package main
import (
"github.com/rkt/rkt/common"
pkgPod "github.com/rkt/rkt/pkg/pod"
"github.com/rkt/rkt/stage0"
"github.com/rkt/rkt/store/imagestore"
"github.com/rkt/rkt/store/treestore"
"github.com/spf13/cobra"
)
const (
cmdRunPreparedName = "run-prepared"
)
var (
cmdRunPrepared = &cobra.Command{
Use: "run-prepared UUID",
Short: "Run a prepared application pod in rkt",
Long: `Runs a previously prepared pod by its UUID`,
Run: ensureSuperuser(runWrapper(runRunPrepared)),
}
)
func init() {
cmdRkt.AddCommand(cmdRunPrepared)
cmdRunPrepared.Flags().Var(&flagNet, "net", "configure the pod's networking. Optionally, pass a list of user-configured networks to load and set arguments to pass to each network, respectively. Syntax: --net[=n[:args]][,]")
cmdRunPrepared.Flags().Lookup("net").NoOptDefVal = "default"
cmdRunPrepared.Flags().Var(&flagDNS, "dns", "name servers to write in /etc/resolv.conf. Pass 'host' to use host's resolv.conf. Pass 'none' to ignore CNI DNS config")
cmdRunPrepared.Flags().Var(&flagDNSSearch, "dns-search", "DNS search domains to write in /etc/resolv.conf")
cmdRunPrepared.Flags().Var(&flagDNSOpt, "dns-opt", "DNS options to write in /etc/resolv.conf")
cmdRunPrepared.Flags().StringVar(&flagDNSDomain, "dns-domain", "", "DNS domain to write in /etc/resolv.conf")
cmdRunPrepared.Flags().Var(&flagHostsEntries, "hosts-entry", "Entries to add to the pod-wide /etc/hosts. Pass 'host' to use the host's /etc/hosts")
cmdRunPrepared.Flags().BoolVar(&flagInteractive, "interactive", false, "run pod interactively")
cmdRunPrepared.Flags().BoolVar(&flagMDSRegister, "mds-register", false, "register pod with metadata service")
cmdRunPrepared.Flags().StringVar(&flagHostname, "hostname", "", `pod's hostname. If empty, it will be "rkt-$PODUUID"`)
cmdRunPrepared.Flags().StringVar(&flagIPCMode, "ipc", "", `whether to stay in the host IPC namespace. Syntax: --ipc=[auto|private|parent]`)
}
func runRunPrepared(cmd *cobra.Command, args []string) (exit int) {
if len(args) != 1 {
cmd.Usage()
return 254
}
p, err := pkgPod.PodFromUUIDString(getDataDir(), args[0])
if err != nil {
stderr.PrintE("problem retrieving pod", err)
return 254
}
defer p.Close()
s, err := imagestore.NewStore(storeDir())
if err != nil {
stderr.PrintE("cannot open store", err)
return 254
}
ts, err := treestore.NewStore(treeStoreDir(), s)
if err != nil {
stderr.PrintE("cannot open treestore", err)
return 254
}
if p.State() != pkgPod.Prepared {
stderr.Printf("pod %q is not prepared", p.UUID)
return 254
}
_, manifest, err := p.PodManifest()
if err != nil {
stderr.PrintE("cannot read pod manifest", err)
return 254
}
if flagInteractive {
if len(manifest.Apps) > 1 {
stderr.Print("interactive option only supports pods with one app")
return 254
}
}
// Make sure we have a metadata service available before we move to
// run state so that the user can rerun the command without needing
// to prepare the image again.
if flagMDSRegister {
if err := stage0.CheckMdsAvailability(); err != nil {
stderr.Error(err)
return 254
}
}
if err := p.ToRun(); err != nil {
stderr.PrintE("cannot transition to run", err)
return 254
}
lfd, err := p.Fd()
if err != nil {
stderr.PrintE("unable to get lock fd", err)
return 254
}
rktgid, err := common.LookupGid(common.RktGroup)
if err != nil {
stderr.Printf("group %q not found, will use default gid when rendering images", common.RktGroup)
rktgid = -1
}
ovlOk := true
if err := common.PathSupportsOverlay(getDataDir()); err != nil {
if oerr, ok := err.(common.ErrOverlayUnsupported); ok {
stderr.Printf("disabling overlay support: %q", oerr.Error())
ovlOk = false
} else {
stderr.PrintE("error determining overlay support", err)
return 254
}
}
ovlPrep := p.UsesOverlay()
// should not happen, maybe the data directory moved from an overlay-enabled fs to another location
// between prepare and run-prepared
if ovlPrep && !ovlOk {
stderr.Print("unable to run prepared overlay-enabled pod: overlay not supported")
return 254
}
DNSConfMode, DNSConfig, HostsEntries, err := parseDNSFlags(flagHostsEntries, flagDNS, flagDNSSearch, flagDNSOpt, flagDNSDomain)
if err != nil {
stderr.PrintE("error with dns flags", err)
return 254
}
rcfg := stage0.RunConfig{
CommonConfig: &stage0.CommonConfig{
DataDir: getDataDir(),
Store: s,
TreeStore: ts,
UUID: p.UUID,
Debug: globalFlags.Debug,
},
Net: flagNet,
LockFd: lfd,
Interactive: flagInteractive,
DNSConfMode: DNSConfMode,
DNSConfig: DNSConfig,
HostsEntries: *HostsEntries,
MDSRegister: flagMDSRegister,
Apps: manifest.Apps,
RktGid: rktgid,
Hostname: flagHostname,
InsecureCapabilities: globalFlags.InsecureFlags.SkipCapabilities(),
InsecurePaths: globalFlags.InsecureFlags.SkipPaths(),
InsecureSeccomp: globalFlags.InsecureFlags.SkipSeccomp(),
UseOverlay: ovlPrep && ovlOk,
}
if globalFlags.Debug {
stage0.InitDebug()
}
stage0.Run(rcfg, p.Path(), getDataDir()) // execs, never returns
return 254
}