func TestRunServiceNoDataContainer(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } srv.Service.AutoData = false if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } if n := util.HowManyContainersRunning(name, def.TypeService); n != 1 { t.Fatalf("expecting 1 service container running, got %v", n) } if n := util.HowManyContainersExisting(name, def.TypeData); n != 0 { t.Fatalf("expecting no dependent data containers, got %v", n) } tests.RemoveAllContainers() }
func TestLoadServiceDefinition(t *testing.T) { var e error srv, e = loaders.LoadServiceDefinition(servName, true, 1) if e != nil { log.Error(e) tests.IfExit(e) } if srv.Name != servName { log.WithFields(log.Fields{ "expected": servName, "got": srv.Name, }).Error("Improper name on load") } if srv.Service.Name != servName { log.WithFields(log.Fields{ "expected": servName, "got": srv.Service.Name, }).Error("Improper service name on load") tests.IfExit(e) } if !srv.Service.AutoData { log.Error("data_container not properly read on load") tests.IfExit(e) } if srv.Operations.DataContainerName == "" { log.Error("data_container_name not set") tests.IfExit(e) } }
func RmService(do *definitions.Do) error { for _, servName := range do.Args { service, err := loaders.LoadServiceDefinition(servName, false, do.Operations.ContainerNumber) if err != nil { return err } if IsServiceExisting(service.Service, service.Operations) { err = perform.DockerRemove(service.Service, service.Operations, do.RmD) if err != nil { return err } } if do.File { oldFile := util.GetFileByNameAndType("services", servName) if err != nil { return err } oldFile = path.Join(ServicesPath, oldFile) + ".toml" logger.Printf("Removing file =>\t\t%s\n", oldFile) if err := os.Remove(oldFile); err != nil { return err } } } do.Result = "success" return nil }
func TestLoadServiceDefinition(t *testing.T) { var e error srv, e = loaders.LoadServiceDefinition(servName, true, 1) if e != nil { logger.Errorln(e) tests.IfExit(e) } if srv.Name != servName { logger.Errorf("FAILURE: improper name on LOAD. expected: %s\tgot: %s\n", servName, srv.Name) } if srv.Service.Name != servName { logger.Errorf("FAILURE: improper service name on LOAD. expected: %s\tgot: %s\n", servName, srv.Service.Name) tests.IfExit(e) } if !srv.Service.AutoData { logger.Errorf("FAILURE: data_container not properly read on LOAD.\n") tests.IfExit(e) } if srv.Operations.DataContainerName == "" { logger.Errorf("FAILURE: data_container_name not set.\n") tests.IfExit(e) } }
func TestStopDataContainer(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } srv.Operations.SrvContainerName = srv.Operations.DataContainerName if err := DockerStop(srv.Service, srv.Operations, 5); err == nil { t.Fatalf("expected stop to fail, got %v", err) } tests.RemoveAllContainers() }
func LogsService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } return LogsServiceByService(service.Service, service.Operations, do.Follow, do.Tail) }
func TestDataContainerExistsAfterRemove(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } srv.Operations.SrvContainerName = srv.Operations.DataContainerName if _, exists := DataContainerExists(srv.Operations); exists == false { t.Fatalf("expecting service container exists, got false") } tests.RemoveContainer(name, def.TypeData, number) if _, exists := DataContainerExists(srv.Operations); exists == true { t.Fatalf("expecting service container not existing after remove, got true") } tests.RemoveAllContainers() }
func ImportService(do *definitions.Do) error { fileName := filepath.Join(ServicesPath, do.Name) if filepath.Ext(fileName) == "" { fileName = fileName + ".toml" } var err error if logger.Level > 0 { err = ipfs.GetFromIPFS(do.Hash, fileName, "", logger.Writer) } else { err = ipfs.GetFromIPFS(do.Hash, fileName, "", bytes.NewBuffer([]byte{})) } if err != nil { return err //return fmt.Errorf("I do not know how to get that file. Sorry. %v\n", err) } _, err = loaders.LoadServiceDefinition(do.Name, false, 0) //XXX add protections? if err != nil { return fmt.Errorf("Your service defintion file looks improperly formatted and will not marshal.") } do.Result = "success" return nil }
func TestContainerRunningBadName(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } if _, exists := ContainerRunning(srv.Operations); exists == false { t.Fatalf("expecting service container running, got false") } srv.Operations.SrvContainerName = "random-bad-name" if _, exists := ContainerRunning(srv.Operations); exists == true { t.Fatalf("expecting data container not running, got true") } tests.RemoveAllContainers() }
func TestExecServiceAfterRunServiceWithPublishedPorts2(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } srv.Operations.PublishAllPorts = true srv.Operations.Interactive = true srv.Operations.Args = []string{"uptime"} if err := DockerExecService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected exec container created, got %v", err) } if n := util.HowManyContainersRunning(name, def.TypeService); n != 1 { t.Fatalf("expecting 1 service container running, got %v", n) } if n := util.HowManyContainersExisting(name, def.TypeData); n != 1 { t.Fatalf("expecting 1 dependent data container, got %v", n) } tests.RemoveAllContainers() }
func TestExecServiceAfterRunService(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } srv.Operations.Interactive = true srv.Operations.Args = []string{"uptime"} if err := DockerExecService(srv.Service, srv.Operations); err == nil { t.Fatalf("expected failure due to unpublished ports, got %v", err) } tests.RemoveAllContainers() }
func ExecService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } util.Merge(service.Operations, do.Operations) // Get the main service container name, check if it's running. main := util.FindServiceContainer(do.Name, do.Operations.ContainerNumber, false) if main != nil { if service.Service.ExecHost == "" { log.Info("exec_host not found in service definition file") log.WithField("service", do.Name).Info("May not be able to communicate with the service") } else { service.Service.Environment = append(service.Service.Environment, fmt.Sprintf("%s=%s", service.Service.ExecHost, do.Name)) } // Use service's short name as a link alias. service.Service.Links = append(service.Service.Links, fmt.Sprintf("%s:%s", main.FullName, do.Name)) } // Override links on the command line. if len(do.Links) > 0 { service.Service.Links = do.Links } return perform.DockerExecService(service.Service, service.Operations) }
func ImportService(do *definitions.Do) error { fileName := filepath.Join(ServicesPath, do.Name) if filepath.Ext(fileName) == "" { fileName = fileName + ".toml" } var err error if log.GetLevel() > 0 { err = ipfs.GetFromIPFS(do.Hash, fileName, "", os.Stdout) } else { err = ipfs.GetFromIPFS(do.Hash, fileName, "", bytes.NewBuffer([]byte{})) } if err != nil { return err } _, err = loaders.LoadServiceDefinition(do.Name, false, 0) //XXX add protections? if err != nil { return fmt.Errorf("Your service definition file looks improperly formatted and will not marshal.") } do.Result = "success" return nil }
func TestChainGraduate(t *testing.T) { do := def.NowDo() do.Name = chainName if err := GraduateChain(do); err != nil { t.Fatalf("expected chain to graduate, got %v", err) } srvDef, err := loaders.LoadServiceDefinition(chainName, false, 1) if err != nil { t.Fatalf("expected service definition to be loaded") } if image := path.Join(ver.ERIS_REG_DEF, ver.ERIS_IMG_DB); srvDef.Service.Image != image { t.Fatalf("bad image on graduate, expected %s, got: %s", image, srvDef.Service.Image) } if srvDef.Service.Command != loaders.ErisChainStart { t.Fatalf("improper service command on graduate, expected %s, got %s", loaders.ErisChainStart, srvDef.Service.Command) } if !srvDef.Service.AutoData { t.Fatalf("improper service autodata value on graduate, expected %t, got %t", true, srvDef.Service.AutoData) } if len(srvDef.Dependencies.Services) != 1 { t.Fatalf("improper service deps on graduate, expected: [%q], got %s", "keys", srvDef.Dependencies.Services) } }
func TestChainGraduate(t *testing.T) { do := def.NowDo() do.Name = chainName logger.Infof("Graduate chain (from tests) =>\t%s\n", do.Name) if err := GraduateChain(do); err != nil { fatal(t, err) } srvDef, err := loaders.LoadServiceDefinition(chainName, false, 1) if err != nil { fatal(t, err) } image := "eris/erisdb:" + version.VERSION if srvDef.Service.Image != image { fatal(t, fmt.Errorf("FAILURE: improper service image on GRADUATE. expected: %s\tgot: %s\n", image, srvDef.Service.Image)) } if srvDef.Service.Command != loaders.ErisChainStart { fatal(t, fmt.Errorf("FAILURE: improper service command on GRADUATE. expected: %s\tgot: %s\n", loaders.ErisChainStart, srvDef.Service.Command)) } if !srvDef.Service.AutoData { fatal(t, fmt.Errorf("FAILURE: improper service autodata on GRADUATE. expected: %t\tgot: %t\n", true, srvDef.Service.AutoData)) } if len(srvDef.Dependencies.Services) != 1 { fatal(t, fmt.Errorf("FAILURE: improper service deps on GRADUATE. expected: [\"keys\"]\tgot: %s\n", srvDef.Dependencies.Services)) } }
// boot chain dependencies // TODO: this currently only supports simple services (with no further dependencies) func bootDependencies(chain *definitions.Chain, do *definitions.Do) error { if chain.Dependencies != nil { name := do.Name logger.Infoln("Booting chain dependencies", chain.Dependencies.Services, chain.Dependencies.Chains) for _, srvName := range chain.Dependencies.Services { do.Name = srvName srv, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } // Start corresponding service. if !services.IsServiceRunning(srv.Service, srv.Operations) { name := strings.ToUpper(do.Name) logger.Infof("%s is not running. Starting now. Waiting for %s to become available \n", name, name) if err = perform.DockerRunService(srv.Service, srv.Operations); err != nil { return err } } } do.Name = name // undo side effects for _, chainName := range chain.Dependencies.Chains { chn, err := loaders.LoadChainDefinition(chainName, false, do.Operations.ContainerNumber) if err != nil { return err } if !IsChainRunning(chn) { return fmt.Errorf("chain %s depends on chain %s but %s is not running", chain.Name, chainName, chainName) } } } return nil }
func TestExecServiceBadCommandLine(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } srv.Operations.Interactive = false srv.Operations.Args = []string{"/bad/command/line"} if err := DockerExecService(srv.Service, srv.Operations); err == nil { t.Fatalf("expected failure, got %v", err) } if n := util.HowManyContainersRunning(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 service container running, got %v", n) } if n := util.HowManyContainersExisting(name, def.TypeData); n != 1 { t.Fatalf("expecting 1 dependent data container, got %v", n) } tests.RemoveAllContainers() }
func InspectService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } err = InspectServiceByService(service.Service, service.Operations, do.Args[0]) if err != nil { return err } return nil }
func UpdateService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } err = perform.DockerRebuild(service.Service, service.Operations, do.Pull, do.Timeout) if err != nil { return err } do.Result = "success" return nil }
func PortsService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } if IsServiceExisting(service.Service, service.Operations) { logger.Debugf("Service exists, getting port mapping.\n") return perform.PrintPortMappings(service.Operations.SrvContainerID, do.Args) } return nil }
//checks that a service is running. if not, tells user to start it func EnsureRunning(do *definitions.Do) error { srv, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } if !IsServiceRunning(srv.Service, srv.Operations) { return ErrServiceNotRunning } else { logger.Infof("%s is running.\n", strings.ToUpper(do.Name)) } return nil }
func TestRunServiceTwoServicesPublishedPorts(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv1, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("1. could not load service definition %v", err) } if err := DockerRunService(srv1.Service, srv1.Operations); err != nil { t.Fatalf("1. expected service container created, got %v", err) } srv2, err := loaders.LoadServiceDefinition(name, true, number+1) if err != nil { t.Fatalf("2. could not load service definition %v", err) } srv2.Operations.PublishAllPorts = true if err := DockerRunService(srv2.Service, srv2.Operations); err != nil { t.Fatalf("2. expected service container created, got %v", err) } if n := util.HowManyContainersRunning(name, def.TypeService); n != 2 { t.Fatalf("expecting 2 services running, got %v", n) } if n := util.HowManyContainersExisting(name, def.TypeData); n != 2 { t.Fatalf("expecting 2 dependent data container, got %v", n) } tests.RemoveAllContainers() }
// EnsureRunning checks if a service is running and starts it if not // TODO: ping all exposed ports until at least one is available (issue #149) // NOTE: does not accept ENV vars func EnsureRunning(do *definitions.Do) error { srv, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } var id string if !IsServiceRunning(srv.Service, srv.Operations) { name := strings.ToUpper(do.Name) logger.Infof("%s is not running. Starting now. Waiting for %s to become available \n", name, name) if id, err = perform.DockerRun(srv.Service, srv.Operations); err != nil { return err } // TODO: to do this right we have to get the bound port // which might be randomly assigned! cont, err := util.DockerClient.InspectContainer(id) if err != nil { return err } exposedPorts := cont.NetworkSettings.Ports MAIN_LOOP: for { // give it a half second and then try all the ports var endpoint string time.Sleep(500 * time.Millisecond) for _, ep := range exposedPorts { for _, p := range ep { endpoint = fmt.Sprintf("%s:%s", p.HostIP, p.HostPort) if _, err := net.Dial("tcp", endpoint); err != nil { time.Sleep(500 * time.Millisecond) } } if _, err := http.Post(endpoint, "", nil); err != nil { time.Sleep(500 * time.Millisecond) } if _, err := http.Get(endpoint); err != nil { time.Sleep(500 * time.Millisecond) } } time.Sleep(500 * time.Millisecond) break MAIN_LOOP } } else { logger.Infof("%s is running.\n", strings.ToUpper(do.Name)) } return nil }
//checks that a service is running. if not, tells user to start it func EnsureRunning(do *definitions.Do) error { srv, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } if !IsServiceRunning(srv.Service, srv.Operations) { e := fmt.Sprintf("The requested service is not running, start it with `eris services start %s`", do.Name) return errors.New(e) } else { logger.Infof("%s is running.\n", strings.ToUpper(do.Name)) } return nil }
func TestRemoveWithoutData(t *testing.T) { const ( name = "ipfs" number = 99 ) if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 containers, got %v", n) } srv, err := loaders.LoadServiceDefinition(name, true, number) if err != nil { t.Fatalf("could not load service definition %v", err) } if err := DockerRunService(srv.Service, srv.Operations); err != nil { t.Fatalf("expected service container created, got %v", err) } if err := DockerStop(srv.Service, srv.Operations, 5); err != nil { t.Fatal("expected service container stopped, got %v", err) } if n := util.HowManyContainersExisting(name, def.TypeService); n != 1 { t.Fatalf("expecting 1 service container running (before removal), got %v", n) } if err := DockerRemove(srv.Service, srv.Operations, false, true); err != nil { t.Fatal("expected service container removed, got %v", err) } if n := util.HowManyContainersExisting(name, def.TypeService); n != 0 { t.Fatalf("expecting 0 service container running (after removal), got %v", n) } srv.Operations.SrvContainerName = srv.Operations.DataContainerName if n := util.HowManyContainersExisting(name, def.TypeData); n != 1 { t.Fatalf("expecting 1 data container existing (before removal), got %v", n) } if err := DockerRemove(srv.Service, srv.Operations, false, true); err != nil { t.Fatal("expected service container removed, got %v", err) } if n := util.HowManyContainersExisting(name, def.TypeData); n != 0 { t.Fatalf("expecting 0 data container running (after removal), got %v", n) } tests.RemoveAllContainers() }
func ExecService(do *definitions.Do) error { service, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } if IsServiceExisting(service.Service, service.Operations) { return ExecServiceByService(service.Service, service.Operations, do.Args, do.Interactive) } else { return fmt.Errorf("Services does not exist. Please start the service container with eris services start %s.\n", do.Name) } return nil }
// TODO: test this recursion and service deps generally func BuildServicesGroup(srvName string, cNum int, services ...*definitions.ServiceDefinition) ([]*definitions.ServiceDefinition, error) { logger.Debugf("BuildServicesGroup for =>\t%s:%d\n", srvName, len(services)) srv, err := loaders.LoadServiceDefinition(srvName, false, cNum) if err != nil { return nil, err } for _, sName := range srv.ServiceDeps { logger.Debugf("Found service dependency =>\t%s\n", sName) s, e := BuildServicesGroup(sName, cNum) if e != nil { return nil, e } services = append(services, s...) } services = append(services, srv) return services, nil }
func StartChain(do *definitions.Do) error { logger.Infoln("Ensuring Key Server is Started.") //should it take a flag? keys server may be running another cNum // XXX: currently we don't use or need a key server. // plus this should be specified in a service def anyways keysService, err := loaders.LoadServiceDefinition("keys", false, 1) if err != nil { return err } err = perform.DockerRun(keysService.Service, keysService.Operations) if err != nil { return err } chain, err := loaders.LoadChainDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { logger.Infoln("Cannot start a chain I cannot find.") do.Result = "no file" return nil } if chain.Name == "" { logger.Infoln("Cannot start a chain without a name.") do.Result = "no name" return nil } chain.Service.Command = loaders.ErisChainStart if do.Run { chain.Service.Command = loaders.ErisChainStartApi } util.OverWriteOperations(chain.Operations, do.Operations) chain.Service.Environment = append(chain.Service.Environment, "CHAIN_ID="+chain.ChainID) logger.Infof("StartChainRaw to DockerRun =>\t%s\n", chain.Service.Name) logger.Debugf("\twith ChainID =>\t\t%v\n", chain.ChainID) logger.Debugf("\twith Environment =>\t%v\n", chain.Service.Environment) logger.Debugf("\twith AllPortsPublshd =>\t%v\n", chain.Operations.PublishAllPorts) if err := perform.DockerRun(chain.Service, chain.Operations); err != nil { do.Result = "error" return err } return nil }
func ImportAction(do *definitions.Do) error { if do.Name == "" { do.Name = strings.Join(do.Operations.Args, "_") } fileName := filepath.Join(ActionsPath, strings.Join(do.Operations.Args, " ")) if filepath.Ext(fileName) == "" { fileName = fileName + ".toml" } s := strings.Split(do.Path, ":") if s[0] == "ipfs" { var err error //unset 1 as default ContainerNumber, let it take flag? ipfsService, err := loaders.LoadServiceDefinition("ipfs", false, 1) if err != nil { return err } ipfsService.Operations.ContainerType = definitions.TypeService err = perform.DockerRunService(ipfsService.Service, ipfsService.Operations) if err != nil { return err } if log.GetLevel() > 0 { err = ipfs.GetFromIPFS(s[1], fileName, "", os.Stdout) } else { err = ipfs.GetFromIPFS(s[1], fileName, "", bytes.NewBuffer([]byte{})) } if err != nil { return err } return nil } if strings.Contains(s[0], "github") { log.Warn("https://twitter.com/ryaneshea/status/595957712040628224") return nil } log.Warn("Failed to get that file. Sorry") return nil }
//checks that a service is running. if not, tells user to start it func EnsureRunning(do *definitions.Do) error { if os.Getenv("ERIS_SKIP_ENSURE") != "" { return nil } srv, err := loaders.LoadServiceDefinition(do.Name, false, do.Operations.ContainerNumber) if err != nil { return err } if !IsServiceRunning(srv.Service, srv.Operations) { e := fmt.Sprintf("The requested service is not running, start it with `eris services start %s`", do.Name) return errors.New(e) } else { log.WithField("=>", strings.ToUpper(do.Name)).Info("Service is running") } return nil }