From fae2680095868053514c7060946d4d4fdf1cacd5 Mon Sep 17 00:00:00 2001 From: nixpig <143995476+nixpig@users.noreply.github.com> Date: Sat, 28 Dec 2024 05:45:30 +0000 Subject: [PATCH] refactor: extract container exists logic --- container/container.go | 42 +++++++++++++---------------------- internal/commands/create.go | 44 ++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/container/container.go b/container/container.go index 5e4019b..16b279a 100644 --- a/container/container.go +++ b/container/container.go @@ -43,6 +43,7 @@ type ContainerState struct { } type ContainerOpts struct { + Bundle string PIDFile string ConsoleSocket string Stdin *os.File @@ -52,19 +53,9 @@ type ContainerOpts struct { func New( id string, - bundle string, + spec *specs.Spec, opts *ContainerOpts, ) (*Container, error) { - b, err := os.ReadFile(filepath.Join(bundle, configFilename)) - if err != nil { - return nil, fmt.Errorf("read new container config file: %w", err) - } - - var spec *specs.Spec - if err := json.Unmarshal(b, &spec); err != nil { - return nil, fmt.Errorf("parse new container config: %w", err) - } - if spec.Linux == nil { return nil, errors.New("only Linux containers are supported") } @@ -77,15 +68,10 @@ func New( return nil, fmt.Errorf("version must be valid semver: %s", spec.Version) } - absBundlePath, err := filepath.Abs(bundle) - if err != nil { - return nil, fmt.Errorf("absolute path from new container bundle: %w", err) - } - state := &ContainerState{ Version: OCIVersion, ID: id, - Bundle: absBundlePath, + Bundle: opts.Bundle, Annotations: spec.Annotations, Status: specs.StateCreating, } @@ -96,18 +82,13 @@ func New( Opts: opts, } - if err := os.MkdirAll( - filepath.Join(containerRootDir, cntr.ID()), - 0666, - ); err != nil { - return nil, fmt.Errorf("create new container directory: %w", err) - } + return &cntr, nil +} - if err := cntr.Save(); err != nil { - return nil, fmt.Errorf("save new container: %w", err) - } +func Exists(containerRootDir string, id string) bool { + _, err := os.Stat(filepath.Join(containerRootDir, id)) - return &cntr, nil + return err == nil } func Load(id string) (*Container, error) { @@ -170,6 +151,13 @@ func (c *Container) RefreshState() error { } func (c *Container) Save() error { + if err := os.MkdirAll( + filepath.Join(containerRootDir, c.ID()), + 0666, + ); err != nil { + return fmt.Errorf("create container directory: %w", err) + } + b, err := json.Marshal(c.State) if err != nil { return fmt.Errorf("serialise container state for saving: %w", err) diff --git a/internal/commands/create.go b/internal/commands/create.go index 2d3f2ff..bbe30fc 100644 --- a/internal/commands/create.go +++ b/internal/commands/create.go @@ -1,14 +1,19 @@ package commands import ( + "encoding/json" "fmt" "os" "path/filepath" "github.com/nixpig/brownie/container" + "github.com/opencontainers/runtime-spec/specs-go" ) -const containerRootDir = "/var/lib/brownie/containers" +const ( + containerRootDir = "/var/lib/brownie/containers" + configFilename = "config.json" +) type CreateOpts struct { ID string @@ -20,19 +25,30 @@ type CreateOpts struct { } func Create(opts *CreateOpts) error { - if _, err := os.Stat(filepath.Join( - containerRootDir, opts.ID, - )); err == nil { - return fmt.Errorf( - "container already exists (%s): %w", - opts.ID, err, - ) + if container.Exists(containerRootDir, opts.ID) { + return fmt.Errorf("container with id '%s' already exists", opts.ID) + } + + bundle, err := filepath.Abs(opts.Bundle) + if err != nil { + return fmt.Errorf("absolute path from new container bundle: %w", err) + } + + b, err := os.ReadFile(filepath.Join(opts.Bundle, configFilename)) + if err != nil { + return fmt.Errorf("read new container config file: %w", err) + } + + var spec *specs.Spec + if err := json.Unmarshal(b, &spec); err != nil { + return fmt.Errorf("parse new container config: %w", err) } cntr, err := container.New( opts.ID, - opts.Bundle, + spec, &container.ContainerOpts{ + Bundle: bundle, PIDFile: opts.PIDFile, ConsoleSocket: opts.ConsoleSocket, Stdin: os.Stdin, @@ -44,5 +60,13 @@ func Create(opts *CreateOpts) error { return fmt.Errorf("create container: %w", err) } - return cntr.Init(opts.ReexecCmd, opts.ReexecArgs) + if err := cntr.Init(opts.ReexecCmd, opts.ReexecArgs); err != nil { + return fmt.Errorf("initialise container: %w", err) + } + + if err := cntr.Save(); err != nil { + return fmt.Errorf("save container: %w", err) + } + + return nil }