2015-06-22 10:31:12 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2016-11-01 19:13:49 +08:00
|
|
|
"path/filepath"
|
2018-01-13 15:39:28 +08:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2015-06-22 10:31:12 +08:00
|
|
|
|
2016-05-26 02:24:26 +08:00
|
|
|
"github.com/opencontainers/runtime-spec/specs-go"
|
2017-07-19 22:28:59 +08:00
|
|
|
|
|
|
|
"github.com/sirupsen/logrus"
|
2016-06-07 02:45:46 +08:00
|
|
|
"github.com/urfave/cli"
|
2015-06-22 10:31:12 +08:00
|
|
|
)
|
|
|
|
|
2016-10-28 23:43:10 +08:00
|
|
|
const (
|
|
|
|
exactArgs = iota
|
|
|
|
minArgs
|
2017-02-03 00:32:52 +08:00
|
|
|
maxArgs
|
2016-10-28 23:43:10 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func checkArgs(context *cli.Context, expected, checkType int) error {
|
|
|
|
var err error
|
|
|
|
cmdName := context.Command.Name
|
|
|
|
switch checkType {
|
|
|
|
case exactArgs:
|
|
|
|
if context.NArg() != expected {
|
|
|
|
err = fmt.Errorf("%s: %q requires exactly %d argument(s)", os.Args[0], cmdName, expected)
|
|
|
|
}
|
|
|
|
case minArgs:
|
|
|
|
if context.NArg() < expected {
|
|
|
|
err = fmt.Errorf("%s: %q requires a minimum of %d argument(s)", os.Args[0], cmdName, expected)
|
|
|
|
}
|
2017-02-03 00:32:52 +08:00
|
|
|
case maxArgs:
|
|
|
|
if context.NArg() > expected {
|
|
|
|
err = fmt.Errorf("%s: %q requires a maximum of %d argument(s)", os.Args[0], cmdName, expected)
|
|
|
|
}
|
2016-10-28 23:43:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Incorrect Usage.\n\n")
|
|
|
|
cli.ShowCommandHelp(context, cmdName)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-06-22 10:31:12 +08:00
|
|
|
// fatal prints the error's details if it is a libcontainer specific error type
|
2015-07-11 07:19:18 +08:00
|
|
|
// then exits the program with an exit status of 1.
|
2015-06-22 10:31:12 +08:00
|
|
|
func fatal(err error) {
|
2016-03-09 10:05:50 +08:00
|
|
|
// make sure the error is written to the logger
|
|
|
|
logrus.Error(err)
|
2015-06-22 10:31:12 +08:00
|
|
|
fmt.Fprintln(os.Stderr, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2016-05-26 02:24:26 +08:00
|
|
|
|
2016-10-12 07:22:48 +08:00
|
|
|
// setupSpec performs initial setup based on the cli.Context for the container
|
2016-05-26 02:24:26 +08:00
|
|
|
func setupSpec(context *cli.Context) (*specs.Spec, error) {
|
|
|
|
bundle := context.String("bundle")
|
|
|
|
if bundle != "" {
|
|
|
|
if err := os.Chdir(bundle); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spec, err := loadSpec(specConfig)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return spec, nil
|
|
|
|
}
|
2016-11-01 19:13:49 +08:00
|
|
|
|
|
|
|
func revisePidFile(context *cli.Context) error {
|
|
|
|
pidFile := context.String("pid-file")
|
|
|
|
if pidFile == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert pid-file to an absolute path so we can write to the right
|
|
|
|
// file after chdir to bundle
|
|
|
|
pidFile, err := filepath.Abs(pidFile)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-01-07 07:57:31 +08:00
|
|
|
return context.Set("pid-file", pidFile)
|
2016-11-01 19:13:49 +08:00
|
|
|
}
|
2018-01-13 15:39:28 +08:00
|
|
|
|
|
|
|
// parseBoolOrAuto returns (nil, nil) if s is empty or "auto"
|
|
|
|
func parseBoolOrAuto(s string) (*bool, error) {
|
|
|
|
if s == "" || strings.ToLower(s) == "auto" {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
b, err := strconv.ParseBool(s)
|
|
|
|
return &b, err
|
|
|
|
}
|