Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create: add support for --bundle and --pid-file #27

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 44 additions & 11 deletions cmd/runj/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"

"go.sbk.wtf/runj/jail"
"go.sbk.wtf/runj/oci"
Expand Down Expand Up @@ -45,8 +46,14 @@ import (
// integrations on top of runc expect this behavior, runj copies that at the
// expense of more complication in the codebase.
func createCommand() *cobra.Command {
var (
bundle string
consoleSocket string
pidFile string
)

create := &cobra.Command{
Use: "create <container-id> <path-to-bundle>",
Use: "create <container-id> [<path-to-bundle]",
Short: "Create a new container with given ID and bundle",
Long: `Create a new container with given ID and bundle. IDs must be unique.

Expand All @@ -57,9 +64,11 @@ filesystem.
The specification file includes an args parameter. The args parameter is used
to specify command(s) that get run when the container is started. To change the
command(s) that get executed on start, edit the args parameter of the spec.`,
Args: cobra.ExactArgs(2),
Args: cobra.RangeArgs(1, 2),
PreRunE: func(cmd *cobra.Command, args []string) error {
bundle := args[1]
if len(args) == 2 {
bundle = args[1]
}
bundleConfig := filepath.Join(bundle, oci.ConfigFileName)
fInfo, err := os.Stat(bundleConfig)
if err != nil {
Expand All @@ -71,16 +80,27 @@ command(s) that get executed on start, edit the args parameter of the spec.`,
return nil
},
}
consoleSocket := create.Flags().String(
flags := create.Flags()
flags.StringVar(
&bundle,
"bundle",
"",
`path to the root of the bundle directory, defaults to the current directory`)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a specific need for runj to support CWD here as the default or are you more interested in just adding support for --bundle? CWD does not currently work with your PR (the jail utility requires an absolute pathname and there's no current code to compute that).

I'm going to remove support for CWD for now while I'm working on this code and we can add it back in a separate PR if you need it.

flags.StringVar(
&consoleSocket,
"console-socket",
"",
`path to an AF_UNIX socket which will receive a
file descriptor referencing the master end of
the console's pseudoterminal`)
flags.StringVar(
&pidFile,
"pid-file",
"",
"the file to write the process id to")
create.RunE = func(cmd *cobra.Command, args []string) (err error) {
disableUsage(cmd)
id := args[0]
bundle := args[1]
var s *state.State
s, err = state.Create(id, bundle)
if err != nil {
Expand Down Expand Up @@ -121,15 +141,15 @@ the console's pseudoterminal`)
}
// console socket validation
if ociConfig.Process.Terminal {
if *consoleSocket == "" {
if consoleSocket == "" {
return errors.New("console-socket is required when Process.Terminal is true")
}
if socketStat, err := os.Stat(*consoleSocket); err != nil {
return fmt.Errorf("failed to stat console socket %q: %w", *consoleSocket, err)
if socketStat, err := os.Stat(consoleSocket); err != nil {
return fmt.Errorf("failed to stat console socket %q: %w", consoleSocket, err)
} else if socketStat.Mode()&os.ModeSocket != os.ModeSocket {
return fmt.Errorf("console-socket %q is not a socket", *consoleSocket)
return fmt.Errorf("console-socket %q is not a socket", consoleSocket)
}
} else if *consoleSocket != "" {
} else if consoleSocket != "" {
return errors.New("console-socket provided but Process.Terminal is false")
}
var confPath string
Expand All @@ -154,13 +174,26 @@ the console's pseudoterminal`)
// Setup and start the "runj-entrypoint" helper program in order to
// get the container STDIO hooked up properly.
var entrypoint *exec.Cmd
entrypoint, err = jail.SetupEntrypoint(id, true, ociConfig.Process.Args, ociConfig.Process.Env, *consoleSocket)
entrypoint, err = jail.SetupEntrypoint(id, true, ociConfig.Process.Args, ociConfig.Process.Env, consoleSocket)
if err != nil {
return err
}
// the runj-entrypoint pid will become the container process's pid
// through a series of exec(2) calls
s.PID = entrypoint.Process.Pid
if pidFile != "" {
f, err := os.OpenFile(pidFile, os.O_RDWR|os.O_CREATE, 0o666)
if err != nil {
return err
}
pidValue := strconv.Itoa(s.PID)
_, err = f.WriteString(pidValue)
f.Close()
if err != nil {
return err
}
}

return nil
}
return create
Expand Down