Add ctr run functions for mocking client

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-11-29 16:52:04 -08:00
parent 3ebf1c456b
commit 3ef3f74878
3 changed files with 147 additions and 5 deletions

View file

@ -25,13 +25,21 @@ service Containers {
message Container {
string id = 1;
string image = 2;
repeated Mount mounts = 2;
repeated string tags = 3;
Process process = 4;
optional string container_spec = 5;
}
message Process {
uint64 pid = 1;
repeated string args = 1;
repeated string env = 2;
User user = 3;
string cwd = 4;
bool terminal = 5;
}
message ProcessSpec {
repeated string args = 1;
repeated string env = 2;
User user = 3;
@ -54,10 +62,10 @@ message User {
message CreateRequest {
string id = 1;
Process process = 2;
ProcessSpec process = 2;
repeated Mount mounts = 3;
optional string config_path = 4;
repeated string tags = 5;
repeated string tags = 4;
optional string config_path = 5;
}
message CreateResponse {

49
cli/ctr/main.go Normal file
View file

@ -0,0 +1,49 @@
package main
import (
"fmt"
"os"
"github.com/Sirupsen/logrus"
"github.com/docker/containerd"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "ctr"
app.Version = containerd.Version
app.Usage = `
__
_____/ /______
/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
containerd client
`
app.Flags = []cli.Flag{
cli.BoolFlag{
Name: "debug",
Usage: "enable debug output in logs",
},
cli.StringFlag{
Name: "socket, s",
Usage: "socket path for containerd's GRPC server",
Value: "/run/containerd/containerd.sock",
},
}
app.Commands = []cli.Command{
runCommand,
}
app.Before = func(context *cli.Context) error {
if context.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
return nil
}
if err := app.Run(os.Args); err != nil {
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
os.Exit(1)
}
}

85
cli/ctr/run.go Normal file
View file

@ -0,0 +1,85 @@
package main
import (
"fmt"
"os"
"github.com/BurntSushi/toml"
"github.com/urfave/cli"
)
type runConfig struct {
Image string `toml:"image"`
Process struct {
Args []string `toml:"args"`
Env []string `toml:"env"`
Cwd string `toml:"cwd"`
Uid int `toml:"uid"`
Gid int `toml:"gid"`
Tty bool `toml:"tty"`
} `toml:"process"`
Network struct {
Type string `toml:"type"`
IP string `toml:"ip"`
Gateway string `toml:"gateway"`
} `toml:"network"`
}
var runCommand = cli.Command{
Name: "run",
Usage: "run a container",
Action: func(context *cli.Context) error {
var config runConfig
if _, err := toml.DecodeFile(context.Args().First(), &config); err != nil {
return err
}
id := context.Args().Get(1)
if id == "" {
return fmt.Errorf("containerd must be provided")
}
client, err := getClient(context)
if err != nil {
return err
}
clone, err := client.Images.Clone(config.Image)
if err != nil {
return err
}
container, err := client.Containers.Create(CreateRequest{
Id: id,
Mounts: clone.Mounts,
Process: Process{
Args: config.Args,
Env: config.Env,
Cwd: config.Cwd,
Uid: config.Uid,
Gid: config.Gid,
Tty: config.Tty,
Stdin: os.Stdin.Name(),
Stdout: os.Stdout.Name(),
Stderr: os.Stderr.Name(),
},
Tags: []string{
"ctr",
},
})
defer client.Containers.Delete(container)
if err := client.Networks.Attach(config.Network, container); err != nil {
return err
}
if err := client.Containers.Start(container); err != nil {
return err
}
go forwarSignals(client.Containers.SignalProcess, container.Process)
events, err := client.Containers.Events(container.Id)
if err != nil {
return err
}
for event := range events {
if event.Type == "exit" {
os.Exit(event.Status)
}
}
return nil
},
}