fix: use scale for restarting

The other approach wasn't working. Duplicating containers on restart.
You'd end up with 2 containers per restart...
This commit is contained in:
decentral1se 2022-01-01 17:22:35 +01:00
parent a556ca625b
commit abd094387f
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
2 changed files with 72 additions and 21 deletions

View File

@ -3,28 +3,28 @@ package app
import (
"errors"
"fmt"
"time"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client"
containerPkg "coopcloud.tech/abra/pkg/container"
"github.com/docker/docker/api/types/filters"
upstream "coopcloud.tech/abra/pkg/upstream/service"
stack "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var appRestartCommand = &cli.Command{
Name: "restart",
Usage: "Restart an app",
Aliases: []string{"re"},
ArgsUsage: "<service>",
Description: `This command restarts a service within a deployed app.`,
Name: "restart",
Usage: "Restart an app",
Aliases: []string{"re"},
ArgsUsage: "<service>",
Description: `This command restarts a service within a deployed app.`,
BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
serviceName := c.Args().Get(1)
if serviceName == "" {
serviceNameShort := c.Args().Get(1)
if serviceNameShort == "" {
err := errors.New("missing service?")
internal.ShowSubcommandHelpAndError(c, err)
}
@ -34,25 +34,32 @@ var appRestartCommand = &cli.Command{
logrus.Fatal(err)
}
serviceFilter := fmt.Sprintf("%s_%s", app.StackName(), serviceName)
filters := filters.NewArgs()
filters.Add("name", serviceFilter)
serviceName := fmt.Sprintf("%s_%s", app.StackName(), serviceNameShort)
targetContainer, err := containerPkg.GetContainer(c.Context, cl, filters, true)
if err != nil {
logrus.Debugf("attempting to scale %s to 0 (restart logic)", serviceName)
if err := upstream.RunServiceScale(c.Context, cl, serviceName, 0); err != nil {
logrus.Fatal(err)
}
logrus.Debugf("attempting to restart %s", serviceFilter)
timeout := 30 * time.Second
if err := cl.ContainerRestart(c.Context, targetContainer.ID, &timeout); err != nil {
if err := stack.WaitOnService(c.Context, cl, serviceName, app.Name); err != nil {
logrus.Fatal(err)
}
logrus.Infof("%s service restarted", serviceFilter)
logrus.Debugf("%s has been scaled to 0 (restart logic)", serviceName)
logrus.Debugf("attempting to scale %s to 1 (restart logic)", serviceName)
if err := upstream.RunServiceScale(c.Context, cl, serviceName, 1); err != nil {
logrus.Fatal(err)
}
if err := stack.WaitOnService(c.Context, cl, serviceName, app.Name); err != nil {
logrus.Fatal(err)
}
logrus.Debugf("%s has been scaled to 1 (restart logic)", serviceName)
logrus.Infof("%s service successfully restarted", serviceNameShort)
return nil
},
BashComplete: autocomplete.AppNameComplete,
}

View File

@ -0,0 +1,44 @@
package upstream
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/sirupsen/logrus"
)
// RunServiceScale scales a service (useful for restart action)
func RunServiceScale(ctx context.Context, cl *client.Client, serviceID string, scale uint64) error {
service, _, err := cl.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
if err != nil {
return err
}
serviceMode := &service.Spec.Mode
if serviceMode.Replicated != nil {
serviceMode.Replicated.Replicas = &scale
} else if serviceMode.ReplicatedJob != nil {
serviceMode.ReplicatedJob.TotalCompletions = &scale
} else {
return fmt.Errorf("scale can only be used with replicated or replicated-job mode")
}
response, err := cl.ServiceUpdate(
ctx,
service.ID,
service.Version,
service.Spec,
types.ServiceUpdateOptions{},
)
if err != nil {
return err
}
for _, warning := range response.Warnings {
logrus.Warn(warning)
}
return nil
}