1
0
mirror of https://github.com/drone/drone-cli.git synced 2024-11-23 01:11:57 +01:00

refactored ambassador

This commit is contained in:
Brad Rydzewski 2015-03-15 12:40:11 -07:00
parent 8027800a30
commit 5c0bfedd01
5 changed files with 200 additions and 193 deletions

@ -1,189 +0,0 @@
package ambassador
import (
"errors"
"io"
log "github.com/Sirupsen/logrus"
"github.com/samalba/dockerclient"
)
var errNop = errors.New("Operation not supported")
// Ambassador is a wrapper around the Docker client that
// provides a shared volume and network for all containers.
type Ambassador struct {
name string
client dockerclient.Client
}
// Create creates a new ambassador container.
func Create(client dockerclient.Client) (_ *Ambassador, err error) {
amb := &Ambassador{
client: client,
}
conf := &dockerclient.ContainerConfig{}
host := &dockerclient.HostConfig{}
conf.Entrypoint = []string{"/bin/sleep"}
conf.Cmd = []string{"1d"}
conf.Image = "busybox"
conf.Volumes = map[string]struct{}{}
conf.Volumes["/drone"] = struct{}{}
// creates the ambassador container
amb.name, err = client.CreateContainer(conf, "")
if err != nil {
// on failure attempts to pull the image
client.PullImage(conf.Image, nil)
// then attempts to re-create the container
amb.name, err = client.CreateContainer(conf, "")
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
return nil, err
}
}
err = client.StartContainer(amb.name, host)
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
}
return amb, err
}
// Destroy stops and deletes the ambassador container.
func (c *Ambassador) Destroy() error {
c.client.StopContainer(c.name, 5)
c.client.KillContainer(c.name, "SIGKILL")
return c.client.RemoveContainer(c.name, true, true)
}
// CreateContainer creates a container.
func (c *Ambassador) CreateContainer(conf *dockerclient.ContainerConfig, name string) (string, error) {
log.WithField("image", conf.Image).Debugln("create container")
id, err := c.client.CreateContainer(conf, name)
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
}
return id, err
}
// InspectContainer returns container details.
func (c *Ambassador) InspectContainer(id string) (*dockerclient.ContainerInfo, error) {
return c.client.InspectContainer(id)
}
// ContainerLogs returns an io.ReadCloser for reading the
// container logs.
func (c *Ambassador) ContainerLogs(id string, options *dockerclient.LogOptions) (io.ReadCloser, error) {
return c.client.ContainerLogs(id, options)
}
// StartContainer starts a container. The ambassador volume
// is automatically linked. The ambassador network is linked
// iff a network mode is not already specified.
func (c *Ambassador) StartContainer(id string, conf *dockerclient.HostConfig) error {
log.WithField("container", id).Debugln("start container")
conf.VolumesFrom = append(conf.VolumesFrom, "container:"+c.name)
if len(conf.NetworkMode) == 0 {
conf.NetworkMode = "container:" + c.name
}
err := c.client.StartContainer(id, conf)
if err != nil {
log.WithField("container", id).Errorln(err)
}
return err
}
// StopContainer stops a container.
func (c *Ambassador) StopContainer(id string, timeout int) error {
log.WithField("container", id).Debugln("stop container")
err := c.client.StopContainer(id, timeout)
if err != nil {
log.WithField("container", id).Errorln(err)
}
return err
}
// PullImage pulls an image.
func (c *Ambassador) PullImage(name string, auth *dockerclient.AuthConfig) error {
log.WithField("image", name).Debugln("pull image")
err := c.client.PullImage(name, auth)
if err != nil {
log.WithField("image", name).Errorln(err)
}
return err
}
// RemoveContainer removes a container.
func (c *Ambassador) RemoveContainer(id string, force, volumes bool) error {
return c.client.RemoveContainer(id, force, volumes)
}
// KillContainer kills a running container.
func (c *Ambassador) KillContainer(id, signal string) error {
return c.client.KillContainer(id, signal)
}
//
// methods below are not implemented
//
// Info returns a no-op error
func (c *Ambassador) Info() (*dockerclient.Info, error) {
return nil, errNop
}
// ListContainers returns a no-op error
func (c *Ambassador) ListContainers(all bool, size bool, filters string) ([]dockerclient.Container, error) {
return nil, errNop
}
// RestartContainer returns a no-op error
func (c *Ambassador) RestartContainer(id string, timeout int) error {
return errNop
}
// StartMonitorEvents returns a no-op error
func (c *Ambassador) StartMonitorEvents(cb dockerclient.Callback, ec chan error, args ...interface{}) {
}
// StopAllMonitorEvents returns a no-op error
func (c *Ambassador) StopAllMonitorEvents() {
}
// Version returns a no-op error
func (c *Ambassador) Version() (*dockerclient.Version, error) {
return nil, errNop
}
// ListImages returns a no-op error
func (c *Ambassador) ListImages() ([]*dockerclient.Image, error) {
return nil, errNop
}
// RemoveImage returns a no-op error
func (c *Ambassador) RemoveImage(name string) error {
return errNop
}
// PauseContainer returns a no-op error
func (c *Ambassador) PauseContainer(name string) error {
return errNop
}
// UnpauseContainer returns a no-op error
func (c *Ambassador) UnpauseContainer(name string) error {
return errNop
}
// Exec returns a no-op error
func (c *Ambassador) Exec(config *dockerclient.ExecConfig) (string, error) {
var empty string
return empty, errNop
}

