Skip to content

Instantly share code, notes, and snippets.

@samuelkarp
Created June 8, 2017 21:47
Show Gist options
  • Save samuelkarp/05007af20e242cf61a1df63eb48acc7b to your computer and use it in GitHub Desktop.
Save samuelkarp/05007af20e242cf61a1df63eb48acc7b to your computer and use it in GitHub Desktop.
containerd experiment
package main
import (
"context"
"fmt"
"os"
"syscall"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces"
"github.com/pkg/errors"
)
const (
myNamespace = "samuelkarp"
myImage = "docker.io/library/busybox:latest"
myContainerID = "test-container"
)
var client *containerd.Client
func main() {
c, err := containerd.New("/run/containerd/containerd.sock")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
client = c
funcs := []struct {
Name string
F func() error
}{
{"pull", pullImage},
{"create", createContainer},
{"start", startContainer},
{"stop", stopContainer},
{"delete", deleteContainer},
}
for _, f := range funcs {
fmt.Println(f.Name)
if err := f.F(); err != nil {
fmt.Println(err)
os.Exit(1)
}
time.Sleep(time.Second)
}
}
func pullImage() error {
ctx := namespaces.WithNamespace(context.TODO(), myNamespace)
pullResponse, err := client.Pull(ctx, myImage, containerd.WithPullUnpack)
if err != nil {
return errors.Wrap(err, "pull: failed to pull")
}
fmt.Println(pullResponse)
return nil
}
func createContainer() error {
ctx := namespaces.WithNamespace(context.TODO(), myNamespace)
image, err := client.GetImage(ctx, myImage)
if err != nil {
return errors.Wrap(err, "create: failed to find image")
}
opts := []containerd.SpecOpts{
containerd.WithImageConfig(ctx, image),
containerd.WithProcessArgs("/bin/sh", "-c", "echo HELLO; sleep 5; echo DONE"),
}
spec, err := containerd.GenerateSpec(opts...)
if err != nil {
return errors.Wrap(err, "create: failed to generate spec")
}
_, err = client.NewContainer(ctx, myContainerID, containerd.WithSpec(spec), containerd.WithNewRootFS(myContainerID, image), containerd.WithImage(image))
if err != nil {
return errors.Wrap(err, "create: failed to create")
}
return nil
}
func startContainer() error {
ctx := namespaces.WithNamespace(context.TODO(), myNamespace)
container, err := client.LoadContainer(ctx, myContainerID)
if err != nil {
return errors.Wrap(err, "start: failed to load container")
}
task, err := container.NewTask(ctx, containerd.Stdio)
if err != nil {
return errors.Wrap(err, "start: failed to create task")
}
err = task.Start(ctx)
if err != nil {
return errors.Wrap(err, "start: failed to start task")
}
return nil
}
func stopContainer() error {
ctx := namespaces.WithNamespace(context.TODO(), myNamespace)
container, err := client.LoadContainer(ctx, myContainerID)
if err != nil {
return errors.Wrap(err, "stop: failed to load container")
}
task, err := container.Task(ctx, nil)
if err != nil {
return errors.Wrap(err, "stop: failed to load task")
}
done := make(chan struct{})
go func() {
defer close(done)
status, err := task.Wait(ctx)
if err != nil {
fmt.Printf("stop: failed to wait: %v", err)
return
}
fmt.Printf("stop: task exited with status %d", status)
}()
err = task.Kill(ctx, syscall.SIGKILL)
if err != nil {
return errors.Wrap(err, "stop: failed to kill")
}
<-done
status, err := task.Delete(ctx)
if err != nil {
return errors.Wrap(err, "stop: failed to delete task")
}
fmt.Printf("stop: task deleted with status %d", status)
return nil
}
func deleteContainer() error {
ctx := namespaces.WithNamespace(context.TODO(), myNamespace)
container, err := client.LoadContainer(ctx, myContainerID)
if err != nil {
return errors.Wrap(err, "delete: failed to load container")
}
err = container.Delete(ctx)
if err != nil {
return errors.Wrap(err, "delete: failed to delete container")
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment