Skip to content

Commit

Permalink
restructure config and options objects throughout
Browse files Browse the repository at this point in the history
  • Loading branch information
oclaussen committed Apr 16, 2019
1 parent b4b474c commit 8095a10
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 70 deletions.
50 changes: 24 additions & 26 deletions pkg/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,17 @@ import (
"os"

"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/term"
"github.com/oclaussen/dodo/pkg/types"
"golang.org/x/net/context"
)

// Options represents the configuration for running a docker container to
// be used as backdrop.
type Options struct {
Client *client.Client
Image string
Name string
Remove bool
Entrypoint []string
Script string
ScriptPath string
Command []string
Environment []string
Volumes []string
VolumesFrom []string
PortBindings types.Ports
User string
WorkingDir string
type Container struct {
config *types.Backdrop
client *client.Client
context context.Context
scriptPath string
}

type ScriptError struct {
Expand All @@ -38,25 +27,34 @@ func (e *ScriptError) Error() string {
return e.Message
}

// Run runs a docker container as backdrop.
func Run(ctx context.Context, options Options) error {
if options.Client == nil {
return errors.New("client may not be nil")
func NewContainer(client *client.Client, config *types.Backdrop) (*Container, error) {
if client == nil {
return nil, errors.New("client may not be nil")
}
return &Container{
config: config,
client: client,
context: context.Background(),
scriptPath: "/tmp/dodo-dockerfile-" + stringid.GenerateRandomID()[:20],
}, nil
}

// Run runs a docker container as backdrop.
func (c *Container) Run(image string) error {
_, inTerm := term.GetFdInfo(os.Stdin)
_, outTerm := term.GetFdInfo(os.Stdout)
tty := inTerm && outTerm

containerID, err := createContainer(ctx, options, tty)
containerID, err := c.create(image, tty)
if err != nil {
return err
}

err = uploadEntrypoint(ctx, containerID, options)
if err != nil {
return err
if len(c.config.Script) > 0 {
if err = c.uploadEntrypoint(containerID); err != nil {
return err
}
}

return runContainer(ctx, containerID, options, tty)
return c.run(containerID, tty)
}
48 changes: 32 additions & 16 deletions pkg/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,51 @@ package container
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"golang.org/x/net/context"
)

func createContainer(ctx context.Context, options Options, tty bool) (string, error) {
response, err := options.Client.ContainerCreate(
ctx,
func (c *Container) create(image string, tty bool) (string, error) {
entrypoint := []string{"/bin/sh"}
command := c.config.Command

if c.config.Interpreter != nil {
entrypoint = c.config.Interpreter
}
if c.config.Interactive {
command = nil
} else if len(c.config.Script) > 0 {
entrypoint = append(entrypoint, c.scriptPath)
}

response, err := c.client.ContainerCreate(
c.context,
&container.Config{
User: options.User,
User: c.config.User,
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Tty: tty,
OpenStdin: true,
StdinOnce: true,
Env: options.Environment,
Cmd: options.Command,
Image: options.Image,
WorkingDir: options.WorkingDir,
Entrypoint: options.Entrypoint,
ExposedPorts: options.PortBindings.PortSet(),
Env: c.config.Environment.Strings(),
Cmd: command,
Image: image,
WorkingDir: c.config.WorkingDir,
Entrypoint: entrypoint,
ExposedPorts: c.config.Ports.PortSet(),
},
&container.HostConfig{
AutoRemove: options.Remove,
Binds: options.Volumes,
VolumesFrom: options.VolumesFrom,
PortBindings: options.PortBindings.PortMap(),
AutoRemove: func() bool {
if c.config.Remove == nil {
return true
}
return *c.config.Remove
}(),
Binds: c.config.Volumes.Strings(),
VolumesFrom: c.config.VolumesFrom,
PortBindings: c.config.Ports.PortMap(),
},
&network.NetworkingConfig{},
options.Name,
c.config.ContainerName,
)
if err != nil {
return "", err
Expand Down
13 changes: 5 additions & 8 deletions pkg/container/entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import (
"io"

"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)

func uploadEntrypoint(
ctx context.Context, containerID string, options Options,
) error {
func (container *Container) uploadEntrypoint(containerID string) error {
reader, writer := io.Pipe()
defer reader.Close()
defer writer.Close()

go options.Client.CopyToContainer(
ctx,
go container.client.CopyToContainer(
container.context,
containerID,
"/",
reader,
Expand All @@ -26,10 +23,10 @@ func uploadEntrypoint(
tarWriter := tar.NewWriter(writer)
defer tarWriter.Close()

script := options.Script + "\n"
script := container.config.Script + "\n"

err := tarWriter.WriteHeader(&tar.Header{
Name: options.ScriptPath,
Name: container.scriptPath,
Mode: 0644,
Size: int64(len(script)),
})
Expand Down
32 changes: 14 additions & 18 deletions pkg/container/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import (
"golang.org/x/net/context"
)

func runContainer(
ctx context.Context, containerID string, options Options, tty bool,
) error {
attach, err := options.Client.ContainerAttach(
ctx,
func (c *Container) run(containerID string, tty bool) error {
attach, err := c.client.ContainerAttach(
c.context,
containerID,
types.ContainerAttachOptions{
Stream: true,
Expand All @@ -33,20 +31,20 @@ func runContainer(
defer attach.Close()

streamErrorChannel := make(chan error, 1)
go streamContainer(ctx, streamErrorChannel, attach, tty)
go streamContainer(c.context, streamErrorChannel, attach, tty)

condition := container.WaitConditionNextExit
if options.Remove {
if c.config.Remove == nil || *c.config.Remove == true {
condition = container.WaitConditionRemoved
}
waitChannel, waitErrorChannel := options.Client.ContainerWait(
ctx,
waitChannel, waitErrorChannel := c.client.ContainerWait(
c.context,
containerID,
condition,
)

err = options.Client.ContainerStart(
ctx,
err = c.client.ContainerStart(
c.context,
containerID,
types.ContainerStartOptions{},
)
Expand All @@ -55,12 +53,12 @@ func runContainer(
}

if tty {
resizeContainer(ctx, containerID, options)
c.resize(containerID)
resizeChannel := make(chan os.Signal, 1)
signal.Notify(resizeChannel, syscall.SIGWINCH)
go func() {
for range resizeChannel {
resizeContainer(ctx, containerID, options)
c.resize(containerID)
}
}()
}
Expand All @@ -84,9 +82,7 @@ func runContainer(
}
}

func resizeContainer(
ctx context.Context, containerID string, options Options,
) {
func (c *Container) resize(containerID string) {
outFd, _ := term.GetFdInfo(os.Stdout)

ws, err := term.GetWinsize(outFd)
Expand All @@ -100,8 +96,8 @@ func resizeContainer(
return
}

options.Client.ContainerResize(
ctx,
c.client.ContainerResize(
c.context,
containerID,
types.ResizeOptions{
Height: height,
Expand Down
4 changes: 2 additions & 2 deletions pkg/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (image *Image) Build() (string, error) {
)
})

if image.config.PrintOutput && stdErrIsTerminal {
if image.config.ForceRebuild && stdErrIsTerminal {
eg.Go(func() error {
cons, err := console.ConsoleFromFile(os.Stderr)
if err != nil {
Expand Down Expand Up @@ -116,7 +116,7 @@ func (image *Image) runBuild(contextData *contextData, displayCh chan *client.So
defer response.Body.Close()

_, stdErrIsTerminal := term.GetFdInfo(os.Stderr)
return handleBuildResult(response.Body, displayCh, image.config.PrintOutput && stdErrIsTerminal)
return handleBuildResult(response.Body, displayCh, image.config.ForceRebuild && stdErrIsTerminal)
}

func handleBuildResult(response io.Reader, displayCh chan *client.SolveStatus, printOutput bool) (string, error) {
Expand Down

0 comments on commit 8095a10

Please sign in to comment.