Add a 'start' command
When any non-global-flag parameter appears on the command line make sure there's a "command" even in the 'start' (run) case to ensure its not ambiguous as to what the arg is. For example, w/o this fix its not clear if runc foo means 'foo' is the name of a config file or an unknown command. Or worse, you can't name a config file the same a ANY command, even future (yet to be created) commands. We should fix this now before we ship 1.0 and are forced to support this ambiguous case for a long time. Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
parent
744a6b0e7b
commit
714ae2acc9
22
README.md
22
README.md
|
@ -29,11 +29,9 @@ sudo make install
|
||||||
|
|
||||||
### Using:
|
### Using:
|
||||||
|
|
||||||
To run a container that you received just execute `runc` with the JSON format as the argument or have a
|
To run a container, execute `runc start` in the bundle's root directory:
|
||||||
`config.json` file in the current working directory.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
runc
|
runc start
|
||||||
/ $ ps
|
/ $ ps
|
||||||
PID USER COMMAND
|
PID USER COMMAND
|
||||||
1 daemon sh
|
1 daemon sh
|
||||||
|
@ -41,6 +39,18 @@ PID USER COMMAND
|
||||||
/ $
|
/ $
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or you can specify the path to a JSON configuration file:
|
||||||
|
```bash
|
||||||
|
runc start config.json
|
||||||
|
/ $ ps
|
||||||
|
PID USER COMMAND
|
||||||
|
1 daemon sh
|
||||||
|
5 daemon sh
|
||||||
|
/ $
|
||||||
|
```
|
||||||
|
Note: the use of the `start` command is required when specifying a
|
||||||
|
configuration file.
|
||||||
|
|
||||||
### OCF Container JSON Format:
|
### OCF Container JSON Format:
|
||||||
|
|
||||||
Below is a sample `config.json` configuration file. It assumes that
|
Below is a sample `config.json` configuration file. It assumes that
|
||||||
|
@ -210,9 +220,9 @@ tar -C rootfs -xf busybox.tar
|
||||||
```
|
```
|
||||||
* Create a file called `config.json` using the example from above. You can also
|
* Create a file called `config.json` using the example from above. You can also
|
||||||
generate a spec using `runc spec`, redirecting the output into `config.json`
|
generate a spec using `runc spec`, redirecting the output into `config.json`
|
||||||
* Execute `runc` and you should be placed into a shell where you can run `ps`:
|
* Execute `runc start` and you should be placed into a shell where you can run `ps`:
|
||||||
```
|
```
|
||||||
$ runc
|
$ runc start
|
||||||
/ # ps
|
/ # ps
|
||||||
PID USER COMMAND
|
PID USER COMMAND
|
||||||
1 root sh
|
1 root sh
|
||||||
|
|
10
main.go
10
main.go
|
@ -24,7 +24,11 @@ After creating a spec for your root filesystem with runc, you can execute a
|
||||||
container in your shell by running:
|
container in your shell by running:
|
||||||
|
|
||||||
cd /mycontainer
|
cd /mycontainer
|
||||||
runc [ spec-file ]
|
runc start
|
||||||
|
|
||||||
|
or
|
||||||
|
cd /mycontainer
|
||||||
|
runc start [ spec-file ]
|
||||||
|
|
||||||
If not specified, the default value for the 'spec-file' is 'config.json'. `
|
If not specified, the default value for the 'spec-file' is 'config.json'. `
|
||||||
)
|
)
|
||||||
|
@ -56,6 +60,7 @@ func main() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
|
startCommand,
|
||||||
checkpointCommand,
|
checkpointCommand,
|
||||||
eventsCommand,
|
eventsCommand,
|
||||||
restoreCommand,
|
restoreCommand,
|
||||||
|
@ -69,7 +74,8 @@ func main() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Action = runAction
|
// Default to 'start' is no command is specified
|
||||||
|
app.Action = startCommand.Action
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
|
|
|
@ -13,6 +13,33 @@ import (
|
||||||
"github.com/opencontainers/specs"
|
"github.com/opencontainers/specs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var startCommand = cli.Command{
|
||||||
|
Name: "start",
|
||||||
|
Usage: "create and run a container",
|
||||||
|
Action: func(context *cli.Context) {
|
||||||
|
spec, err := loadSpec(context.Args().First())
|
||||||
|
|
||||||
|
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
||||||
|
if notifySocket != "" {
|
||||||
|
setupSdNotify(spec, notifySocket)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fatal(err)
|
||||||
|
}
|
||||||
|
if os.Geteuid() != 0 {
|
||||||
|
logrus.Fatal("runc should be run as root")
|
||||||
|
}
|
||||||
|
status, err := startContainer(context, spec)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatalf("Container start failed: %v", err)
|
||||||
|
}
|
||||||
|
// exit with the container's exit status so any external supervisor is
|
||||||
|
// notified of the exit with the correct exit status.
|
||||||
|
os.Exit(status)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if len(os.Args) > 1 && os.Args[1] == "init" {
|
if len(os.Args) > 1 && os.Args[1] == "init" {
|
||||||
runtime.GOMAXPROCS(1)
|
runtime.GOMAXPROCS(1)
|
||||||
|
@ -25,7 +52,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func execContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
|
func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
|
||||||
config, err := createLibcontainerConfig(context.GlobalString("id"), spec)
|
config, err := createLibcontainerConfig(context.GlobalString("id"), spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
|
@ -65,28 +92,6 @@ func execContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// default action is to execute a container
|
// default action is to execute a container
|
||||||
func runAction(context *cli.Context) {
|
|
||||||
spec, err := loadSpec(context.Args().First())
|
|
||||||
|
|
||||||
notifySocket := os.Getenv("NOTIFY_SOCKET")
|
|
||||||
if notifySocket != "" {
|
|
||||||
setupSdNotify(spec, notifySocket)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fatal(err)
|
|
||||||
}
|
|
||||||
if os.Geteuid() != 0 {
|
|
||||||
logrus.Fatal("runc should be run as root")
|
|
||||||
}
|
|
||||||
status, err := execContainer(context, spec)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatalf("Container start failed: %v", err)
|
|
||||||
}
|
|
||||||
// exit with the container's exit status so any external supervisor is
|
|
||||||
// notified of the exit with the correct exit status.
|
|
||||||
os.Exit(status)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If systemd is supporting sd_notify protocol, this function will add support
|
// If systemd is supporting sd_notify protocol, this function will add support
|
||||||
// for sd_notify protocol from within the container.
|
// for sd_notify protocol from within the container.
|
Loading…
Reference in New Issue