@ -0,0 +1,106 @@
package docker
import (
"errors"
log "github.com/Sirupsen/logrus"
"github.com/samalba/dockerclient"
)
var errNop = errors.New("Operation not supported")
// Ambassador is a wrapper around the Docker client that
// provides a shared volume and network for all containers.
type Ambassador struct {
dockerclient.Client
name string
}
// NewAmbassador creates an ambassador container and wraps the Docker
// client to inject the ambassador volume and network into containers.
func NewAmbassador(client dockerclient.Client) (_ *Ambassador, err error) {
amb := &Ambassador{client, ""}
conf := &dockerclient.ContainerConfig{}
host := &dockerclient.HostConfig{}
conf.Entrypoint = []string{"/bin/sleep"}
conf.Cmd = []string{"1d"}
conf.Image = "busybox"
conf.Volumes = map[string]struct{}{}
conf.Volumes["/drone"] = struct{}{}
// creates the ambassador container
amb.name, err = client.CreateContainer(conf, "")
if err != nil {
// on failure attempts to pull the image
client.PullImage(conf.Image, nil)
// then attempts to re-create the container
amb.name, err = client.CreateContainer(conf, "")
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
return nil, err
}
}
err = client.StartContainer(amb.name, host)
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
}
return amb, err
}
// Destroy stops and deletes the ambassador container.
func (c *Ambassador) Destroy() error {
c.Client.StopContainer(c.name, 5)
c.Client.KillContainer(c.name, "SIGKILL")
return c.Client.RemoveContainer(c.name, true, true)
}
// CreateContainer creates a container.
func (c *Ambassador) CreateContainer(conf *dockerclient.ContainerConfig, name string) (string, error) {
log.WithField("image", conf.Image).Debugln("create container")
id, err := c.Client.CreateContainer(conf, name)
if err != nil {
log.WithField("image", conf.Image).Errorln(err)
}
return id, err
}
// StartContainer starts a container. The ambassador volume
// is automatically linked. The ambassador network is linked
// iff a network mode is not already specified.
func (c *Ambassador) StartContainer(id string, conf *dockerclient.HostConfig) error {
log.WithField("container", id).Debugln("start container")
conf.VolumesFrom = append(conf.VolumesFrom, "container:"+c.name)
if len(conf.NetworkMode) == 0 {
conf.NetworkMode = "container:" + c.name
}
err := c.Client.StartContainer(id, conf)
if err != nil {
log.WithField("container", id).Errorln(err)
}
return err
}
// StopContainer stops a container.
func (c *Ambassador) StopContainer(id string, timeout int) error {
log.WithField("container", id).Debugln("stop container")
err := c.Client.StopContainer(id, timeout)
if err != nil {
log.WithField("container", id).Errorln(err)
}
return err
}
// PullImage pulls an image.
func (c *Ambassador) PullImage(name string, auth *dockerclient.AuthConfig) error {
log.WithField("image", name).Debugln("pull image")
err := c.Client.PullImage(name, auth)
if err != nil {
log.WithField("image", name).Errorln(err)
}
return err
}

