예제 #1
0
파일: api.go 프로젝트: carriercomm/serviced
// Images returns a list of all the named images in the local repository
func Images() ([]*Image, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}
	imgs, err := dc.ListImages(false)
	if err != nil {
		return nil, err
	}

	re := regexp.MustCompile("<none>:<none>")

	resp := []*Image{}
	for _, img := range imgs {
		for _, repotag := range img.RepoTags {
			if len(re.FindString(repotag)) > 0 {
				continue
			}

			iid, err := commons.ParseImageID(repotag)
			if err != nil {
				return resp, err
			}
			resp = append(resp, &Image{img.ID, *iid})
		}
	}
	return resp, nil
}
예제 #2
0
파일: api.go 프로젝트: carriercomm/serviced
// Stop stops the container specified by the id. If the container can't be stopped before the timeout
// expires an error is returned.
func (c *Container) Stop(timeout time.Duration) error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	return dc.StopContainer(c.ID, uint(timeout.Seconds()))
}
예제 #3
0
파일: api.go 프로젝트: carriercomm/serviced
// Inspect returns information about the container specified by id.
func (c *Container) Inspect() (*dockerclient.Container, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}
	return dc.InspectContainer(c.ID)
}
예제 #4
0
파일: api.go 프로젝트: carriercomm/serviced
// Delete remove the image from the local repository
func (img *Image) Delete() error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	return dc.RemoveImage(img.ID.String())
}
예제 #5
0
파일: api.go 프로젝트: carriercomm/serviced
// Export writes the contents of the container's filesystem as a tar archive to outfile.
func (c *Container) Export(outfile *os.File) error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	return dc.ExportContainer(dockerclient.ExportContainerOptions{c.ID, outfile})
}
예제 #6
0
파일: api.go 프로젝트: carriercomm/serviced
// Kill sends a SIGKILL signal to the container. If the container is not started
// no action is taken.
func (c *Container) Kill() error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	return dc.KillContainer(dockerclient.KillContainerOptions{ID: c.ID, Signal: dockerclient.SIGKILL})
}
예제 #7
0
파일: api.go 프로젝트: carriercomm/serviced
// Delete removes the container.
func (c *Container) Delete(volumes bool) error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	return dc.RemoveContainer(dockerclient.RemoveContainerOptions{ID: c.ID, RemoveVolumes: volumes})
}
예제 #8
0
파일: api.go 프로젝트: carriercomm/serviced
// Commit creates a new Image from the containers changes.
func (c *Container) Commit(iidstr string) (*Image, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}
	iid, err := commons.ParseImageID(iidstr)
	if err != nil {
		return nil, err
	}

	img, err := dc.CommitContainer(
		dockerclient.CommitContainerOptions{
			Container:  c.ID,
			Repository: iid.BaseName(),
		})

	if err != nil {
		glog.V(1).Infof("unable to commit container %s: %v", c.ID, err)
		return nil, err
	}

	if useRegistry {
		err = pushImage(iid.BaseName(), iid.Registry(), iid.Tag)
	}

	return &Image{img.ID, *iid}, err
}
예제 #9
0
파일: api.go 프로젝트: carriercomm/serviced
func InspectImage(uuid string) (*dockerclient.Image, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}
	return dc.InspectImage(uuid)
}
예제 #10
0
파일: api.go 프로젝트: carriercomm/serviced
// ImportImage creates a new image in the local repository from a file system archive.
func ImportImage(repotag, filename string) error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}
	glog.V(1).Infof("importing image %s from %s", repotag, filename)
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()

	iid, err := commons.ParseImageID(repotag)
	if err != nil {
		return err
	}

	opts := dockerclient.ImportImageOptions{
		Repository:  iid.BaseName(),
		Source:      "-",
		InputStream: f,
		Tag:         iid.Tag,
	}

	if err = dc.ImportImage(opts); err != nil {
		glog.V(1).Infof("unable to import %s: %v", repotag, err)
		return err
	}
	return err
}
예제 #11
0
파일: api.go 프로젝트: carriercomm/serviced
// Opens a connection to docker if not already connected
func (a *api) connectDocker() (*dockerclient.Client, error) {
	if a.docker == nil {
		const DockerEndpoint string = "unix:///var/run/docker.sock"
		var err error
		if a.docker, err = dockerclient.NewClient(DockerEndpoint); err != nil {
			return nil, fmt.Errorf("could not create a client to docker: %s", err)
		}
	}
	return a.docker, nil
}
예제 #12
0
파일: api.go 프로젝트: carriercomm/serviced
// FindContainer looks up a container using its id or name.
func FindContainer(id string) (*Container, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}

	ctr, err := dc.InspectContainer(id)
	if err != nil {
		if _, ok := err.(*dockerclient.NoSuchContainer); ok {
			return nil, ErrNoSuchContainer
		}
		return nil, err
	}
	return &Container{ctr, dockerclient.HostConfig{}}, nil
}
예제 #13
0
// init starts up the kernel loop that is responsible for handling all the API calls
// in a goroutine.
func init() {
	trues := []string{"1", "true", "t", "yes"}
	if v := strings.ToLower(os.Getenv(sdr)); v != "" {
		for _, t := range trues {
			if v == t {
				useRegistry = true
			}
		}
	}

	client, err := dockerclient.NewClient(dockerep)
	if err != nil {
		panic(fmt.Sprintf("can't create Docker client: %v", err))
	}

	go kernel(client, done)
}
예제 #14
0
파일: api.go 프로젝트: carriercomm/serviced
// Containers retrieves a list of all the Docker containers.
func Containers() ([]*Container, error) {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}
	apictrs, err := dc.ListContainers(dockerclient.ListContainersOptions{All: true})
	if err != nil {
		return nil, err
	}
	resp := []*Container{}
	for _, apictr := range apictrs {
		ctr, err := dc.InspectContainer(apictr.ID)
		if err != nil {
			continue
		}
		resp = append(resp, &Container{ctr, dockerclient.HostConfig{}})
	}
	return resp, nil
}
예제 #15
0
파일: api.go 프로젝트: carriercomm/serviced
// Start uses the information provided in the container definition cd to start a new Docker
// container. If a container can't be started before the timeout expires an error is returned.
func (c *Container) Start(timeout time.Duration) error {
	if c.State.Running != false {
		return nil
	}

	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}

	args := struct {
		id         string
		hostConfig *dockerclient.HostConfig
	}{c.ID, &c.HostConfig}

	// check to see if the container is already running
	ctr, err := dc.InspectContainer(args.id)
	if err != nil {
		glog.V(1).Infof("unable to inspect container %s prior to starting it: %v", args.id, err)
		return err
	}

	if ctr.State.Running {
		return ErrAlreadyStarted
	}

	glog.V(2).Infof("starting container %s: %+v", args.id, args.hostConfig)
	err = dc.StartContainer(args.id, args.hostConfig)
	if err != nil {
		glog.V(2).Infof("unable to start %s: %v", args.id, err)
		return err
	}

	glog.V(2).Infof("update container %s state post start", args.id)
	ctr, err = dc.InspectContainer(args.id)
	if err != nil {
		glog.V(2).Infof("failed to update container %s state post start: %v", args.id, err)
		return err
	}
	c.Container = ctr

	return nil
}
예제 #16
0
파일: api.go 프로젝트: carriercomm/serviced
func pullImage(repo, registry, tag string) error {

	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}

	glog.V(2).Info("pulling image: ", repo)
	opts := dockerclient.PullImageOptions{
		Repository: repo,
		Registry:   registry,
		Tag:        tag,
	}

	// FIXME: Need to populate AuthConfiguration (eventually)
	err = dc.PullImage(opts, dockerclient.AuthConfiguration{})
	if err != nil {
		glog.V(2).Infof("failed to pull %s: %v", repo, err)
		return err
	}
	return nil
}
예제 #17
0
파일: api.go 프로젝트: carriercomm/serviced
// Tag tags an image in the local repository
func (img *Image) Tag(tag string) (*Image, error) {

	iid, err := commons.ParseImageID(tag)
	if err != nil {
		return nil, err
	}

	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}

	args := struct {
		uuid     string
		name     string
		repo     string
		registry string
		tag      string
	}{img.UUID, img.ID.String(), iid.BaseName(), iid.Registry(), iid.Tag}

	glog.V(1).Infof("tagging image %s as: %s", args.repo, args.tag)
	opts := dockerclient.TagImageOptions{Repo: args.repo, Tag: args.tag, Force: true}
	err = dc.TagImage(args.name, opts)
	if err != nil {
		glog.V(1).Infof("unable to tag image %s: %v", args.repo, err)
		return nil, err
	}

	if useRegistry {
		pushImage(args.repo, args.registry, args.tag)
	}

	iid, err = commons.ParseImageID(fmt.Sprintf("%s:%s", args.repo, args.tag))
	if err != nil {
		return nil, err
	}
	return &Image{args.uuid, *iid}, nil
}
예제 #18
0
파일: api.go 프로젝트: carriercomm/serviced
// Wait blocks until the container stops or the timeout expires and then returns its exit code.
func (c *Container) Wait(timeout time.Duration) (int, error) {

	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return -127, err
	}
	type waitResult struct {
		rc  int
		err error
	}
	errc := make(chan waitResult, 1)
	go func() {
		rc, err := dc.WaitContainer(c.ID)
		errc <- waitResult{rc, err}
	}()

	select {
	case <-time.After(timeout):
	case result := <-errc:
		return result.rc, result.err
	}
	return -127, ErrRequestTimeout
}
예제 #19
0
파일: api.go 프로젝트: carriercomm/serviced
func pushImage(repo, registry, tag string) error {
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return err
	}

	glog.V(0).Infof("pushing image from repo: %s to registry: %s with tag: %s", repo, registry, tag)
	opts := dockerclient.PushImageOptions{
		Name:     repo,
		Registry: registry,
		Tag:      tag,
	}

	// FIXME: Need to populate AuthConfiguration (eventually)
	err = dc.PushImage(opts, dockerclient.AuthConfiguration{})
	if err != nil {
		glog.V(2).Infof("failed to push %s: %v", repo, err)
		return err
	}

	glog.V(0).Infof("finished pushing image from repo: %s to registry: %s with tag: %s", repo, registry, tag)
	return nil
}
예제 #20
0
	"github.com/control-center/serviced/commons"
	"github.com/control-center/serviced/commons/docker"
	"github.com/control-center/serviced/dao"
	"github.com/control-center/serviced/datastore"
	"github.com/control-center/serviced/domain/service"
	"github.com/control-center/serviced/domain/servicedefinition"
	"github.com/control-center/serviced/domain/servicetemplate"
	"github.com/control-center/serviced/isvcs"
)

