123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- 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())
- }
|