90
builder/worker/pool.go Normal file

@ -0,0 +1,90 @@
package worker
// import (
// "sync"
//
// "github.com/drone/drone/server/worker"
// "github.com/samalba/dockerclient"
// )
//
// // TODO (bradrydzewski) ability to cancel work.
// // TODO (bradrydzewski) ability to remove a worker.
//
// type Pool struct {
// sync.Mutex
// workers map[dockerclient.Client]bool
// workerc chan dockerclient.Client
// }
//
// func New() *Pool {
// return &Pool{
// workers: make(map[Worker]bool),
// workerc: make(chan Worker, 999),
// }
// }
//
// // Allocate allocates a worker to the pool to
// // be available to accept work.
// func (p *Pool) Allocate(w worker.Worker) bool {
// if p.IsAllocated(w) {
// return false
// }
//
// p.Lock()
// p.workers[w] = true
// p.Unlock()
//
// p.workerc <- w
// return true
// }
//
// // IsAllocated is a helper function that returns
// // true if the worker is currently allocated to
// // the Pool.
// func (p *Pool) IsAllocated(w worker.Worker) bool {
// p.Lock()
// defer p.Unlock()
// _, ok := p.workers[w]
// return ok
// }
//
// // Deallocate removes the worker from the pool of
// // available workers. If the worker is currently
// // reserved and performing work it will finish,
// // but no longer be given new work.
// func (p *Pool) Deallocate(w worker.Worker) {
// p.Lock()
// defer p.Unlock()
// delete(p.workers, w)
// }
//
// // List returns a list of all Workers currently
// // allocated to the Pool.
// func (p *Pool) List() []worker.Worker {
// p.Lock()
// defer p.Unlock()
//
// var workers []worker.Worker
// for w, _ := range p.workers {
// workers = append(workers, w)
// }
// return workers
// }
//
// // Reserve reserves the next available worker to
// // start doing work. Once work is complete, the
// // worker should be released back to the pool.
// func (p *Pool) Reserve() <-chan worker.Worker {
// return p.workerc
// }
//
// // Release releases the worker back to the pool
// // of available workers.
// func (p *Pool) Release(w worker.Worker) bool {
// if !p.IsAllocated(w) {
// return false
// }
//
// p.workerc <- w
// return true
// }

1
builder/worker/worker.go Normal file

@ -0,0 +1 @@
package worker

@ -4,10 +4,9 @@ import (
"os"
"github.com/drone/drone-cli/builder"
"github.com/drone/drone-cli/builder/ambassador"
"github.com/drone/drone-cli/builder/docker"
"github.com/drone/drone-cli/common"
"github.com/drone/drone-cli/parser"
"github.com/samalba/dockerclient"
log "github.com/Sirupsen/logrus"
)
@ -23,7 +22,7 @@ type Context struct {
builder *builder.Builder
config *common.Config
client dockerclient.Client
client *docker.Ambassador
}
func main() {
@ -45,7 +44,7 @@ func main() {
// list of builds and builders for each item
// in the matrix
for _, conf := range matrix {
client, err := ambassador.Create(&mockClient{})
client, err := docker.NewAmbassador(&mockClient{})
if err != nil {
return
}