type reloadLogstashContainer func(ctx datastore.Context, f *Facade) error

var LogstashContainerReloader reloadLogstashContainer = reloadLogstashContainerImpl

var getDockerClient = func() (*dockerclient.Client, error) { return dockerclient.NewClient("unix:///var/run/docker.sock") }

//AddServiceTemplate  adds a service template to the system. Returns the id of the template added
func (f *Facade) AddServiceTemplate(ctx datastore.Context, serviceTemplate servicetemplate.ServiceTemplate) (string, error) {
	hash, err := serviceTemplate.Hash()
	if err != nil {
		return "", err
	}
	serviceTemplate.ID = hash

	if st, _ := f.templateStore.Get(ctx, hash); st != nil {
		// This id already exists in the system
		glog.Infof("Not replacing existing template %s", hash)
		return hash, nil
	}
예제 #21
0
파일: api.go 프로젝트: carriercomm/serviced
// NewContainer creates a new container and returns its id. The supplied create action, if
// any, will be executed on successful creation of the container. If a start action is specified
// it will be executed after the container has been started. Note, if the start parameter is
// false the container won't be started and the start action will not be executed.
func NewContainer(cd *ContainerDefinition, start bool, timeout time.Duration, oncreate ContainerActionFunc, onstart ContainerActionFunc) (*Container, error) {

	args := struct {
		containerOptions *dockerclient.CreateContainerOptions
		hostConfig       *dockerclient.HostConfig
		start            bool
		createaction     ContainerActionFunc
		startaction      ContainerActionFunc
	}{&cd.CreateContainerOptions, &cd.HostConfig, start, oncreate, onstart}

	timeoutc := time.After(timeout)
	dc, err := dockerclient.NewClient(dockerep)
	if err != nil {
		return nil, err
	}

	em, err := dc.MonitorEvents()
	if err != nil {
		return nil, fmt.Errorf("can't monitor Docker events: %v", err)
	}

	iid, err := commons.ParseImageID(args.containerOptions.Config.Image)
	if err != nil {
		return nil, err
	}

	if useRegistry {
		if err := PullImage(iid.String()); err != nil {
			glog.V(2).Infof("Unable to pull image %s: %v", iid.String(), err)
			if _, err2 := lookupImage(iid.String()); err2 != nil {
				return nil, err2
			}
		}
	}

	glog.V(2).Infof("creating container: %#v", *args.containerOptions)
	ctr, err := dc.CreateContainer(*args.containerOptions)
	switch {
	case err == dockerclient.ErrNoSuchImage:
		if err := PullImage(iid.String()); err != nil {
			glog.V(2).Infof("Unable to pull image %s: %v", iid.String(), err)
			return nil, err
		}
		ctr, err = dc.CreateContainer(*args.containerOptions)
		if err != nil {
			glog.V(2).Infof("container creation failed %+v: %v", *args.containerOptions, err)
			return nil, err
		}
	case err != nil:
		glog.V(2).Infof("container creation failed %+v: %v", *args.containerOptions, err)
		return nil, err
	}

	glog.V(2).Infof("created container: %+v", *ctr)
	if args.createaction != nil {
		args.createaction(ctr.ID)
	}

	if args.start {
		ss, err := em.Subscribe(ctr.ID)
		if err != nil {
			return nil, err
		}

		sc := make(chan struct{})

		ss.Handle(Start, func(e dockerclient.Event) error {
			if args.startaction != nil {
				args.startaction(ctr.ID)
			}
			glog.V(2).Infof("handling event: %+v for %s", e, ctr.ID)
			close(sc)
			return nil
		})
		defer ss.Cancel()

		glog.V(2).Infof("post creation start of %s: %+v", ctr.ID, args.hostConfig)
		err = dc.StartContainer(ctr.ID, args.hostConfig)
		if err != nil {
			glog.V(1).Infof("post creation start of %s failed: %v", ctr.ID, err)
			return nil, err
		}

		glog.V(2).Infof("======= wait for %s to start =======", ctr.ID)
		attempts := 0

	WaitForContainerStart:
		for {
			select {
			case <-timeoutc:
				glog.V(2).Infof("timeout starting container")
				return nil, fmt.Errorf("docker timeout starting container after %s", timeout)
			case <-sc:
				glog.V(2).Infof("update container %s state post start", ctr.ID)
				ctrID := ctr.ID
				ctr, err = dc.InspectContainer(ctrID)
				if err != nil {
					glog.V(1).Infof("failed to update container %s state post start: %v", ctrID, err)
					return nil, err
				}
				glog.V(2).Infof("container %s is started", ctr.ID)
				break WaitForContainerStart
			case <-time.After(5 * time.Second):
				nctr, err := dc.InspectContainer(ctr.ID)
				if err != nil {
					glog.V(2).Infof("can't inspect container %s: %v", ctr.ID, err)
					return nil, err
				}
				ctr = nctr

				switch {
				case !ctr.State.Running && attempts > maxStartAttempts:
					glog.V(2).Infof("timed out starting container")
					return nil, fmt.Errorf("timed out starting container: %s", ctr.ID)
				case !ctr.State.Running:
					attempts = attempts + 1
					continue WaitForContainerStart
				default:
					glog.V(2).Infof("container %s is running", ctr.ID)
					break WaitForContainerStart
				}
			}
		}
	}

	return &Container{ctr, cd.HostConfig}, nil
}