From 36bdb8b0ceab08dfac00192282dc776df7d29c37 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 14:07:33 +0700 Subject: [PATCH 01/22] Add function WaitForContainerStatus --- container/container.go | 23 +++++++++++++++++++ container/container_test.go | 45 +++++++++---------------------------- container/type.go | 14 ++++++++++++ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/container/container.go b/container/container.go index 2fa95b983..1de96deda 100644 --- a/container/container.go +++ b/container/container.go @@ -2,6 +2,7 @@ package container import ( "context" + "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -48,3 +49,25 @@ func ContainerStatus(namespace []string) (status StatusType, err error) { } return } + +// WaitForContainerStatus wait for the container to have the provided status until it reach the timeout +func WaitForContainerStatus(namespace []string, status StatusType, timeout time.Duration) (err error) { + start := time.Now() + for { + currentStatus, err := ContainerStatus(namespace) + if err != nil { + return err + } + if currentStatus == status { + return nil + } + diff := time.Now().Sub(start) + if diff.Nanoseconds() >= int64(timeout) { + return &TimeoutError{ + duration: timeout, + name: Namespace(namespace), + } + } + time.Sleep(500 * time.Millisecond) + } +} diff --git a/container/container_test.go b/container/container_test.go index 955a728a4..a4953a520 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -1,7 +1,6 @@ package container import ( - "errors" "fmt" "testing" "time" @@ -18,7 +17,7 @@ func TestFindContainer(t *testing.T) { namespace := []string{"TestFindContainer"} startTestService(namespace) defer StopService(namespace) - <-WaitContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING, time.Minute) container, err := FindContainer(namespace) assert.Nil(t, err) assert.NotEqual(t, "", container.ID) @@ -43,7 +42,7 @@ func TestContainerStatusRunning(t *testing.T) { namespace := []string{"TestContainerStatusRunning"} startTestService(namespace) defer StopService(namespace) - <-WaitContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING, time.Minute) status, err := ContainerStatus(namespace) assert.Nil(t, err) assert.Equal(t, status, RUNNING) @@ -52,10 +51,10 @@ func TestContainerStatusRunning(t *testing.T) { func TestContainerStatusStopped(t *testing.T) { namespace := []string{"TestContainerStatusStopped"} startTestService(namespace) - <-WaitContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING, time.Minute) fmt.Println("wait for running") StopService(namespace) - <-WaitContainerStatus(namespace, STOPPED, time.Minute) + WaitForContainerStatus(namespace, STOPPED, time.Minute) fmt.Println("wait for stop") status, err := ContainerStatus(namespace) assert.Nil(t, err) @@ -66,7 +65,7 @@ func TestWaitForContainerRunning(t *testing.T) { namespace := []string{"TestWaitForContainerRunning"} startTestService(namespace) defer StopService(namespace) - err := <-WaitContainerStatus(namespace, RUNNING, time.Minute) + err := WaitForContainerStatus(namespace, RUNNING, time.Minute) assert.Nil(t, err) } @@ -74,42 +73,18 @@ func TestWaitForContainerTimeout(t *testing.T) { namespace := []string{"TestWaitForContainerTimeout"} startTestService(namespace) defer StopService(namespace) - err := <-WaitContainerStatus(namespace, RUNNING, time.Nanosecond) + err := WaitForContainerStatus(namespace, RUNNING, time.Nanosecond) assert.NotNil(t, err) + _, ok := err.(*TimeoutError) + assert.True(t, ok) } func TestWaitForContainerStopped(t *testing.T) { namespace := []string{"TestWaitForContainerStopped"} startTestService(namespace) - <-WaitContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING, time.Minute) StopService(namespace) - err := <-WaitContainerStatus(namespace, STOPPED, time.Minute) + err := WaitForContainerStatus(namespace, STOPPED, time.Minute) assert.Nil(t, err) } - -// WaitContainerStatus wait for the container to have the provided status until it reach the timeout -func WaitContainerStatus(namespace []string, status StatusType, timeout time.Duration) (wait chan error) { - start := time.Now() - wait = make(chan error, 1) - go func() { - for { - currentStatus, err := ContainerStatus(namespace) - if err != nil { - wait <- err - return - } - if currentStatus == status { - close(wait) - return - } - diff := time.Now().Sub(start) - if diff.Nanoseconds() >= int64(timeout) { - wait <- errors.New("Wait too long for the container, timeout reached") - return - } - time.Sleep(500 * time.Millisecond) - } - }() - return -} diff --git a/container/type.go b/container/type.go index 62de9dedb..be76abae8 100644 --- a/container/type.go +++ b/container/type.go @@ -1,5 +1,9 @@ package container +import ( + "time" +) + // StatusType of the service type StatusType uint @@ -8,3 +12,13 @@ const ( STOPPED StatusType = 1 RUNNING StatusType = 2 ) + +// TimeoutError represents an error of timeout +type TimeoutError struct { + duration time.Duration + name string +} + +func (e *TimeoutError) Error() string { + return "Timeout reached after " + e.duration.String() + " for ressource " + e.name +} From e865379f94e0add5d403ea50e2250c18f0fd2544 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 14:59:16 +0700 Subject: [PATCH 02/22] Make daemon start and stop blockable --- daemon/start.go | 10 ++++++++-- daemon/start_test.go | 2 +- daemon/stop.go | 7 ++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/daemon/start.go b/daemon/start.go index 56dbc55b1..063bc4565 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -2,6 +2,7 @@ package daemon import ( "path/filepath" + "time" "github.com/mesg-foundation/core/config" "github.com/mesg-foundation/core/container" @@ -21,12 +22,17 @@ func Start() (serviceID string, err error) { if err != nil { return } - return container.StartService(serviceSpec(sharedNetworkID)) + serviceID, err = container.StartService(serviceSpec(sharedNetworkID)) + if err != nil { + return + } + err = container.WaitForContainerStatus(Namespace(), container.RUNNING, time.Minute) + return } func serviceSpec(networkID string) container.ServiceOptions { return container.ServiceOptions{ - Namespace: []string{name}, + Namespace: Namespace(), Image: viper.GetString(config.DaemonImage), Env: []string{ "MESG.PATH=/mesg", diff --git a/daemon/start_test.go b/daemon/start_test.go index 6bf00efc7..02f96c602 100644 --- a/daemon/start_test.go +++ b/daemon/start_test.go @@ -24,7 +24,7 @@ func startForTest() { panic(err) } _, err = container.StartService(container.ServiceOptions{ - Namespace: []string{name}, + Namespace: Namespace(), Image: "nginx", NetworksID: []string{sharedNetworkID}, }) diff --git a/daemon/stop.go b/daemon/stop.go index 0726b45f3..6e4391e56 100644 --- a/daemon/stop.go +++ b/daemon/stop.go @@ -1,6 +1,10 @@ package daemon -import "github.com/mesg-foundation/core/container" +import ( + "time" + + "github.com/mesg-foundation/core/container" +) // Stop the daemon docker func Stop() (err error) { @@ -12,5 +16,6 @@ func Stop() (err error) { if err != nil { return } + err = container.WaitForContainerStatus(Namespace(), container.STOPPED, time.Minute) return } From a74d343f578bf4a9c88425dd6eeb36892b6b5309 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 14:59:27 +0700 Subject: [PATCH 03/22] Update command daemon start and stop --- cmd/daemon/start.go | 5 ++++- cmd/daemon/stop.go | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index e408087c3..35849f233 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/logrusorgru/aurora" + "github.com/mesg-foundation/core/cmd/utils" "github.com/mesg-foundation/core/daemon" "github.com/spf13/cobra" ) @@ -26,10 +27,12 @@ func startHandler(cmd *cobra.Command, args []string) { fmt.Println(aurora.Green("Daemon is running")) return } + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Daemon is starting..."}) _, err = daemon.Start() + s.Stop() if err != nil { fmt.Println(aurora.Red(err)) return } - fmt.Println(aurora.Green("Daemon is starting")) + fmt.Println(aurora.Green("Daemon is running")) } diff --git a/cmd/daemon/stop.go b/cmd/daemon/stop.go index b08495c24..2f384c42c 100644 --- a/cmd/daemon/stop.go +++ b/cmd/daemon/stop.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/logrusorgru/aurora" + "github.com/mesg-foundation/core/cmd/utils" "github.com/mesg-foundation/core/daemon" "github.com/spf13/cobra" ) @@ -17,10 +18,12 @@ var Stop = &cobra.Command{ } func stopHandler(cmd *cobra.Command, args []string) { + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Daemon is stopping..."}) err := daemon.Stop() + s.Stop() if err != nil { fmt.Println(aurora.Red(err)) return } - fmt.Println(aurora.Green("Daemon is stopping")) + fmt.Println(aurora.Green("Daemon is stopped")) } From ead3fd920cd2829571547f98ed9c6799e395539b Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 15:23:44 +0700 Subject: [PATCH 04/22] Make service start and stop blocking --- service/start.go | 33 ++++++++++++++++++++++++++------- service/start_test.go | 18 ++++++++++++++++++ service/stop.go | 31 ++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/service/start.go b/service/start.go index 798c17b84..841f48deb 100644 --- a/service/start.go +++ b/service/start.go @@ -3,6 +3,8 @@ package service import ( "errors" "strings" + "sync" + "time" "github.com/mesg-foundation/core/config" "github.com/mesg-foundation/core/container" @@ -26,18 +28,29 @@ func (service *Service) Start() (serviceIDs []string, err error) { return } serviceIDs = make([]string, len(service.GetDependencies())) + var mutex sync.Mutex i := 0 + var wg sync.WaitGroup for name, dependency := range service.GetDependencies() { - serviceIDs[i], err = dependency.Start(service, dependencyDetails{ + d := dependencyDetails{ namespace: service.namespace(), dependencyName: name, serviceName: service.Name, - }, networkID) - i++ - if err != nil { - break } + wg.Add(1) + go func(service *Service, d dependencyDetails, name string, i int) { + serviceID, errStart := dependency.Start(service, d, networkID) + mutex.Lock() + serviceIDs[i] = serviceID + if errStart != nil && err == nil { + err = errStart + } + mutex.Unlock() + wg.Done() + }(service, d, name, i) + i++ } + wg.Wait() // Disgrasfully close the service because there is an error if err != nil { service.Stop() @@ -60,8 +73,9 @@ func (dependency *Dependency) Start(service *Service, details dependencyDetails, if err != nil { return } - return container.StartService(container.ServiceOptions{ - Namespace: []string{details.namespace, details.dependencyName}, + namespace := []string{details.namespace, details.dependencyName} //TODO: refacto namespace + serviceID, err = container.StartService(container.ServiceOptions{ + Namespace: namespace, Labels: map[string]string{ "mesg.service": details.serviceName, }, @@ -78,4 +92,9 @@ func (dependency *Dependency) Start(service *Service, details dependencyDetails, Ports: extractPorts(dependency), NetworksID: []string{networkID, sharedNetworkID}, }) + if err != nil { + return + } + err = container.WaitForContainerStatus(namespace, container.RUNNING, time.Minute) //TODO: be careful with timeout + return } diff --git a/service/start_test.go b/service/start_test.go index 56159978b..e0456985a 100644 --- a/service/start_test.go +++ b/service/start_test.go @@ -24,6 +24,24 @@ func TestStartService(t *testing.T) { service.Stop() } +func TestStartWith2Dependencies(t *testing.T) { + service := &Service{ + Name: "TestStartWith2Dependencies", + Dependencies: map[string]*Dependency{ + "test": &Dependency{ + Image: "nginx", + }, + "test2": &Dependency{ + Image: "nginx", + }, + }, + } + servicesID, err := service.Start() + assert.Nil(t, err) + assert.Equal(t, 2, len(servicesID)) + service.Stop() +} + func TestStartAgainService(t *testing.T) { service := &Service{ Name: "TestStartAgainService", diff --git a/service/stop.go b/service/stop.go index 2db4c4517..bdd853213 100644 --- a/service/stop.go +++ b/service/stop.go @@ -1,6 +1,9 @@ package service import ( + "sync" + "time" + "github.com/mesg-foundation/core/container" ) @@ -22,20 +25,34 @@ func (service *Service) Stop() (err error) { // StopDependencies stops all dependencies func (service *Service) StopDependencies() (err error) { + var mutex sync.Mutex + var wg sync.WaitGroup for name, dependency := range service.GetDependencies() { - err = dependency.Stop(service.namespace(), name) - if err != nil { - return - } + wg.Add(1) + go func(d *Dependency, name string, dependencyName string) { + errStop := d.Stop(name, dependencyName) + mutex.Lock() + if errStop != nil && err == nil { + err = errStop + } + mutex.Unlock() + wg.Done() + }(dependency, service.namespace(), name) } + wg.Wait() return } // Stop a dependency -func (dependency *Dependency) Stop(namespace string, dependencyName string) (err error) { - if !dependency.IsRunning(namespace, dependencyName) { +func (dependency *Dependency) Stop(name string, dependencyName string) (err error) { + if !dependency.IsRunning(name, dependencyName) { + return + } + namespace := []string{name, dependencyName} //TODO: refacto namespace + err = container.StopService(namespace) + if err != nil { return } - err = container.StopService([]string{namespace, dependencyName}) + err = container.WaitForContainerStatus(namespace, container.STOPPED, time.Minute) //TODO: be careful with timeout return } From 030cd7284317b1a904678992cf67f38e969fc84f Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 15:24:04 +0700 Subject: [PATCH 05/22] Improve service command --- cmd/service/start.go | 5 ++++- cmd/service/stop.go | 3 +++ cmd/service/test.go | 13 ++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cmd/service/start.go b/cmd/service/start.go index a32007866..5baa3427d 100644 --- a/cmd/service/start.go +++ b/cmd/service/start.go @@ -7,6 +7,7 @@ import ( "github.com/mesg-foundation/core/api/core" "github.com/logrusorgru/aurora" + "github.com/mesg-foundation/core/cmd/utils" "github.com/spf13/cobra" ) @@ -25,9 +26,11 @@ var Start = &cobra.Command{ } func startHandler(cmd *cobra.Command, args []string) { + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Starting service..."}) _, err := cli.StartService(context.Background(), &core.StartServiceRequest{ ServiceID: args[0], }) + s.Stop() handleError(err) - fmt.Println(aurora.Green("Service started")) + fmt.Println(aurora.Green("Service is running")) } diff --git a/cmd/service/stop.go b/cmd/service/stop.go index 41335d0bf..823111785 100644 --- a/cmd/service/stop.go +++ b/cmd/service/stop.go @@ -6,6 +6,7 @@ import ( "github.com/logrusorgru/aurora" "github.com/mesg-foundation/core/api/core" + "github.com/mesg-foundation/core/cmd/utils" "github.com/spf13/cobra" ) @@ -24,9 +25,11 @@ To have more explanation, see the page [stake explanation from the documentation } func stopHandler(cmd *cobra.Command, args []string) { + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping service..."}) _, err := cli.StopService(context.Background(), &core.StopServiceRequest{ ServiceID: args[0], }) + s.Stop() handleError(err) fmt.Println(aurora.Green("Service stopped")) } diff --git a/cmd/service/test.go b/cmd/service/test.go index 46a693662..30d15688e 100644 --- a/cmd/service/test.go +++ b/cmd/service/test.go @@ -90,25 +90,28 @@ func testHandler(cmd *cobra.Command, args []string) { }) handleError(err) + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Starting service..."}) _, err = cli.StartService(context.Background(), &core.StartServiceRequest{ ServiceID: deployment.ServiceID, }) + s.Stop() handleError(err) + fmt.Println(aurora.Green("Service started")) go listenEvents(deployment.ServiceID, cmd.Flag("event").Value.String()) - go listenResults(deployment.ServiceID) - time.Sleep(10 * time.Second) - + time.Sleep(time.Second) executeTask(deployment.ServiceID, cmd.Flag("task").Value.String(), cmd.Flag("data").Value.String()) - <-cmdUtils.WaitForCancel() + s = cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping service..."}) _, err = cli.StopService(context.Background(), &core.StopServiceRequest{ ServiceID: deployment.ServiceID, }) - fmt.Println(err) + s.Stop() + handleError(err) + fmt.Println(aurora.Green("Service stopped")) } func init() { From 67afce5fcfd4dbdcbaadd80b1563aa92ff4543ac Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 15:24:16 +0700 Subject: [PATCH 06/22] Improve command text --- cmd/daemon/stop.go | 4 ++-- cmd/service/list.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/daemon/stop.go b/cmd/daemon/stop.go index 2f384c42c..6d10a4311 100644 --- a/cmd/daemon/stop.go +++ b/cmd/daemon/stop.go @@ -18,12 +18,12 @@ var Stop = &cobra.Command{ } func stopHandler(cmd *cobra.Command, args []string) { - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Daemon is stopping..."}) + s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping daemon..."}) err := daemon.Stop() s.Stop() if err != nil { fmt.Println(aurora.Red(err)) return } - fmt.Println(aurora.Green("Daemon is stopped")) + fmt.Println(aurora.Green("Daemon stopped")) } diff --git a/cmd/service/list.go b/cmd/service/list.go index 4498794aa..4a368bacd 100644 --- a/cmd/service/list.go +++ b/cmd/service/list.go @@ -21,7 +21,7 @@ To have more details, see the [detail command](mesg-core_service_detail.md).`, } func listHandler(cmd *cobra.Command, args []string) { - services, err := services.All() + services, err := services.All() // TODO: this should use the API handleError(err) for _, service := range services { hash, _ := service.Hash() From d335451f34b846e984092f066b0fcd98a994b4cf Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 15:32:58 +0700 Subject: [PATCH 07/22] Increase test timeout --- .circleci/config.yml | 2 +- service/start_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c9ff50321..bd35337d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,7 +29,7 @@ jobs: - setup_remote_docker - run: go get -t ./... - run: docker swarm init - - run: env DAEMON.IMAGE=mesg/daemon:$CIRCLE_SHA1 go test -timeout 60s -p 1 -coverprofile=coverage.txt ./... + - run: env DAEMON.IMAGE=mesg/daemon:$CIRCLE_SHA1 go test -timeout 180s -p 1 -coverprofile=coverage.txt ./... - run: bash <(curl -s https://codecov.io/bash) "publish_docker_version": diff --git a/service/start_test.go b/service/start_test.go index e0456985a..26f85e2f2 100644 --- a/service/start_test.go +++ b/service/start_test.go @@ -19,7 +19,7 @@ func TestStartService(t *testing.T) { } dockerServices, err := service.Start() assert.Nil(t, err) - assert.Equal(t, len(dockerServices), len(service.GetDependencies())) + assert.Equal(t, len(service.GetDependencies()), len(dockerServices)) assert.Equal(t, service.IsRunning(), true) service.Stop() } From 70c33a46cdcbb042aa36881c26dee900a31d9d10 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 15:41:40 +0700 Subject: [PATCH 08/22] pull nginx in test --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index bd35337d6..42fdcdbc8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,6 +29,7 @@ jobs: - setup_remote_docker - run: go get -t ./... - run: docker swarm init + - run: docker pull nginx - run: env DAEMON.IMAGE=mesg/daemon:$CIRCLE_SHA1 go test -timeout 180s -p 1 -coverprofile=coverage.txt ./... - run: bash <(curl -s https://codecov.io/bash) From 001719a0fe9afd427a22cbe7523dfc06af5be7a8 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 16:13:32 +0700 Subject: [PATCH 09/22] No service mount with circleCI --- service/start.go | 56 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/service/start.go b/service/start.go index 841f48deb..33dc17c0b 100644 --- a/service/start.go +++ b/service/start.go @@ -2,6 +2,8 @@ package service import ( "errors" + "os" + "strconv" "strings" "sync" "time" @@ -74,24 +76,42 @@ func (dependency *Dependency) Start(service *Service, details dependencyDetails, return } namespace := []string{details.namespace, details.dependencyName} //TODO: refacto namespace - serviceID, err = container.StartService(container.ServiceOptions{ - Namespace: namespace, - Labels: map[string]string{ - "mesg.service": details.serviceName, - }, - Image: dependency.Image, - Args: strings.Fields(dependency.Command), - Env: []string{ - "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), - "MESG_ENDPOINT_TCP=mesg-daemon:50052", - }, - Mounts: append(extractVolumes(service, dependency, details), container.Mount{ - Source: viper.GetString(config.APIServiceSocketPath), - Target: viper.GetString(config.APIServiceTargetPath), - }), - Ports: extractPorts(dependency), - NetworksID: []string{networkID, sharedNetworkID}, - }) + circleCI, errCircle := strconv.ParseBool(os.Getenv("CIRCLECI")) + if errCircle == nil && circleCI { + serviceID, err = container.StartService(container.ServiceOptions{ + Namespace: namespace, + Labels: map[string]string{ + "mesg.service": details.serviceName, + }, + Image: dependency.Image, + Args: strings.Fields(dependency.Command), + Env: []string{ + "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), + "MESG_ENDPOINT_TCP=mesg-daemon:50052", + }, + Ports: extractPorts(dependency), + NetworksID: []string{networkID, sharedNetworkID}, + }) + } else { + serviceID, err = container.StartService(container.ServiceOptions{ + Namespace: namespace, + Labels: map[string]string{ + "mesg.service": details.serviceName, + }, + Image: dependency.Image, + Args: strings.Fields(dependency.Command), + Env: []string{ + "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), + "MESG_ENDPOINT_TCP=mesg-daemon:50052", + }, + Mounts: append(extractVolumes(service, dependency, details), container.Mount{ + Source: viper.GetString(config.APIServiceSocketPath), + Target: viper.GetString(config.APIServiceTargetPath), + }), + Ports: extractPorts(dependency), + NetworksID: []string{networkID, sharedNetworkID}, + }) + } if err != nil { return } From 59f01fc109dc2a93eff3c387e1561d31b0127343 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 16:19:37 +0700 Subject: [PATCH 10/22] Prevent mount when running in CircleCI --- container/service_options.go | 8 ++++++ service/start.go | 56 ++++++++++++------------------------ 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/container/service_options.go b/container/service_options.go index b9f1a90f1..b50d1307a 100644 --- a/container/service_options.go +++ b/container/service_options.go @@ -1,6 +1,9 @@ package container import ( + "os" + "strconv" + "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/swarm" ) @@ -72,6 +75,11 @@ func (options *ServiceOptions) swarmPorts() (ports []swarm.PortConfig) { } func (options *ServiceOptions) swarmMounts() (mounts []mount.Mount) { + // hack for preventing mount when in CircleCI + circleCI, errCircle := strconv.ParseBool(os.Getenv("CIRCLECI")) + if errCircle == nil && circleCI { + return + } mounts = make([]mount.Mount, len(options.Mounts)) for i, m := range options.Mounts { mounts[i] = mount.Mount{ diff --git a/service/start.go b/service/start.go index 33dc17c0b..841f48deb 100644 --- a/service/start.go +++ b/service/start.go @@ -2,8 +2,6 @@ package service import ( "errors" - "os" - "strconv" "strings" "sync" "time" @@ -76,42 +74,24 @@ func (dependency *Dependency) Start(service *Service, details dependencyDetails, return } namespace := []string{details.namespace, details.dependencyName} //TODO: refacto namespace - circleCI, errCircle := strconv.ParseBool(os.Getenv("CIRCLECI")) - if errCircle == nil && circleCI { - serviceID, err = container.StartService(container.ServiceOptions{ - Namespace: namespace, - Labels: map[string]string{ - "mesg.service": details.serviceName, - }, - Image: dependency.Image, - Args: strings.Fields(dependency.Command), - Env: []string{ - "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), - "MESG_ENDPOINT_TCP=mesg-daemon:50052", - }, - Ports: extractPorts(dependency), - NetworksID: []string{networkID, sharedNetworkID}, - }) - } else { - serviceID, err = container.StartService(container.ServiceOptions{ - Namespace: namespace, - Labels: map[string]string{ - "mesg.service": details.serviceName, - }, - Image: dependency.Image, - Args: strings.Fields(dependency.Command), - Env: []string{ - "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), - "MESG_ENDPOINT_TCP=mesg-daemon:50052", - }, - Mounts: append(extractVolumes(service, dependency, details), container.Mount{ - Source: viper.GetString(config.APIServiceSocketPath), - Target: viper.GetString(config.APIServiceTargetPath), - }), - Ports: extractPorts(dependency), - NetworksID: []string{networkID, sharedNetworkID}, - }) - } + serviceID, err = container.StartService(container.ServiceOptions{ + Namespace: namespace, + Labels: map[string]string{ + "mesg.service": details.serviceName, + }, + Image: dependency.Image, + Args: strings.Fields(dependency.Command), + Env: []string{ + "MESG_ENDPOINT=" + viper.GetString(config.APIServiceTargetSocket), + "MESG_ENDPOINT_TCP=mesg-daemon:50052", + }, + Mounts: append(extractVolumes(service, dependency, details), container.Mount{ + Source: viper.GetString(config.APIServiceSocketPath), + Target: viper.GetString(config.APIServiceTargetPath), + }), + Ports: extractPorts(dependency), + NetworksID: []string{networkID, sharedNetworkID}, + }) if err != nil { return } From e79c20ed4fc6232a198ac055e892cff256ed12bf Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 16:26:58 +0700 Subject: [PATCH 11/22] Remove useless print --- container/container_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/container/container_test.go b/container/container_test.go index a4953a520..0d79253d4 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -1,7 +1,6 @@ package container import ( - "fmt" "testing" "time" @@ -52,10 +51,8 @@ func TestContainerStatusStopped(t *testing.T) { namespace := []string{"TestContainerStatusStopped"} startTestService(namespace) WaitForContainerStatus(namespace, RUNNING, time.Minute) - fmt.Println("wait for running") StopService(namespace) WaitForContainerStatus(namespace, STOPPED, time.Minute) - fmt.Println("wait for stop") status, err := ContainerStatus(namespace) assert.Nil(t, err) assert.Equal(t, status, STOPPED) From 03eebc864c6d363809e487036aeafa36cc997770 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 16:33:26 +0700 Subject: [PATCH 12/22] add option to force service options mount even in CircleCI. useful for unit test. --- container/service_options.go | 6 +++--- container/service_options_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/container/service_options.go b/container/service_options.go index b50d1307a..3cb000a5b 100644 --- a/container/service_options.go +++ b/container/service_options.go @@ -50,7 +50,7 @@ func (options *ServiceOptions) toSwarmServiceSpec() (service swarm.ServiceSpec) }, Env: options.Env, Args: options.Args, - Mounts: options.swarmMounts(), + Mounts: options.swarmMounts(true), }, Networks: options.swarmNetworks(), }, @@ -74,10 +74,10 @@ func (options *ServiceOptions) swarmPorts() (ports []swarm.PortConfig) { return } -func (options *ServiceOptions) swarmMounts() (mounts []mount.Mount) { +func (options *ServiceOptions) swarmMounts(force bool) (mounts []mount.Mount) { // hack for preventing mount when in CircleCI circleCI, errCircle := strconv.ParseBool(os.Getenv("CIRCLECI")) - if errCircle == nil && circleCI { + if force == false && errCircle == nil && circleCI { return } mounts = make([]mount.Mount, len(options.Mounts)) diff --git a/container/service_options_test.go b/container/service_options_test.go index b06401310..c59bd38b5 100644 --- a/container/service_options_test.go +++ b/container/service_options_test.go @@ -87,7 +87,7 @@ func TestServiceOptionMounts(t *testing.T) { }, }, } - mounts := options.swarmMounts() + mounts := options.swarmMounts(true) assert.Equal(t, 1, len(mounts)) assert.Equal(t, "source/file", mounts[0].Source) assert.Equal(t, "target/file", mounts[0].Target) From 38271a2eda11e3480c5328f96fc4192d71d2bab1 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Fri, 1 Jun 2018 16:40:04 +0700 Subject: [PATCH 13/22] Fix: add option to force service options mount even in CircleCI. useful for unit test. --- container/service_options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/container/service_options.go b/container/service_options.go index 3cb000a5b..cdaf35abe 100644 --- a/container/service_options.go +++ b/container/service_options.go @@ -50,7 +50,7 @@ func (options *ServiceOptions) toSwarmServiceSpec() (service swarm.ServiceSpec) }, Env: options.Env, Args: options.Args, - Mounts: options.swarmMounts(true), + Mounts: options.swarmMounts(false), }, Networks: options.swarmNetworks(), }, From 704a0cca7d5b324b433e2f5ec1c97b6f3f220eee Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Mon, 4 Jun 2018 19:16:48 +0700 Subject: [PATCH 14/22] Update comment on the mount hack for CircleCI --- container/service_options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/container/service_options.go b/container/service_options.go index cdaf35abe..a091cc26c 100644 --- a/container/service_options.go +++ b/container/service_options.go @@ -75,7 +75,7 @@ func (options *ServiceOptions) swarmPorts() (ports []swarm.PortConfig) { } func (options *ServiceOptions) swarmMounts(force bool) (mounts []mount.Mount) { - // hack for preventing mount when in CircleCI + // TOFIX: hack to prevent mount when in CircleCI (Mount in CircleCI doesn't work). Should use CircleCi with machine to fix this. circleCI, errCircle := strconv.ParseBool(os.Getenv("CIRCLECI")) if force == false && errCircle == nil && circleCI { return From 60ea1b42e486517f2b1e9b96e35916b3f527bc48 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Mon, 4 Jun 2018 19:35:50 +0700 Subject: [PATCH 15/22] Use defer for mutex.Unlock() on service start and stop --- service/start.go | 2 +- service/stop.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service/start.go b/service/start.go index 841f48deb..6bb36ea5a 100644 --- a/service/start.go +++ b/service/start.go @@ -41,11 +41,11 @@ func (service *Service) Start() (serviceIDs []string, err error) { go func(service *Service, d dependencyDetails, name string, i int) { serviceID, errStart := dependency.Start(service, d, networkID) mutex.Lock() + defer mutex.Unlock() serviceIDs[i] = serviceID if errStart != nil && err == nil { err = errStart } - mutex.Unlock() wg.Done() }(service, d, name, i) i++ diff --git a/service/stop.go b/service/stop.go index bdd853213..9099442f1 100644 --- a/service/stop.go +++ b/service/stop.go @@ -32,10 +32,10 @@ func (service *Service) StopDependencies() (err error) { go func(d *Dependency, name string, dependencyName string) { errStop := d.Stop(name, dependencyName) mutex.Lock() + defer mutex.Unlock() if errStop != nil && err == nil { err = errStop } - mutex.Unlock() wg.Done() }(dependency, service.namespace(), name) } From d22f278c43355049c10402340f2c381cb1c51a60 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Mon, 4 Jun 2018 19:40:49 +0700 Subject: [PATCH 16/22] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 191c89530..69a6e50e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - (#174) Update CI to build version based on tags - (#173) Use official Docker client - (#175) Changed the struct to use to start docker service +- (#181) Daemon and Service start and stop functions wait for the docker container to actually run or stop. #### Added - (#174) Add CHANGELOG.md file From e2adc19635ed3048bbd1d161eede7e6720fcc906 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 10:40:20 +0700 Subject: [PATCH 17/22] use defer for waitGroup done in service --- service/start.go | 2 +- service/stop.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service/start.go b/service/start.go index 6bb36ea5a..41398090d 100644 --- a/service/start.go +++ b/service/start.go @@ -39,6 +39,7 @@ func (service *Service) Start() (serviceIDs []string, err error) { } wg.Add(1) go func(service *Service, d dependencyDetails, name string, i int) { + defer wg.Done() serviceID, errStart := dependency.Start(service, d, networkID) mutex.Lock() defer mutex.Unlock() @@ -46,7 +47,6 @@ func (service *Service) Start() (serviceIDs []string, err error) { if errStart != nil && err == nil { err = errStart } - wg.Done() }(service, d, name, i) i++ } diff --git a/service/stop.go b/service/stop.go index 9099442f1..73e0b484a 100644 --- a/service/stop.go +++ b/service/stop.go @@ -30,13 +30,13 @@ func (service *Service) StopDependencies() (err error) { for name, dependency := range service.GetDependencies() { wg.Add(1) go func(d *Dependency, name string, dependencyName string) { + defer wg.Done() errStop := d.Stop(name, dependencyName) mutex.Lock() defer mutex.Unlock() if errStop != nil && err == nil { err = errStop } - wg.Done() }(dependency, service.namespace(), name) } wg.Wait() From 61f2da0fb59370379334392ccddca348951adee3 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 12:09:11 +0700 Subject: [PATCH 18/22] Remove timeout from container.WaitForContainerStatus function --- container/container.go | 10 +--------- container/container_test.go | 25 +++++++------------------ container/type.go | 14 -------------- daemon/start.go | 3 +-- daemon/stop.go | 4 +--- service/start.go | 3 +-- service/stop.go | 3 +-- 7 files changed, 12 insertions(+), 50 deletions(-) diff --git a/container/container.go b/container/container.go index 6de9fd8a7..3ae716b33 100644 --- a/container/container.go +++ b/container/container.go @@ -51,8 +51,7 @@ func Status(namespace []string) (status StatusType, err error) { } // WaitForContainerStatus wait for the container to have the provided status until it reach the timeout -func WaitForContainerStatus(namespace []string, status StatusType, timeout time.Duration) (err error) { - start := time.Now() +func WaitForContainerStatus(namespace []string, status StatusType) (err error) { for { currentStatus, err := Status(namespace) if err != nil { @@ -61,13 +60,6 @@ func WaitForContainerStatus(namespace []string, status StatusType, timeout time. if currentStatus == status { return nil } - diff := time.Now().Sub(start) - if diff.Nanoseconds() >= int64(timeout) { - return &TimeoutError{ - duration: timeout, - name: Namespace(namespace), - } - } time.Sleep(500 * time.Millisecond) } } diff --git a/container/container_test.go b/container/container_test.go index f35df6c50..c8d1ec2f6 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -2,7 +2,6 @@ package container import ( "testing" - "time" "github.com/stvp/assert" ) @@ -16,7 +15,7 @@ func TestFindContainer(t *testing.T) { namespace := []string{"TestFindContainer"} startTestService(namespace) defer StopService(namespace) - WaitForContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING) container, err := FindContainer(namespace) assert.Nil(t, err) assert.NotEqual(t, "", container.ID) @@ -41,7 +40,7 @@ func TestContainerStatusRunning(t *testing.T) { namespace := []string{"TestContainerStatusRunning"} startTestService(namespace) defer StopService(namespace) - WaitForContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING) status, err := Status(namespace) assert.Nil(t, err) assert.Equal(t, status, RUNNING) @@ -50,9 +49,9 @@ func TestContainerStatusRunning(t *testing.T) { func TestContainerStatusStopped(t *testing.T) { namespace := []string{"TestContainerStatusStopped"} startTestService(namespace) - WaitForContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING) StopService(namespace) - WaitForContainerStatus(namespace, STOPPED, time.Minute) + WaitForContainerStatus(namespace, STOPPED) status, err := Status(namespace) assert.Nil(t, err) assert.Equal(t, status, STOPPED) @@ -62,26 +61,16 @@ func TestWaitForContainerRunning(t *testing.T) { namespace := []string{"TestWaitForContainerRunning"} startTestService(namespace) defer StopService(namespace) - err := WaitForContainerStatus(namespace, RUNNING, time.Minute) + err := WaitForContainerStatus(namespace, RUNNING) assert.Nil(t, err) } -func TestWaitForContainerTimeout(t *testing.T) { - namespace := []string{"TestWaitForContainerTimeout"} - startTestService(namespace) - defer StopService(namespace) - err := WaitForContainerStatus(namespace, RUNNING, time.Nanosecond) - assert.NotNil(t, err) - _, ok := err.(*TimeoutError) - assert.True(t, ok) -} - func TestWaitForContainerStopped(t *testing.T) { namespace := []string{"TestWaitForContainerStopped"} startTestService(namespace) - WaitForContainerStatus(namespace, RUNNING, time.Minute) + WaitForContainerStatus(namespace, RUNNING) StopService(namespace) - err := WaitForContainerStatus(namespace, STOPPED, time.Minute) + err := WaitForContainerStatus(namespace, STOPPED) assert.Nil(t, err) } diff --git a/container/type.go b/container/type.go index be76abae8..62de9dedb 100644 --- a/container/type.go +++ b/container/type.go @@ -1,9 +1,5 @@ package container -import ( - "time" -) - // StatusType of the service type StatusType uint @@ -12,13 +8,3 @@ const ( STOPPED StatusType = 1 RUNNING StatusType = 2 ) - -// TimeoutError represents an error of timeout -type TimeoutError struct { - duration time.Duration - name string -} - -func (e *TimeoutError) Error() string { - return "Timeout reached after " + e.duration.String() + " for ressource " + e.name -} diff --git a/daemon/start.go b/daemon/start.go index 063bc4565..ee9c2e704 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -2,7 +2,6 @@ package daemon import ( "path/filepath" - "time" "github.com/mesg-foundation/core/config" "github.com/mesg-foundation/core/container" @@ -26,7 +25,7 @@ func Start() (serviceID string, err error) { if err != nil { return } - err = container.WaitForContainerStatus(Namespace(), container.RUNNING, time.Minute) + err = container.WaitForContainerStatus(Namespace(), container.RUNNING) return } diff --git a/daemon/stop.go b/daemon/stop.go index 6e4391e56..748191ef0 100644 --- a/daemon/stop.go +++ b/daemon/stop.go @@ -1,8 +1,6 @@ package daemon import ( - "time" - "github.com/mesg-foundation/core/container" ) @@ -16,6 +14,6 @@ func Stop() (err error) { if err != nil { return } - err = container.WaitForContainerStatus(Namespace(), container.STOPPED, time.Minute) + err = container.WaitForContainerStatus(Namespace(), container.STOPPED) return } diff --git a/service/start.go b/service/start.go index 41398090d..a76ad178d 100644 --- a/service/start.go +++ b/service/start.go @@ -4,7 +4,6 @@ import ( "errors" "strings" "sync" - "time" "github.com/mesg-foundation/core/config" "github.com/mesg-foundation/core/container" @@ -95,6 +94,6 @@ func (dependency *Dependency) Start(service *Service, details dependencyDetails, if err != nil { return } - err = container.WaitForContainerStatus(namespace, container.RUNNING, time.Minute) //TODO: be careful with timeout + err = container.WaitForContainerStatus(namespace, container.RUNNING) return } diff --git a/service/stop.go b/service/stop.go index 73e0b484a..cb9d2dd6f 100644 --- a/service/stop.go +++ b/service/stop.go @@ -2,7 +2,6 @@ package service import ( "sync" - "time" "github.com/mesg-foundation/core/container" ) @@ -53,6 +52,6 @@ func (dependency *Dependency) Stop(name string, dependencyName string) (err erro if err != nil { return } - err = container.WaitForContainerStatus(namespace, container.STOPPED, time.Minute) //TODO: be careful with timeout + err = container.WaitForContainerStatus(namespace, container.STOPPED) return } From 5e404aef0b49486f5be48c8e5b1af3dcf4b45faa Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 12:10:14 +0700 Subject: [PATCH 19/22] Remove return in WaitForContainerStatus --- container/container.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/container/container.go b/container/container.go index 3ae716b33..141a3b04e 100644 --- a/container/container.go +++ b/container/container.go @@ -53,13 +53,15 @@ func Status(namespace []string) (status StatusType, err error) { // WaitForContainerStatus wait for the container to have the provided status until it reach the timeout func WaitForContainerStatus(namespace []string, status StatusType) (err error) { for { - currentStatus, err := Status(namespace) + var currentStatus StatusType + currentStatus, err = Status(namespace) if err != nil { - return err + break } if currentStatus == status { - return nil + break } time.Sleep(500 * time.Millisecond) } + return } From 50a6576df9592706a762f740cb1fc808dfc305f5 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 12:14:14 +0700 Subject: [PATCH 20/22] Reorganize daemon start to fix CodeClimate error --- daemon/start.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/daemon/start.go b/daemon/start.go index ee9c2e704..2a8a1e8e8 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -11,17 +11,14 @@ import ( // Start the docker daemon func Start() (serviceID string, err error) { running, err := IsRunning() - if err != nil { - return - } - if running == true { + if err != nil || running == true { return } - sharedNetworkID, err := container.SharedNetworkID() + spec, err := serviceSpec() if err != nil { return } - serviceID, err = container.StartService(serviceSpec(sharedNetworkID)) + serviceID, err = container.StartService(spec) if err != nil { return } @@ -29,8 +26,12 @@ func Start() (serviceID string, err error) { return } -func serviceSpec(networkID string) container.ServiceOptions { - return container.ServiceOptions{ +func serviceSpec() (spec container.ServiceOptions, err error) { + sharedNetworkID, err := container.SharedNetworkID() + if err != nil { + return + } + spec = container.ServiceOptions{ Namespace: Namespace(), Image: viper.GetString(config.DaemonImage), Env: []string{ @@ -54,6 +55,7 @@ func serviceSpec(networkID string) container.ServiceOptions { Published: 50052, }, }, - NetworksID: []string{networkID}, + NetworksID: []string{sharedNetworkID}, } + return } From 7f78f017e72abfdf64c3917d0169e1892166d623 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 12:26:41 +0700 Subject: [PATCH 21/22] Refacto Spinner in CLI to fix CodeClimate --- cmd/daemon/start.go | 6 +++--- cmd/daemon/stop.go | 7 ++++--- cmd/service/start.go | 9 +++++---- cmd/service/stop.go | 9 +++++---- cmd/service/test.go | 16 ++++++++-------- cmd/utils/spinner.go | 8 ++++++++ 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/cmd/daemon/start.go b/cmd/daemon/start.go index 35849f233..72a931758 100644 --- a/cmd/daemon/start.go +++ b/cmd/daemon/start.go @@ -27,9 +27,9 @@ func startHandler(cmd *cobra.Command, args []string) { fmt.Println(aurora.Green("Daemon is running")) return } - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Daemon is starting..."}) - _, err = daemon.Start() - s.Stop() + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Starting daemon..."}, func() { + _, err = daemon.Start() + }) if err != nil { fmt.Println(aurora.Red(err)) return diff --git a/cmd/daemon/stop.go b/cmd/daemon/stop.go index 6d10a4311..25bec38bc 100644 --- a/cmd/daemon/stop.go +++ b/cmd/daemon/stop.go @@ -18,9 +18,10 @@ var Stop = &cobra.Command{ } func stopHandler(cmd *cobra.Command, args []string) { - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping daemon..."}) - err := daemon.Stop() - s.Stop() + var err error + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Stopping daemon..."}, func() { + err = daemon.Stop() + }) if err != nil { fmt.Println(aurora.Red(err)) return diff --git a/cmd/service/start.go b/cmd/service/start.go index 5baa3427d..2cbe11833 100644 --- a/cmd/service/start.go +++ b/cmd/service/start.go @@ -26,11 +26,12 @@ var Start = &cobra.Command{ } func startHandler(cmd *cobra.Command, args []string) { - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Starting service..."}) - _, err := cli.StartService(context.Background(), &core.StartServiceRequest{ - ServiceID: args[0], + var err error + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Starting service..."}, func() { + _, err = cli.StartService(context.Background(), &core.StartServiceRequest{ + ServiceID: args[0], + }) }) - s.Stop() handleError(err) fmt.Println(aurora.Green("Service is running")) } diff --git a/cmd/service/stop.go b/cmd/service/stop.go index 823111785..2cd915a03 100644 --- a/cmd/service/stop.go +++ b/cmd/service/stop.go @@ -25,11 +25,12 @@ To have more explanation, see the page [stake explanation from the documentation } func stopHandler(cmd *cobra.Command, args []string) { - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping service..."}) - _, err := cli.StopService(context.Background(), &core.StopServiceRequest{ - ServiceID: args[0], + var err error + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Stopping service..."}, func() { + _, err = cli.StopService(context.Background(), &core.StopServiceRequest{ + ServiceID: args[0], + }) }) - s.Stop() handleError(err) fmt.Println(aurora.Green("Service stopped")) } diff --git a/cmd/service/test.go b/cmd/service/test.go index 30d15688e..33beb4051 100644 --- a/cmd/service/test.go +++ b/cmd/service/test.go @@ -90,11 +90,11 @@ func testHandler(cmd *cobra.Command, args []string) { }) handleError(err) - s := cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Starting service..."}) - _, err = cli.StartService(context.Background(), &core.StartServiceRequest{ - ServiceID: deployment.ServiceID, + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Starting service..."}, func() { + _, err = cli.StartService(context.Background(), &core.StartServiceRequest{ + ServiceID: deployment.ServiceID, + }) }) - s.Stop() handleError(err) fmt.Println(aurora.Green("Service started")) @@ -105,11 +105,11 @@ func testHandler(cmd *cobra.Command, args []string) { executeTask(deployment.ServiceID, cmd.Flag("task").Value.String(), cmd.Flag("data").Value.String()) <-cmdUtils.WaitForCancel() - s = cmdUtils.StartSpinner(cmdUtils.SpinnerOptions{Text: "Stopping service..."}) - _, err = cli.StopService(context.Background(), &core.StopServiceRequest{ - ServiceID: deployment.ServiceID, + cmdUtils.ShowSpinnerForFunc(cmdUtils.SpinnerOptions{Text: "Stopping service..."}, func() { + _, err = cli.StopService(context.Background(), &core.StopServiceRequest{ + ServiceID: deployment.ServiceID, + }) }) - s.Stop() handleError(err) fmt.Println(aurora.Green("Service stopped")) } diff --git a/cmd/utils/spinner.go b/cmd/utils/spinner.go index 11253342c..f6ec22ea8 100644 --- a/cmd/utils/spinner.go +++ b/cmd/utils/spinner.go @@ -24,3 +24,11 @@ func StartSpinner(opts SpinnerOptions) (spinner *spinnerPkg.Spinner) { } return } + +// ShowSpinnerForFunc shows a spinner during the execution of the function +func ShowSpinnerForFunc(opts SpinnerOptions, function func()) { + s := StartSpinner(opts) + defer s.Stop() + function() + return +} From 10be2d17bf9c8ac38bd7cb6857e509e642804f46 Mon Sep 17 00:00:00 2001 From: Nicolas Mahe Date: Tue, 5 Jun 2018 13:41:38 +0700 Subject: [PATCH 22/22] Fix daemon start test --- daemon/start_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daemon/start_test.go b/daemon/start_test.go index 02f96c602..627b8a1db 100644 --- a/daemon/start_test.go +++ b/daemon/start_test.go @@ -42,7 +42,8 @@ func startForTest() { // } func TestStartConfig(t *testing.T) { - spec := serviceSpec("networkID") + spec, err := serviceSpec() + assert.Nil(t, err) // Make sure that the config directory is passed in parameter to write on the same folder assert.Equal(t, spec.Env[0], "MESG.PATH=/mesg") assert.Equal(t, spec.Env[1], "API.SERVICE.SOCKETPATH="+filepath.Join(viper.GetString(config.MESGPath), "server.sock"))