mirror of
https://github.com/rancher/os.git
synced 2025-09-01 06:40:31 +00:00
Sync with libcompose
This commit is contained in:
@@ -1,26 +1,27 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
dockerClient "github.com/fsouza/go-dockerclient"
|
||||
dockerClient "github.com/docker/engine-api/client"
|
||||
"github.com/rancher/os/config"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func NewSystemClient() (*dockerClient.Client, error) {
|
||||
func NewSystemClient() (dockerClient.APIClient, error) {
|
||||
return NewClient(config.DOCKER_SYSTEM_HOST)
|
||||
}
|
||||
|
||||
func NewDefaultClient() (*dockerClient.Client, error) {
|
||||
func NewDefaultClient() (dockerClient.APIClient, error) {
|
||||
return NewClient(config.DOCKER_HOST)
|
||||
}
|
||||
|
||||
func NewClient(endpoint string) (*dockerClient.Client, error) {
|
||||
client, err := dockerClient.NewClient(endpoint)
|
||||
func NewClient(endpoint string) (dockerClient.APIClient, error) {
|
||||
client, err := dockerClient.NewClient(endpoint, "", nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = ClientOK(endpoint, func() bool {
|
||||
_, err := client.Info()
|
||||
_, err := client.Info(context.Background())
|
||||
return err == nil
|
||||
})
|
||||
|
||||
|
@@ -4,34 +4,36 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libcompose/docker"
|
||||
dockerclient "github.com/docker/engine-api/client"
|
||||
composeClient "github.com/docker/libcompose/docker/client"
|
||||
"github.com/docker/libcompose/project"
|
||||
dockerclient "github.com/fsouza/go-dockerclient"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
type ClientFactory struct {
|
||||
userClient *dockerclient.Client
|
||||
systemClient *dockerclient.Client
|
||||
userClient dockerclient.APIClient
|
||||
systemClient dockerclient.APIClient
|
||||
userOnce sync.Once
|
||||
systemOnce sync.Once
|
||||
}
|
||||
|
||||
func NewClientFactory(opts docker.ClientOpts) (docker.ClientFactory, error) {
|
||||
func NewClientFactory(opts composeClient.Options) (project.ClientFactory, error) {
|
||||
userOpts := opts
|
||||
systemOpts := opts
|
||||
|
||||
userOpts.Host = config.DOCKER_HOST
|
||||
systemOpts.Host = config.DOCKER_SYSTEM_HOST
|
||||
|
||||
userClient, err := docker.CreateClient(userOpts)
|
||||
userClient, err := composeClient.Create(userOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
systemClient, err := docker.CreateClient(systemOpts)
|
||||
systemClient, err := composeClient.Create(systemOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -42,7 +44,7 @@ func NewClientFactory(opts docker.ClientOpts) (docker.ClientFactory, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ClientFactory) Create(service project.Service) *dockerclient.Client {
|
||||
func (c *ClientFactory) Create(service project.Service) dockerclient.APIClient {
|
||||
if IsSystemContainer(service.Config()) {
|
||||
waitFor(&c.systemOnce, c.systemClient, config.DOCKER_SYSTEM_HOST)
|
||||
return c.systemClient
|
||||
@@ -52,10 +54,10 @@ func (c *ClientFactory) Create(service project.Service) *dockerclient.Client {
|
||||
return c.userClient
|
||||
}
|
||||
|
||||
func waitFor(once *sync.Once, client *dockerclient.Client, endpoint string) {
|
||||
func waitFor(once *sync.Once, client dockerclient.APIClient, endpoint string) {
|
||||
once.Do(func() {
|
||||
err := ClientOK(endpoint, func() bool {
|
||||
_, err := client.Info()
|
||||
_, err := client.Info(context.Background())
|
||||
return err == nil
|
||||
})
|
||||
if err != nil {
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/libcompose/project"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/rancher/os/config"
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ func (c *ConfigEnvironment) SetConfig(cfg *config.CloudConfig) {
|
||||
c.cfg = cfg
|
||||
}
|
||||
|
||||
func (c *ConfigEnvironment) Lookup(key, serviceName string, serviceConfig *project.ServiceConfig) []string {
|
||||
func (c *ConfigEnvironment) Lookup(key, serviceName string, serviceConfig *composeConfig.ServiceConfig) []string {
|
||||
fullKey := fmt.Sprintf("%s/%s", serviceName, key)
|
||||
return lookupKeys(c.cfg, fullKey, key)
|
||||
}
|
||||
|
@@ -2,10 +2,14 @@ package docker
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
dockerclient "github.com/docker/engine-api/client"
|
||||
"github.com/docker/engine-api/types"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/docker/libcompose/project"
|
||||
dockerclient "github.com/fsouza/go-dockerclient"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"github.com/rancher/os/config"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
@@ -15,7 +19,7 @@ type Service struct {
|
||||
project *project.Project
|
||||
}
|
||||
|
||||
func NewService(factory *ServiceFactory, name string, serviceConfig *project.ServiceConfig, context *docker.Context, project *project.Project) *Service {
|
||||
func NewService(factory *ServiceFactory, name string, serviceConfig *composeConfig.ServiceConfig, context *docker.Context, project *project.Project) *Service {
|
||||
return &Service{
|
||||
Service: docker.NewService(name, serviceConfig, context),
|
||||
deps: factory.Deps,
|
||||
@@ -50,20 +54,20 @@ func (s *Service) missingImage() bool {
|
||||
return false
|
||||
}
|
||||
client := s.context.ClientFactory.Create(s)
|
||||
i, err := client.InspectImage(s.Config().Image)
|
||||
return err != nil || i == nil
|
||||
_, _, err := client.ImageInspectWithRaw(context.Background(), s.Config().Image, false)
|
||||
return err != nil
|
||||
}
|
||||
|
||||
func (s *Service) requiresSyslog() bool {
|
||||
return s.Config().LogDriver == "syslog"
|
||||
return s.Config().Logging.Driver == "syslog"
|
||||
}
|
||||
|
||||
func (s *Service) requiresUserDocker() bool {
|
||||
return s.Config().Labels.MapParts()[config.SCOPE] != config.SYSTEM
|
||||
return s.Config().Labels[config.SCOPE] != config.SYSTEM
|
||||
}
|
||||
|
||||
func appendLink(deps []project.ServiceRelationship, name string, optional bool, p *project.Project) []project.ServiceRelationship {
|
||||
if _, ok := p.Configs[name]; !ok {
|
||||
if _, ok := p.ServiceConfigs.Get(name); !ok {
|
||||
return deps
|
||||
}
|
||||
rel := project.NewServiceRelationship(name, project.RelTypeLink)
|
||||
@@ -71,8 +75,8 @@ func appendLink(deps []project.ServiceRelationship, name string, optional bool,
|
||||
return append(deps, rel)
|
||||
}
|
||||
|
||||
func (s *Service) shouldRebuild() (bool, error) {
|
||||
containers, err := s.Containers()
|
||||
func (s *Service) shouldRebuild(ctx context.Context) (bool, error) {
|
||||
containers, err := s.Containers(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -81,19 +85,19 @@ func (s *Service) shouldRebuild() (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
for _, c := range containers {
|
||||
outOfSync, err := c.(*docker.Container).OutOfSync(s.Service.Config().Image)
|
||||
outOfSync, err := c.(*docker.Container).OutOfSync(ctx, s.Service.Config().Image)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, containerInfo, err := s.getContainer()
|
||||
if containerInfo == nil || err != nil {
|
||||
_, containerInfo, err := s.getContainer(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
name := containerInfo.Name[1:]
|
||||
|
||||
origRebuildLabel := containerInfo.Config.Labels[config.REBUILD]
|
||||
newRebuildLabel := s.Config().Labels.MapParts()[config.REBUILD]
|
||||
newRebuildLabel := s.Config().Labels[config.REBUILD]
|
||||
rebuildLabelChanged := newRebuildLabel != origRebuildLabel
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"origRebuildLabel": origRebuildLabel,
|
||||
@@ -103,6 +107,9 @@ func (s *Service) shouldRebuild() (bool, error) {
|
||||
|
||||
rebuilding := false
|
||||
if outOfSync {
|
||||
if s.Name() != "console" {
|
||||
continue
|
||||
}
|
||||
if cfg.Rancher.ForceConsoleRebuild && s.Name() == "console" {
|
||||
cfg.Rancher.ForceConsoleRebuild = false
|
||||
if err := cfg.Save(); err != nil {
|
||||
@@ -124,36 +131,37 @@ func (s *Service) shouldRebuild() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (s *Service) Up() error {
|
||||
labels := s.Config().Labels.MapParts()
|
||||
func (s *Service) Up(ctx context.Context, options options.Up) error {
|
||||
labels := s.Config().Labels
|
||||
|
||||
if err := s.Service.Create(); err != nil {
|
||||
if err := s.Service.Create(ctx, options.Create); err != nil {
|
||||
return err
|
||||
}
|
||||
shouldRebuild, err := s.shouldRebuild()
|
||||
|
||||
shouldRebuild, err := s.shouldRebuild(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if shouldRebuild {
|
||||
cs, err := s.Service.Containers()
|
||||
cs, err := s.Service.Containers(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range cs {
|
||||
if _, err := c.(*docker.Container).Recreate(s.Config().Image); err != nil {
|
||||
if _, err := c.(*docker.Container).Recreate(ctx, s.Config().Image); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.rename()
|
||||
s.rename(ctx)
|
||||
}
|
||||
if labels[config.CREATE_ONLY] == "true" {
|
||||
return s.checkReload(labels)
|
||||
}
|
||||
if err := s.Service.Up(); err != nil {
|
||||
if err := s.Service.Up(ctx, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if labels[config.DETACH] == "false" {
|
||||
if err := s.wait(); err != nil {
|
||||
if err := s.wait(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -168,52 +176,53 @@ func (s *Service) checkReload(labels map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) Create() error {
|
||||
return s.Service.Create()
|
||||
func (s *Service) Create(ctx context.Context, options options.Create) error {
|
||||
return s.Service.Create(ctx, options)
|
||||
}
|
||||
|
||||
func (s *Service) getContainer() (*dockerclient.Client, *dockerclient.Container, error) {
|
||||
containers, err := s.Service.Containers()
|
||||
func (s *Service) getContainer(ctx context.Context) (dockerclient.APIClient, types.ContainerJSON, error) {
|
||||
containers, err := s.Service.Containers(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, types.ContainerJSON{}, err
|
||||
}
|
||||
|
||||
if len(containers) == 0 {
|
||||
return nil, nil, nil
|
||||
return nil, types.ContainerJSON{}, nil
|
||||
}
|
||||
|
||||
id, err := containers[0].ID()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, types.ContainerJSON{}, err
|
||||
}
|
||||
|
||||
client := s.context.ClientFactory.Create(s)
|
||||
info, err := client.InspectContainer(id)
|
||||
info, err := client.ContainerInspect(context.Background(), id)
|
||||
return client, info, err
|
||||
}
|
||||
|
||||
func (s *Service) wait() error {
|
||||
client, info, err := s.getContainer()
|
||||
if err != nil || info == nil {
|
||||
func (s *Service) wait(ctx context.Context) error {
|
||||
client, info, err := s.getContainer(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := client.WaitContainer(info.ID); err != nil {
|
||||
if _, err := client.ContainerWait(context.Background(), info.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) rename() error {
|
||||
client, info, err := s.getContainer()
|
||||
if err != nil || info == nil {
|
||||
func (s *Service) rename(ctx context.Context) error {
|
||||
client, info, err := s.getContainer(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(info.Name) > 0 && info.Name[1:] != s.Name() {
|
||||
logrus.Debugf("Renaming container %s => %s", info.Name[1:], s.Name())
|
||||
return client.RenameContainer(dockerclient.RenameContainerOptions{ID: info.ID, Name: s.Name()})
|
||||
return client.ContainerRename(context.Background(), info.ID, s.Name())
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/rancher/os/util"
|
||||
@@ -11,13 +12,13 @@ type ServiceFactory struct {
|
||||
Deps map[string][]string
|
||||
}
|
||||
|
||||
func (s *ServiceFactory) Create(project *project.Project, name string, serviceConfig *project.ServiceConfig) (project.Service, error) {
|
||||
if after := serviceConfig.Labels.MapParts()["io.rancher.os.after"]; after != "" {
|
||||
func (s *ServiceFactory) Create(project *project.Project, name string, serviceConfig *composeConfig.ServiceConfig) (project.Service, error) {
|
||||
if after := serviceConfig.Labels["io.rancher.os.after"]; after != "" {
|
||||
for _, dep := range util.TrimSplit(after, ",") {
|
||||
s.Deps[name] = append(s.Deps[name], dep)
|
||||
}
|
||||
}
|
||||
if before := serviceConfig.Labels.MapParts()["io.rancher.os.before"]; before != "" {
|
||||
if before := serviceConfig.Labels["io.rancher.os.before"]; before != "" {
|
||||
for _, dep := range util.TrimSplit(before, ",") {
|
||||
s.Deps[dep] = append(s.Deps[dep], name)
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/docker/libcompose/project"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/rancher/os/config"
|
||||
)
|
||||
|
||||
func IsSystemContainer(serviceConfig *project.ServiceConfig) bool {
|
||||
return serviceConfig.Labels.MapParts()[config.SCOPE] == config.SYSTEM
|
||||
func IsSystemContainer(serviceConfig *composeConfig.ServiceConfig) bool {
|
||||
return serviceConfig.Labels[config.SCOPE] == config.SYSTEM
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user