mirror of
https://github.com/rancher/os.git
synced 2025-06-30 16:51:47 +00:00
Merge pull request #288 from ibuildthecloud/rancher-compose-refactor
Rancher compose refactor
This commit is contained in:
commit
605dfb085b
12
Godeps/Godeps.json
generated
12
Godeps/Godeps.json
generated
@ -171,14 +171,14 @@
|
||||
"Rev": "166cde1ff3be90b9199a3703177668b647cbdcf4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rancherio/rancher-compose/docker",
|
||||
"Comment": "0.1.0-18-gac8e453",
|
||||
"Rev": "ac8e4533c25f001e633ad85022235182601536dc"
|
||||
"ImportPath": "github.com/rancherio/rancher-compose/librcompose/docker",
|
||||
"Comment": "0.1.0-18-g14fef17",
|
||||
"Rev": "14fef170029bba5896269a3b592035b70ae3f2dc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rancherio/rancher-compose/project",
|
||||
"Comment": "0.1.0-18-gac8e453",
|
||||
"Rev": "ac8e4533c25f001e633ad85022235182601536dc"
|
||||
"ImportPath": "github.com/rancherio/rancher-compose/librcompose/project",
|
||||
"Comment": "0.1.0-18-g14fef17",
|
||||
"Rev": "14fef170029bba5896269a3b592035b70ae3f2dc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ryanuber/go-glob",
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/docker/docker/nat"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
|
||||
shlex "github.com/flynn/go-shlex"
|
||||
)
|
||||
@ -42,17 +42,17 @@ func Convert(c *project.ServiceConfig) (*runconfig.Config, *runconfig.HostConfig
|
||||
WorkingDir: c.WorkingDir,
|
||||
}
|
||||
host_config := &runconfig.HostConfig{
|
||||
Memory: c.MemLimit,
|
||||
CpuShares: c.CpuShares,
|
||||
VolumesFrom: c.VolumesFrom,
|
||||
CapAdd: c.CapAdd,
|
||||
CapDrop: c.CapDrop,
|
||||
CpuShares: c.CpuShares,
|
||||
Privileged: c.Privileged,
|
||||
Binds: c.Volumes,
|
||||
Dns: dns,
|
||||
LogConfig: runconfig.LogConfig{
|
||||
Type: c.LogDriver,
|
||||
},
|
||||
Memory: c.MemLimit,
|
||||
NetworkMode: runconfig.NetworkMode(c.Net),
|
||||
ReadonlyRootfs: c.ReadOnly,
|
||||
PidMode: runconfig.PidMode(c.Pid),
|
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
@ -20,7 +19,7 @@ var (
|
||||
|
||||
type ProjectEvent struct {
|
||||
Event Event
|
||||
Service Service
|
||||
ServiceName string
|
||||
Data map[string]string
|
||||
}
|
||||
|
||||
@ -28,12 +27,11 @@ func NewProject(name string, factory ServiceFactory) *Project {
|
||||
return &Project{
|
||||
Name: name,
|
||||
configs: make(map[string]*ServiceConfig),
|
||||
Services: make(map[string]Service),
|
||||
factory: factory,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Project) createService(name string, config ServiceConfig) (Service, error) {
|
||||
func (p *Project) CreateService(name string, config ServiceConfig) (Service, error) {
|
||||
if p.EnvironmentLookup != nil {
|
||||
parsedEnv := make([]string, 0, len(config.Environment))
|
||||
|
||||
@ -55,17 +53,9 @@ func (p *Project) createService(name string, config ServiceConfig) (Service, err
|
||||
}
|
||||
|
||||
func (p *Project) AddConfig(name string, config *ServiceConfig) error {
|
||||
service, err := p.createService(name, *config)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to create service for %s : %v", name, err)
|
||||
return err
|
||||
}
|
||||
p.Notify(SERVICE_ADD, name, nil)
|
||||
|
||||
p.Notify(SERVICE_ADD, service, nil)
|
||||
|
||||
p.reload = append(p.reload, name)
|
||||
p.configs[name] = config
|
||||
p.Services[name] = service
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -88,24 +78,36 @@ func (p *Project) Load(bytes []byte) error {
|
||||
}
|
||||
|
||||
func (p *Project) Up() error {
|
||||
wrappers := make(map[string]*ServiceWrapper)
|
||||
wrappers := make(map[string]*serviceWrapper)
|
||||
|
||||
p.Notify(PROJECT_UP_START, nil, nil)
|
||||
|
||||
return p.startAll(wrappers)
|
||||
for name, _ := range p.configs {
|
||||
wrapper, err := newServiceWrapper(name, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wrappers[name] = wrapper
|
||||
}
|
||||
|
||||
func (p *Project) startAll(wrappers map[string]*ServiceWrapper) error {
|
||||
for _, name := range p.reload {
|
||||
wrappers[name] = NewServiceWrapper(name, p)
|
||||
p.Notify(PROJECT_UP_START, "", nil)
|
||||
|
||||
err := p.startAll(wrappers, 0)
|
||||
|
||||
if err == nil {
|
||||
p.Notify(PROJECT_UP_DONE, "", nil)
|
||||
}
|
||||
|
||||
p.reload = []string{}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Project) startAll(wrappers map[string]*serviceWrapper, level int) error {
|
||||
restart := false
|
||||
|
||||
if level > 0 {
|
||||
for _, wrapper := range wrappers {
|
||||
wrapper.Reset()
|
||||
if err := wrapper.Reset(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, wrapper := range wrappers {
|
||||
@ -132,85 +134,17 @@ func (p *Project) startAll(wrappers map[string]*ServiceWrapper) error {
|
||||
log.Errorf("Failed calling callback: %v", err)
|
||||
}
|
||||
}
|
||||
return p.startAll(wrappers)
|
||||
return p.startAll(wrappers, level+1)
|
||||
} else {
|
||||
return firstError
|
||||
}
|
||||
}
|
||||
|
||||
type ServiceWrapper struct {
|
||||
name string
|
||||
services map[string]Service
|
||||
service Service
|
||||
done sync.WaitGroup
|
||||
state ServiceState
|
||||
err error
|
||||
project *Project
|
||||
}
|
||||
|
||||
func NewServiceWrapper(name string, p *Project) *ServiceWrapper {
|
||||
wrapper := &ServiceWrapper{
|
||||
name: name,
|
||||
services: make(map[string]Service),
|
||||
service: p.Services[name],
|
||||
state: UNKNOWN,
|
||||
project: p,
|
||||
}
|
||||
return wrapper
|
||||
}
|
||||
|
||||
func (s *ServiceWrapper) Reset() {
|
||||
if s.err == ErrRestart {
|
||||
s.err = nil
|
||||
}
|
||||
s.done.Add(1)
|
||||
}
|
||||
|
||||
func (s *ServiceWrapper) Start(wrappers map[string]*ServiceWrapper) {
|
||||
defer s.done.Done()
|
||||
|
||||
if s.state == EXECUTED {
|
||||
return
|
||||
}
|
||||
|
||||
for _, link := range append(s.service.Config().Links, s.service.Config().VolumesFrom...) {
|
||||
name := strings.Split(link, ":")[0]
|
||||
if wrapper, ok := wrappers[name]; ok {
|
||||
if wrapper.Wait() == ErrRestart {
|
||||
s.project.Notify(PROJECT_RELOAD, wrapper.service, nil)
|
||||
s.err = ErrRestart
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Failed to find %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
s.state = EXECUTED
|
||||
|
||||
s.project.Notify(SERVICE_UP_START, s.service, nil)
|
||||
|
||||
s.err = s.service.Up()
|
||||
if s.err == ErrRestart {
|
||||
s.project.Notify(SERVICE_UP, s.service, nil)
|
||||
s.project.Notify(PROJECT_RELOAD_TRIGGER, s.service, nil)
|
||||
} else if s.err != nil {
|
||||
log.Errorf("Failed to start %s : %v", s.name, s.err)
|
||||
} else {
|
||||
s.project.Notify(SERVICE_UP, s.service, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ServiceWrapper) Wait() error {
|
||||
s.done.Wait()
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (p *Project) AddListener(c chan<- ProjectEvent) {
|
||||
p.listeners = append(p.listeners, c)
|
||||
}
|
||||
|
||||
func (p *Project) Notify(event Event, service Service, data map[string]string) {
|
||||
func (p *Project) Notify(event Event, serviceName string, data map[string]string) {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if data != nil {
|
||||
for k, v := range data {
|
||||
@ -233,16 +167,16 @@ func (p *Project) Notify(event Event, service Service, data map[string]string) {
|
||||
logf = log.Infof
|
||||
}
|
||||
|
||||
if service == nil {
|
||||
if serviceName == "" {
|
||||
logf("Project [%s]: %s %s", p.Name, event, buffer.Bytes())
|
||||
} else {
|
||||
logf("[%d/%d] [%s]: %s %s", p.upCount, len(p.Services), service.Name(), event, buffer.Bytes())
|
||||
logf("[%d/%d] [%s]: %s %s", p.upCount, len(p.configs), serviceName, event, buffer.Bytes())
|
||||
}
|
||||
|
||||
for _, l := range p.listeners {
|
||||
projectEvent := ProjectEvent{
|
||||
Event: event,
|
||||
Service: service,
|
||||
ServiceName: serviceName,
|
||||
Data: data,
|
||||
}
|
||||
// Don't ever block
|
86
Godeps/_workspace/src/github.com/rancherio/rancher-compose/librcompose/project/service-wrapper.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/rancherio/rancher-compose/librcompose/project/service-wrapper.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type serviceWrapper struct {
|
||||
name string
|
||||
service Service
|
||||
done sync.WaitGroup
|
||||
state ServiceState
|
||||
err error
|
||||
project *Project
|
||||
}
|
||||
|
||||
func newServiceWrapper(name string, p *Project) (*serviceWrapper, error) {
|
||||
wrapper := &serviceWrapper{
|
||||
name: name,
|
||||
state: UNKNOWN,
|
||||
project: p,
|
||||
}
|
||||
|
||||
return wrapper, wrapper.Reset()
|
||||
}
|
||||
|
||||
func (s *serviceWrapper) Reset() error {
|
||||
if s.state != EXECUTED {
|
||||
service, err := s.project.CreateService(s.name, *s.project.configs[s.name])
|
||||
if err != nil {
|
||||
log.Errorf("Failed to create service for %s : %v", s.name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
s.service = service
|
||||
}
|
||||
|
||||
if s.err == ErrRestart {
|
||||
s.err = nil
|
||||
}
|
||||
s.done.Add(1)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceWrapper) Start(wrappers map[string]*serviceWrapper) {
|
||||
defer s.done.Done()
|
||||
|
||||
if s.state == EXECUTED {
|
||||
return
|
||||
}
|
||||
|
||||
for _, link := range append(s.service.Config().Links, s.service.Config().VolumesFrom...) {
|
||||
name := strings.Split(link, ":")[0]
|
||||
if wrapper, ok := wrappers[name]; ok {
|
||||
if wrapper.Wait() == ErrRestart {
|
||||
s.project.Notify(PROJECT_RELOAD, wrapper.service.Name(), nil)
|
||||
s.err = ErrRestart
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Failed to find %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
s.state = EXECUTED
|
||||
|
||||
s.project.Notify(SERVICE_UP_START, s.service.Name(), nil)
|
||||
|
||||
s.err = s.service.Up()
|
||||
if s.err == ErrRestart {
|
||||
s.project.Notify(SERVICE_UP, s.service.Name(), nil)
|
||||
s.project.Notify(PROJECT_RELOAD_TRIGGER, s.service.Name(), nil)
|
||||
} else if s.err != nil {
|
||||
log.Errorf("Failed to start %s : %v", s.name, s.err)
|
||||
} else {
|
||||
s.project.Notify(SERVICE_UP, s.service.Name(), nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceWrapper) Wait() error {
|
||||
s.done.Wait()
|
||||
return s.err
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package project
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancherio/go-rancher/client"
|
||||
"gopkg.in/yaml.v2"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Event string
|
||||
@ -20,6 +21,7 @@ const (
|
||||
SERVICE_UP = Event("Started")
|
||||
|
||||
PROJECT_UP_START = Event("Starting project")
|
||||
PROJECT_UP_DONE = Event("Project started")
|
||||
PROJECT_RELOAD = Event("Reloading project")
|
||||
PROJECT_RELOAD_TRIGGER = Event("Triggering project reload")
|
||||
)
|
||||
@ -168,7 +170,6 @@ type Project struct {
|
||||
Name string
|
||||
configs map[string]*ServiceConfig
|
||||
reload []string
|
||||
Services map[string]Service
|
||||
file string
|
||||
content []byte
|
||||
client *client.RancherClient
|
@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/rancherio/os/util"
|
||||
|
@ -1,7 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
)
|
||||
|
||||
func NewConfig() *Config {
|
||||
@ -179,7 +179,7 @@ func NewConfig() *Config {
|
||||
SCOPE: SYSTEM,
|
||||
}),
|
||||
Volumes: []string{
|
||||
"/var/lib/rancher:/var/lib/rancher",
|
||||
"/var/lib/rancher/conf:/var/lib/rancher/conf",
|
||||
"/var/lib/docker:/var/lib/docker",
|
||||
"/var/lib/system-docker:/var/lib/system-docker",
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
package config
|
||||
|
||||
import "github.com/rancherio/rancher-compose/project"
|
||||
import "github.com/rancherio/rancher-compose/librcompose/project"
|
||||
|
||||
const (
|
||||
DEFAULT_IMAGE_VERSION = "v0.3.0-rc2"
|
||||
|
@ -18,8 +18,8 @@ import (
|
||||
dockerClient "github.com/fsouza/go-dockerclient"
|
||||
"github.com/rancherio/os/config"
|
||||
"github.com/rancherio/os/util"
|
||||
"github.com/rancherio/rancher-compose/docker"
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/docker"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
)
|
||||
|
||||
type Container struct {
|
||||
@ -209,7 +209,7 @@ func (c *Container) parseService() {
|
||||
}
|
||||
|
||||
if c.requiresUserDocker() {
|
||||
c.addLink("userdockerwait")
|
||||
c.addLink("dockerwait")
|
||||
} else if c.ContainerCfg.Service.Image != "" {
|
||||
client, err := NewClient(c.dockerHost)
|
||||
if err != nil {
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/rancherio/os/config"
|
||||
"github.com/rancherio/os/util"
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
)
|
||||
|
||||
type ContainerFactory struct {
|
||||
@ -39,7 +39,7 @@ func (c *containerBasedService) Up() error {
|
||||
|
||||
var event project.Event
|
||||
|
||||
c.project.Notify(project.CONTAINER_STARTING, c, map[string]string{})
|
||||
c.project.Notify(project.CONTAINER_STARTING, c.name, map[string]string{})
|
||||
|
||||
if fakeCreate {
|
||||
event = project.CONTAINER_CREATED
|
||||
@ -60,7 +60,7 @@ func (c *containerBasedService) Up() error {
|
||||
}
|
||||
|
||||
if container.Container != nil {
|
||||
c.project.Notify(event, c, map[string]string{
|
||||
c.project.Notify(event, c.name, map[string]string{
|
||||
project.CONTAINER_ID: container.Container.ID,
|
||||
})
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/rancherio/os/config"
|
||||
"github.com/rancherio/os/util"
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
)
|
||||
|
||||
type configEnvironment struct {
|
||||
@ -117,7 +117,7 @@ func RunServices(name string, cfg *config.Config, configs map[string]*project.Se
|
||||
|
||||
go func() {
|
||||
for event := range projectEvents {
|
||||
if event.Event == project.CONTAINER_STARTED && event.Service.Name() == "network" {
|
||||
if event.Event == project.CONTAINER_STARTED && event.ServiceName == "network" {
|
||||
network = true
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/rancherio/os/config"
|
||||
"github.com/rancherio/os/docker"
|
||||
"github.com/rancherio/os/util"
|
||||
"github.com/rancherio/rancher-compose/project"
|
||||
"github.com/rancherio/rancher-compose/librcompose/project"
|
||||
)
|
||||
|
||||
const boot2dockerMagic = "boot2docker, please format-me"
|
||||
|
Loading…
Reference in New Issue
Block a user