mirror of
https://github.com/rancher/os.git
synced 2025-06-26 15:01:34 +00:00
137 lines
3.0 KiB
Go
137 lines
3.0 KiB
Go
package docker
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
"github.com/rancherio/os/config"
|
|
"github.com/rancherio/os/util"
|
|
"github.com/rancherio/rancher-compose/librcompose/project"
|
|
)
|
|
|
|
type configEnvironment struct {
|
|
cfg *config.Config
|
|
}
|
|
|
|
func appendEnv(array []string, key, value string) []string {
|
|
parts := strings.SplitN(key, "/", 2)
|
|
if len(parts) == 2 {
|
|
key = parts[1]
|
|
}
|
|
|
|
return append(array, fmt.Sprintf("%s=%s", key, value))
|
|
}
|
|
|
|
func lookupKeys(cfg *config.Config, keys ...string) []string {
|
|
for _, key := range keys {
|
|
if strings.HasSuffix(key, "*") {
|
|
result := []string{}
|
|
for envKey, envValue := range cfg.Environment {
|
|
keyPrefix := key[:len(key)-1]
|
|
if strings.HasPrefix(envKey, keyPrefix) {
|
|
result = appendEnv(result, envKey, envValue)
|
|
}
|
|
}
|
|
|
|
if len(result) > 0 {
|
|
return result
|
|
}
|
|
} else if value, ok := cfg.Environment[key]; ok {
|
|
return appendEnv([]string{}, key, value)
|
|
}
|
|
}
|
|
|
|
return []string{}
|
|
}
|
|
|
|
func (c *configEnvironment) Lookup(key, serviceName string, serviceConfig *project.ServiceConfig) []string {
|
|
fullKey := fmt.Sprintf("%s/%s", serviceName, key)
|
|
return lookupKeys(c.cfg, fullKey, key)
|
|
}
|
|
|
|
func RunServices(name string, cfg *config.Config, configs map[string]*project.ServiceConfig) error {
|
|
network := false
|
|
projectEvents := make(chan project.ProjectEvent)
|
|
p := project.NewProject(name, NewContainerFactory(cfg))
|
|
p.EnvironmentLookup = &configEnvironment{cfg: cfg}
|
|
p.AddListener(projectEvents)
|
|
enabled := make(map[string]bool)
|
|
|
|
for name, serviceConfig := range configs {
|
|
if err := p.AddConfig(name, serviceConfig); err != nil {
|
|
log.Infof("Failed loading service %s", name)
|
|
}
|
|
}
|
|
|
|
p.ReloadCallback = func() error {
|
|
err := cfg.Reload()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for service, serviceEnabled := range cfg.ServicesInclude {
|
|
if !serviceEnabled {
|
|
continue
|
|
}
|
|
|
|
if _, ok := enabled[service]; ok {
|
|
continue
|
|
}
|
|
|
|
bytes, err := LoadServiceResource(service, network, cfg)
|
|
if err != nil {
|
|
if err == util.ErrNoNetwork {
|
|
log.Debugf("Can not load %s, networking not enabled", service)
|
|
} else {
|
|
log.Errorf("Failed to load %s : %v", service, err)
|
|
}
|
|
continue
|
|
}
|
|
|
|
err = p.Load(bytes)
|
|
if err != nil {
|
|
log.Errorf("Failed to load %s : %v", service, err)
|
|
continue
|
|
}
|
|
|
|
enabled[service] = true
|
|
}
|
|
|
|
for service, config := range cfg.Services {
|
|
if _, ok := enabled[service]; ok {
|
|
continue
|
|
}
|
|
|
|
err = p.AddConfig(service, config)
|
|
if err != nil {
|
|
log.Errorf("Failed to load %s : %v", service, err)
|
|
continue
|
|
}
|
|
|
|
enabled[service] = true
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
go func() {
|
|
for event := range projectEvents {
|
|
if event.Event == project.CONTAINER_STARTED && event.ServiceName == "network" {
|
|
network = true
|
|
}
|
|
}
|
|
}()
|
|
|
|
err := p.ReloadCallback()
|
|
if err != nil {
|
|
log.Errorf("Failed to reload %s : %v", name, err)
|
|
return err
|
|
}
|
|
return p.Up()
|
|
}
|
|
|
|
func LoadServiceResource(name string, network bool, cfg *config.Config) ([]byte, error) {
|
|
return util.LoadResource(name, network, cfg.Repositories.ToArray())
|
|
}
|