Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nixpig committed Sep 16, 2024
1 parent af56f17 commit db7e4ed
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 141 deletions.
8 changes: 8 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/nixpig/brownie/internal/commands"
"github.com/nixpig/brownie/pkg"
Expand All @@ -29,6 +30,8 @@ func createCmd(log *zerolog.Logger) *cobra.Command {
Args: cobra.ExactArgs(1),
Example: " brownie create busybox",
RunE: func(cmd *cobra.Command, args []string) error {
log.Info().Str(cmd.Name(), strings.Join(args, " "))

containerID := args[0]

bundle, err := cmd.Flags().GetString("bundle")
Expand Down Expand Up @@ -72,6 +75,7 @@ func startCmd(log *zerolog.Logger) *cobra.Command {
Args: cobra.ExactArgs(1),
Example: " brownie start busybox",
RunE: func(cmd *cobra.Command, args []string) error {
log.Info().Str(cmd.Name(), strings.Join(args, " "))
containerID := args[0]

opts := &commands.StartOpts{
Expand Down Expand Up @@ -118,6 +122,8 @@ func forkCmd(log *zerolog.Logger) *cobra.Command {
Example: "\n -- FOR INTERNAL USE ONLY --",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
log.Info().Str(cmd.Name(), strings.Join(args, " "))

stage := args[0]
containerID := args[1]
initSockAddr := args[2]
Expand Down Expand Up @@ -148,6 +154,8 @@ func stateCmd(log *zerolog.Logger) *cobra.Command {
Args: cobra.ExactArgs(1),
Example: " brownie state busybox",
RunE: func(cmd *cobra.Command, args []string) error {
log.Info().Str(cmd.Name(), strings.Join(args, " "))

containerID := args[0]

opts := &commands.StateOpts{
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
)

require (
github.com/creack/pty v1.1.23 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
Expand Down
85 changes: 48 additions & 37 deletions internal/commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package commands

import (
"encoding/json"
"errors"
"fmt"
"io"
"net"
"os"
"os/exec"
"path/filepath"
"time"

"github.com/nixpig/brownie/internal"
"github.com/nixpig/brownie/pkg"
Expand All @@ -23,29 +26,35 @@ type CreateOpts struct {
}

func Create(opts *CreateOpts, log *zerolog.Logger) error {
containerPath := filepath.Join(pkg.BrownieRootDir, "containers", opts.ID)
absBundlePath, err := filepath.Abs(opts.Bundle)
if err != nil {
return fmt.Errorf("absolute path to bundle: %w", err)
}

if stat, _ := os.Stat(containerPath); stat != nil {
return pkg.ErrContainerExists
bundleSpecPath := filepath.Join(absBundlePath, "config.json")

bundleSpecJSON, err := os.ReadFile(bundleSpecPath)
if err != nil {
return fmt.Errorf("read spec from bundle: %w", err)
}

if err := os.MkdirAll(containerPath, os.ModeDir); err != nil {
return fmt.Errorf("make brownie container directory: %w", err)
var spec specs.Spec
if err := json.Unmarshal(bundleSpecJSON, &spec); err != nil {
return fmt.Errorf("parse spec: %w", err)
}

absBundlePath, err := filepath.Abs(opts.Bundle)
if err != nil {
return fmt.Errorf("get absolute path to bundle: %w", err)
if spec.Linux == nil {
return errors.New("not a linux container")
}

configJSON, err := os.ReadFile(filepath.Join(absBundlePath, "config.json"))
if err != nil {
return fmt.Errorf("read spec: %w", err)
containerPath := filepath.Join(pkg.BrownieRootDir, "containers", opts.ID)

if stat, _ := os.Stat(containerPath); stat != nil {
return pkg.ErrContainerExists
}

var spec specs.Spec
if err := json.Unmarshal(configJSON, &spec); err != nil {
return fmt.Errorf("parse config: %w", err)
if err := os.MkdirAll(containerPath, os.ModeDir); err != nil {
return fmt.Errorf("make brownie container directory: %w", err)
}

state := &specs.State{
Expand All @@ -57,36 +66,45 @@ func Create(opts *CreateOpts, log *zerolog.Logger) error {
}

if err := internal.SaveState(state); err != nil {
return fmt.Errorf("save state (creating): %w", err)
return fmt.Errorf("save creating state: %w", err)
}

bundleRootfs := filepath.Join(absBundlePath, spec.Root.Path)
containerRootfs := filepath.Join(containerPath, spec.Root.Path)
containerConfigPath := filepath.Join(containerPath, "config.json")
containerSpecPath := filepath.Join(containerPath, "config.json")

if err := cp.Copy(bundleRootfs, containerRootfs); err != nil {
return fmt.Errorf("copy bundle rootfs to container rootfs: %w", err)
}

if err := cp.Copy(filepath.Join(absBundlePath, "config.json"), containerConfigPath); err != nil {
return fmt.Errorf("copy container spec: %w", err)
if err := cp.Copy(bundleSpecPath, containerSpecPath); err != nil {
return fmt.Errorf("copy bundle spec to container spec: %w", err)
}

if spec.Hooks != nil {
// TODO: If error, destroy container and created resources then call 'poststop' hooks.
if err := internal.ExecHooks(spec.Hooks.CreateRuntime); err != nil {
return fmt.Errorf("run createRuntime hooks: %w", err)
return fmt.Errorf("execute createruntime hooks: %w", err)
}

// TODO: If error, destroy container and created resources then call 'poststop' hooks.
if err := internal.ExecHooks(spec.Hooks.CreateContainer); err != nil {
return fmt.Errorf("run createContainer hooks: %w", err)
return fmt.Errorf("execute createcontainer hooks: %w", err)
}
}

initSockAddr := filepath.Join(containerPath, "init.sock")
containerSockAddr := filepath.Join(containerPath, "container.sock")

if err := os.RemoveAll(initSockAddr); err != nil {
return err
}
listener, err := net.Listen("unix", initSockAddr)
if err != nil {
return fmt.Errorf("failed to listen on init socket: %w", err)
}
defer listener.Close()

forkCmd := exec.Command(
"/proc/self/exe",
[]string{
Expand All @@ -97,23 +115,10 @@ func Create(opts *CreateOpts, log *zerolog.Logger) error {
containerSockAddr,
}...)

forkCmd.Stdout = os.Stdout
forkCmd.Stderr = os.Stderr
if err := forkCmd.Run(); err != nil {
return fmt.Errorf("fork: %w", err)
}

// wait for container to be ready
if err := os.RemoveAll(initSockAddr); err != nil {
return err
}

listener, err := net.Listen("unix", initSockAddr)
if err != nil {
return fmt.Errorf("failed to listen on init socket: %w", err)
}
defer listener.Close()

initConn, err := listener.Accept()
if err != nil {
return err
Expand All @@ -122,17 +127,23 @@ func Create(opts *CreateOpts, log *zerolog.Logger) error {

b := make([]byte, 128)

fmt.Println("listening on: ", initSockAddr)
for {
time.Sleep(time.Second)

n, err := initConn.Read(b)
if err != nil || n == 0 {
continue
}
if err == io.EOF {
fmt.Println("error: received EOF from socket")
os.Exit(1)
}

if len(b) > 0 {
log.Info().Str("msg", string(b)).Msg("received")
fmt.Println("error: ", err)
continue
}

if len(b) >= 5 && string(b[:5]) == "ready" {
fmt.Println("received 'ready' message")
log.Info().Msg("received 'ready' message")
break
}
Expand Down
Loading

0 comments on commit db7e4ed

Please sign in to comment.