mirror of
https://github.com/rancher/os.git
synced 2025-09-05 08:42:38 +00:00
Sync with libcompose
This commit is contained in:
@@ -2,17 +2,24 @@ package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/docker/libcompose/cli/logger"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
composeClient "github.com/docker/libcompose/docker/client"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/project/events"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"github.com/rancher/os/config"
|
||||
rosDocker "github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func CreateService(cfg *config.CloudConfig, name string, serviceConfig *project.ServiceConfig) (project.Service, error) {
|
||||
func CreateService(cfg *config.CloudConfig, name string, serviceConfig *composeConfig.ServiceConfigV1) (project.Service, error) {
|
||||
if cfg == nil {
|
||||
var err error
|
||||
cfg, err = config.LoadConfig()
|
||||
@@ -21,7 +28,7 @@ func CreateService(cfg *config.CloudConfig, name string, serviceConfig *project.
|
||||
}
|
||||
}
|
||||
|
||||
p, err := CreateServiceSet("once", cfg, map[string]*project.ServiceConfig{
|
||||
p, err := CreateServiceSet("once", cfg, map[string]*composeConfig.ServiceConfigV1{
|
||||
name: serviceConfig,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -31,7 +38,7 @@ func CreateService(cfg *config.CloudConfig, name string, serviceConfig *project.
|
||||
return p.CreateService(name)
|
||||
}
|
||||
|
||||
func CreateServiceSet(name string, cfg *config.CloudConfig, configs map[string]*project.ServiceConfig) (*project.Project, error) {
|
||||
func CreateServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
|
||||
p, err := newProject(name, cfg, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -42,21 +49,20 @@ func CreateServiceSet(name string, cfg *config.CloudConfig, configs map[string]*
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func RunServiceSet(name string, cfg *config.CloudConfig, configs map[string]*project.ServiceConfig) (*project.Project, error) {
|
||||
func RunServiceSet(name string, cfg *config.CloudConfig, configs map[string]*composeConfig.ServiceConfigV1) (*project.Project, error) {
|
||||
p, err := CreateServiceSet(name, cfg, configs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, p.Up()
|
||||
return p, p.Up(context.Background(), options.Up{})
|
||||
}
|
||||
|
||||
func GetProject(cfg *config.CloudConfig, networkingAvailable bool) (*project.Project, error) {
|
||||
return newCoreServiceProject(cfg, networkingAvailable)
|
||||
}
|
||||
|
||||
func newProject(name string, cfg *config.CloudConfig, environmentLookup project.EnvironmentLookup) (*project.Project, error) {
|
||||
clientFactory, err := rosDocker.NewClientFactory(docker.ClientOpts{})
|
||||
func newProject(name string, cfg *config.CloudConfig, environmentLookup composeConfig.EnvironmentLookup) (*project.Project, error) {
|
||||
clientFactory, err := rosDocker.NewClientFactory(composeClient.Options{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,23 +78,75 @@ func newProject(name string, cfg *config.CloudConfig, environmentLookup project.
|
||||
ClientFactory: clientFactory,
|
||||
Context: project.Context{
|
||||
ProjectName: name,
|
||||
NoRecreate: true, // for libcompose to not recreate on project reload, looping up the boot :)
|
||||
EnvironmentLookup: environmentLookup,
|
||||
ServiceFactory: serviceFactory,
|
||||
Log: cfg.Rancher.Log,
|
||||
LoggerFactory: logger.NewColorLoggerFactory(),
|
||||
},
|
||||
}
|
||||
serviceFactory.Context = context
|
||||
|
||||
return docker.NewProject(context)
|
||||
return docker.NewProject(context, &composeConfig.ParseOptions{
|
||||
Interpolate: true,
|
||||
Validate: false,
|
||||
Preprocess: preprocessServiceMap,
|
||||
})
|
||||
}
|
||||
|
||||
func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*project.ServiceConfig) map[interface{}]interface{} {
|
||||
func preprocessServiceMap(serviceMap composeConfig.RawServiceMap) (composeConfig.RawServiceMap, error) {
|
||||
newServiceMap := make(composeConfig.RawServiceMap)
|
||||
|
||||
for k, v := range serviceMap {
|
||||
newServiceMap[k] = make(composeConfig.RawService)
|
||||
|
||||
for k2, v2 := range v {
|
||||
if k2 == "environment" || k2 == "labels" {
|
||||
newServiceMap[k][k2] = preprocess(v2, true)
|
||||
} else {
|
||||
newServiceMap[k][k2] = preprocess(v2, false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return newServiceMap, nil
|
||||
}
|
||||
|
||||
func preprocess(item interface{}, replaceTypes bool) interface{} {
|
||||
switch typedDatas := item.(type) {
|
||||
|
||||
case map[interface{}]interface{}:
|
||||
newMap := make(map[interface{}]interface{})
|
||||
|
||||
for key, value := range typedDatas {
|
||||
newMap[key] = preprocess(value, replaceTypes)
|
||||
}
|
||||
return newMap
|
||||
|
||||
case []interface{}:
|
||||
// newArray := make([]interface{}, 0) will cause golint to complain
|
||||
var newArray []interface{}
|
||||
newArray = make([]interface{}, 0)
|
||||
|
||||
for _, value := range typedDatas {
|
||||
newArray = append(newArray, preprocess(value, replaceTypes))
|
||||
}
|
||||
return newArray
|
||||
|
||||
default:
|
||||
if replaceTypes {
|
||||
return fmt.Sprint(item)
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*composeConfig.ServiceConfigV1) map[interface{}]interface{} {
|
||||
serviceConfigsV2, _ := composeConfig.ConvertServices(configs)
|
||||
|
||||
// Note: we ignore errors while loading services
|
||||
unchanged := true
|
||||
for name, serviceConfig := range configs {
|
||||
hash := project.GetServiceHash(name, serviceConfig)
|
||||
for name, serviceConfig := range serviceConfigsV2 {
|
||||
hash := composeConfig.GetServiceHash(name, serviceConfig)
|
||||
|
||||
if enabled[name] == hash {
|
||||
continue
|
||||
@@ -121,8 +179,8 @@ func adjustContainerNames(m map[interface{}]interface{}) map[interface{}]interfa
|
||||
return m
|
||||
}
|
||||
|
||||
func newCoreServiceProject(cfg *config.CloudConfig, network bool) (*project.Project, error) {
|
||||
projectEvents := make(chan project.Event)
|
||||
func newCoreServiceProject(cfg *config.CloudConfig, useNetwork bool) (*project.Project, error) {
|
||||
projectEvents := make(chan events.Event)
|
||||
enabled := map[interface{}]interface{}{}
|
||||
|
||||
environmentLookup := rosDocker.NewConfigEnvironment(cfg)
|
||||
@@ -151,7 +209,7 @@ func newCoreServiceProject(cfg *config.CloudConfig, network bool) (*project.Proj
|
||||
continue
|
||||
}
|
||||
|
||||
bytes, err := LoadServiceResource(service, network, cfg)
|
||||
bytes, err := LoadServiceResource(service, useNetwork, cfg)
|
||||
if err != nil {
|
||||
if err == util.ErrNoNetwork {
|
||||
log.Debugf("Can not load %s, networking not enabled", service)
|
||||
@@ -185,8 +243,8 @@ func newCoreServiceProject(cfg *config.CloudConfig, network bool) (*project.Proj
|
||||
|
||||
go func() {
|
||||
for event := range projectEvents {
|
||||
if event.EventType == project.EventContainerStarted && event.ServiceName == "ntp" {
|
||||
network = true
|
||||
if event.EventType == events.ContainerStarted && event.ServiceName == "ntp" {
|
||||
useNetwork = true
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -229,15 +287,15 @@ func StageServices(cfg *config.CloudConfig, services ...string) error {
|
||||
}
|
||||
|
||||
// Reduce service configurations to just image and labels
|
||||
for serviceName, serviceConfig := range p.Configs {
|
||||
p.Configs[serviceName] = &project.ServiceConfig{
|
||||
for _, serviceName := range p.ServiceConfigs.Keys() {
|
||||
serviceConfig, _ := p.ServiceConfigs.Get(serviceName)
|
||||
p.ServiceConfigs.Add(serviceName, &composeConfig.ServiceConfig{
|
||||
Image: serviceConfig.Image,
|
||||
Labels: serviceConfig.Labels,
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
return p.Pull()
|
||||
return p.Pull(context.Background())
|
||||
}
|
||||
|
||||
func LoadServiceResource(name string, network bool, cfg *config.CloudConfig) ([]byte, error) {
|
||||
|
Reference in New Issue
Block a user