Do a large chunk of the move to go
This commit moves a huge chunk of the code to go. The TODO.md document indicates what is left to be done.
This commit is contained in:
parent
db2ad9b4bd
commit
7b38fdd801
93 changed files with 4689 additions and 645 deletions
108
internal/stack/installable.go
Normal file
108
internal/stack/installable.go
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package stack
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/distillery"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
)
|
||||
|
||||
// Installable represents a Stack that can be automatically installed from a set of resources
|
||||
// See the Install() method.
|
||||
type Installable struct {
|
||||
Stack
|
||||
|
||||
ContextResource string // Path to the resource containing 'docker compose' context
|
||||
|
||||
EnvFileResource string // Path to the resource containing dynamically generated env file
|
||||
EnvFileContext map[string]string // Context of variables to replace in the env file
|
||||
|
||||
CopyContextFiles []string // Files to copy from the installation context
|
||||
|
||||
TouchFiles []string // Files to 'touch', i.e. ensure that exist
|
||||
|
||||
MakeDirsPerm fs.FileMode // permission for diretories, defaults to fs.ModeDir
|
||||
MakeDirs []string // directories to ensure that exist
|
||||
}
|
||||
|
||||
// InstallationContext is a context to install data in
|
||||
type InstallationContext map[string]string
|
||||
|
||||
// Install installs or updates this stack into the directory specified by stack.Stack().
|
||||
//
|
||||
// Installation is non-interactive, but will provide debugging output onto io.
|
||||
// InstallationContext
|
||||
func (is Installable) Install(io stream.IOStream, context InstallationContext) error {
|
||||
// setup the base files
|
||||
if err := distillery.InstallResource(
|
||||
is.Dir,
|
||||
is.ContextResource,
|
||||
func(dst, src string) {
|
||||
io.Printf("[install] %s\n", dst)
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// configure .env
|
||||
envDest := filepath.Join(is.Dir, ".env")
|
||||
if is.EnvFileResource != "" && is.EnvFileContext != nil {
|
||||
io.Printf("[config] %s\n", envDest)
|
||||
if err := distillery.InstallTemplate(
|
||||
envDest,
|
||||
is.EnvFileResource,
|
||||
is.EnvFileContext,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// make sure that certain files exist
|
||||
for _, name := range is.MakeDirs {
|
||||
// find the destination!
|
||||
dst := filepath.Join(is.Dir, name)
|
||||
|
||||
io.Printf("[make] %s\n", dst)
|
||||
if is.MakeDirsPerm == fs.FileMode(0) {
|
||||
is.MakeDirsPerm = fs.ModeDir
|
||||
}
|
||||
if err := os.MkdirAll(dst, is.MakeDirsPerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// copy files from the context!
|
||||
for _, name := range is.CopyContextFiles {
|
||||
// find the source!
|
||||
src, ok := context[name]
|
||||
if !ok {
|
||||
return errors.Errorf("Missing file from context: %s", src)
|
||||
}
|
||||
|
||||
// find the destination!
|
||||
dst := filepath.Join(is.Dir, name)
|
||||
|
||||
// copy over file from context
|
||||
io.Printf("[copy] %s (from %s)\n", dst, src)
|
||||
if err := fsx.CopyFile(dst, src); err != nil {
|
||||
return errors.Wrapf(err, "Unable to copy file %s", src)
|
||||
}
|
||||
}
|
||||
|
||||
// make sure that certain files exist
|
||||
for _, name := range is.TouchFiles {
|
||||
// find the destination!
|
||||
dst := filepath.Join(is.Dir, name)
|
||||
|
||||
io.Printf("[touch] %s\n", dst)
|
||||
if err := fsx.Touch(dst); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
110
internal/stack/stack.go
Normal file
110
internal/stack/stack.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Package stack implements a docker compose stack
|
||||
package stack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/execx"
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
)
|
||||
|
||||
// Stack represents a 'docker compose' stack living in a specific directory
|
||||
//
|
||||
// NOTE(twiesing): In the current implementation this requires a 'docker' executable on the system.
|
||||
// This executable must be capable of the 'docker compose' command.
|
||||
// In the future the idea is to replace this with a native docker compose client.
|
||||
type Stack struct {
|
||||
Name string // Name of this stack, TODO: Do we need this?
|
||||
Dir string // Directory of this stack
|
||||
}
|
||||
|
||||
var errStackUpdatePull = errors.New("Stack.Update: Pull returned non-zero exit code")
|
||||
var errStackUpdateBuild = errors.New("Stack.Update: Build returned non-zero exit code")
|
||||
|
||||
// Update pulls, builds, and then optionally starts this stack.
|
||||
// This does not have a direct 'docker compose' shell equivalent.
|
||||
//
|
||||
// See also Up.
|
||||
func (ds Stack) Update(io stream.IOStream, start bool) error {
|
||||
if ds.compose(io, "pull") != 0 {
|
||||
return errStackUpdatePull
|
||||
}
|
||||
if ds.compose(io, "build", "--pull") != 0 {
|
||||
return errStackUpdateBuild
|
||||
}
|
||||
if start {
|
||||
return ds.Up(io)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var errStackUp = errors.New("Stack.Up: Up returned non-zero exit code")
|
||||
|
||||
// Up creates and starts the containers in this Stack.
|
||||
// It is equivalent to 'docker compose up -d' on the shell.
|
||||
func (ds Stack) Up(io stream.IOStream) error {
|
||||
if ds.compose(io, "up", "-d") != 0 {
|
||||
return errStackUp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exec executes an executable in the provided running service.
|
||||
// It is equivalent to 'docker compose exec $service $executable $args...'.
|
||||
//
|
||||
// It returns the exit code of the process.
|
||||
func (ds Stack) Exec(io stream.IOStream, service, executable string, args ...string) int {
|
||||
compose := []string{"exec"}
|
||||
if io.StdinIsATerminal() {
|
||||
compose = append(compose, "-ti")
|
||||
}
|
||||
compose = append(compose, executable)
|
||||
compose = append(compose, args...)
|
||||
return ds.compose(io, compose...)
|
||||
}
|
||||
|
||||
// Run executes the provided service with the given executable.
|
||||
// It is equivalent to 'docker compose run [--rm] $service $executable $args...'.
|
||||
//
|
||||
// It returns the exit code of the process.
|
||||
func (ds Stack) Run(io stream.IOStream, autoRemove bool, service, command string, args ...string) int {
|
||||
compose := []string{"run"}
|
||||
if autoRemove {
|
||||
compose = append(compose, "--rm")
|
||||
}
|
||||
if !io.StdinIsATerminal() {
|
||||
compose = append(compose, "-T")
|
||||
}
|
||||
compose = append(compose, command)
|
||||
compose = append(compose, args...)
|
||||
return ds.compose(io, compose...)
|
||||
}
|
||||
|
||||
var errStackRestart = errors.New("Stack.Restart: Restart returned non-zero exit code")
|
||||
|
||||
// Restart restarts all containers in this Stack.
|
||||
// It is equivalent to 'docker compose restart' on the shell.
|
||||
func (ds Stack) Restart(io stream.IOStream) error {
|
||||
if ds.compose(io, "restart") != 0 {
|
||||
return errStackRestart
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var errStackDown = errors.New("Stack.Down: Down returned non-zero exit code")
|
||||
|
||||
// Down stops and removes all containers in this Stack.
|
||||
// It is equivalent to 'docker compose down -v' on the shell.
|
||||
func (ds Stack) Down(io stream.IOStream) error {
|
||||
if ds.compose(io, "down", "-v") != 0 {
|
||||
return errStackDown
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compose executes a 'docker compose' command on this stack.
|
||||
// TODO: This should be removed and replaced by an internal call directly to libcompose.
|
||||
func (ds Stack) compose(io stream.IOStream, args ...string) int {
|
||||
// TODO: can we migrate to a built-in version of this?
|
||||
return execx.Compose(io, ds.Dir, args...)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue