8000 Add 'docker service rollback' subcommand by redpanda · Pull Request #205 · docker/cli · GitHub
[go: up one dir, main page]

Skip to content

Co 8000 nversation

@redpanda
Copy link
Contributor
@redpanda redpanda commented Jun 19, 2017

Signed-off-by: Jimmy Leger jimmy.leger@gmail.com

fixes #142
PS: This bug was fixed during a Docker Hackergarten.

- What I did

I add the docker service rollback subcommand

- How I did it

I extracted the rollback process from runUpdate

- How to verify it

Create a service with a single replica:

$ docker service create --name my-service -p 8080:80 nginx:alpine

Confirm that the service is running with a single replica:

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          1/1                 nginx:alpine        *:8080->80/tcp

Update the service to use three replicas:

$ docker service update --replicas=3 my-service

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          3/3                 nginx:alpine        *:8080->80/tcp

Now roll back the service to its previous version, and confirm it is
running a single replica again:

$ docker service rollback my-service

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          1/1                 nginx:alpine        *:8080->80/tcp

- Description for the changelog

Add docker service rollback subcommand

- A picture of a cute animal (not mandatory but encouraged)

redpanda picture

Copy link
Contributor
@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Aliases: []string{"rollback"},
Short: "Rollback a service",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern we use in these packages is to keep the inline function separate from adding flag.

The flags can be added at the end of newRollbackCommand() before return cmd

Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()
flags.Bool("rollback", true, "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the command is rollback, we don't need a rollback flag, right?

I guess the calling code expects this? We should refactor runUpdate() so that we have a function we can call directly that doesn't require such a flag.

flags := cmd.Flags()
flags.Bool("rollback", true, "")
flags.Bool("force", false, "Force update even if no changes require it")
addServiceFlags(flags, options, nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to add all the service flags. We only want the force flag added.

@codecov-io
Copy link
codecov-io commented Jun 19, 2017

Codecov Report

❗ No coverage uploaded for pull request base (master@17adcbd). Click here to learn what that means.
The diff coverage is 76.36%.

@@            Coverage Diff            @@
##             master     #205   +/-   ##
=========================================
  Coverage          ?   46.33%           
=========================================
  Files             ?      194           
  Lines             ?    16134           
  Branches          ?        0           
=========================================
  Hits              ?     7475           
  Misses            ?     8272           
  Partials          ?      387

@redpanda
Copy link
Contributor Author
redpanda commented Jun 25, 2017

Hello @dnephin!

First thank for your feedbacks.

I don't make the choice to refactor the runUpdate function but just implement runRollback which only call ServiceUpdate endpoint with the needed parameters.

BTW I have some code duplication between runUpdate and runRollback see: https://github.com/docker/cli/pull/205/files#diff-09b79b8a3ba1feabc2d859a294bb1ac5R43
Should I create a function to initialize types.ServiceUpdateOptions ?

Thanks by advance for your feedbacks.

Copy link
Contributor
@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is looking better

I would suggest rebasing on docker/master to pick the new CI changes. It will help your build run faster.


cmd := &cobra.Command{
Use: "rollback [OPTIONS]",
Aliases: []string{"rollback"},
Copy link
Contributor
8000

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This alias is not necessary because it's the same as the first word in Use:, so this line can be removed.

updateOpts := types.ServiceUpdateOptions{}
spec := &service.Spec

if versions.LessThan(dockerCli.Client().ClientVersion(), "1.28") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just hide this command on earlier versions, so we don't need to check version here. You can do that by setting Tags on the cobra.Command above

Tags: map[string]string{"version": "1.31"}

That way we can always set updateOpts.Rollback to "previous"

Copy link
Contributor
@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

A unit test would be great as well.

There are examples of unit tests in other cli/command packages.

@redpanda
Copy link
Contributor Author
redpanda commented Jul 4, 2017

Yeah I'm working on it! 👍

func warnDetachDefault(err io.Writer, clientVersion string, flags *pflag.FlagSet, msg string) {
if !flags.Changed("detach") && versions.GreaterThanOrEqualTo(clientVersion, "1.29") {
func warnDetachDefault(err io.Writer, clientVersion string, msg string) {
if versions.GreaterThanOrEqualTo(clientVersion, "1.29") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? This doesn't look right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You right! I'm gonna fix that

@redpanda
Copy link
Contributor Author

ping @vdemeester

@docker docker deleted a comment from GordonTheTurtle Jul 18, 2017
Copy link
Member
@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some comments / suggestions

```
```bash
docker service update --image=redis:3.0.7 redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this example output is missing docker service ps (which is needed to show this output)

ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
3duazds0yne3 redis.1 3.0.7 moby Ready Rejected less than a second ago "No such image: 3.0.7:latest"
w08xdhdc5hjv \_ redis.1 3.0.7 moby Shutdown Rejected 2 seconds ago "No such image: 3.0.7:latest"
x9x7gl374ih6 \_ redis.1 redis:3.0.6 moby Shutdown Shutdown 1 second ago
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "rejected" states here are probably only distracting from what we're trying to show here; I suggest updating the output to only show what's needed.


## Examples

Rollback the `redis` service:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using a custom name, it may be good to use something that's clearly "custom". Naming the service redis for a service that's using redis as an image, could lead to people thinking the name must be the same as the image.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

Rollback the `redis` service:

```bash
$ docker service create --name redis redis:3.0.6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if "updating" the image from 3.0.6 to 3.0.7, then rolling back could make people think the "rollback" is rolling back an image update, not the service definition. Although it makes a nice example to update the image version, and roll back that change, would it be better to use something else for illustration? e.g.

### Roll back a service to its previous version

This example creates a service with a single replica, updates the
service to use three replicas, and then rolls back the service to the
previous version, having one replica.

Create a service with a single replica:

```bash
$ docker service create --name my-service -p 8080:80 nginx:alpine
```

Confirm that the service is running with a single replica:

```bash
$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          1/1                 nginx:alpine        *:8080->80/tcp
```

Update the service to use three replicas:

```bash
$ docker service update --replicas=3 my-service

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          3/3                 nginx:alpine        *:8080->80/tcp
```

Now rollback the service to its previous version, and confirm it is
running a single replica again:

```bash
$ docker service rollback my-service

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
xbw728mf6q0d        my-service          replicated          1/1                 nginx:alpine        *:8080->80/tcp
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mstanleyjones wdyt? ^^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, agreed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I am going to use this example instead of the other one.

## Examples

Rollback the `redis` 6D38 service:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this could use some additional information (also strip down the output to show just the relevant information, as mentioned in my other comments), something like;

### Roll back a service to a previous version

In this example, a service is created using the `redis:3.0.6` image,
updated to use the `redis:3.0.7` image, and then rolled back to its
previous version.

Create a service using the `redis:3.0.6` image:

```bash
$ docker service create --name my-service redis:3.0.6
```

Confirm that the service is running:

```bash
$ docker service ps my-service

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
s2xak85rftfc        my-service.1        redis:3.0.6         moby                Running             Running 4 seconds ago
```

Update the service to use the `redis:3.0.7` image:

```bash
$ docker service update --image=redis:3.0.7 my-service
```

The service is now updated to use the `redis:3.0.7` image:

```bash
$ docker service ps my-service

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                    ERROR               PORTS
7jtl9bxnxnx1        my-service.1        redis:3.0.7         moby                Running             Running less than a second ago
s2xak85rftfc         \_ my-service.1    redis:3.0.6         moby                Shutdown            Shutdown 10 seconds ago
```

Roll back the service to its previous version. Rolling back the service
reverts all changes made to the service in the last update. In this
example, rolling back the service changes the service's image back to
`redis:3.0.6`.

```bash
$ docker service rollback my-service

$ docker service ps my-service

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
8gwl1xoi0xh3        my-service.1        redis:3.0.6         moby                Running             Running 3 seconds ago
7jtl9bxnxnx1         \_ my-service.1    redis:3.0.7         moby                Shutdown            Shutdown 4 seconds ago
s2xak85rftfc         \_ my-service.1    redis:3.0.6         moby                Shutdown            Shutdown 2 minutes ago
```

```

### Rolling back to the previous version of a service
### Rolling back to the previous version of a service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use gerunds (-ing words) in titles. How about "Roll back to the previous version of a service"? By the way, when you are using the verb form, it is "roll back" rather than "rollback".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@redpanda I realise this wasn't added in your pull request, but can you address this comment as well?

@redpanda redpanda force-pushed the rollback branch 2 times, most recently from 326cb65 to 155835c Compare August 14, 2017 11:13
@redpanda
Copy link
Contributor Author

Should I implement the flag --update-delay.
This flag can be used with the --rolback flag docker service update command.
See: https://docs.docker.com/engine/reference/commandline/service_update/#rolling-back-to-the-previous-version-of-a-service

@thaJeztah
Copy link
Member

@redpanda I think it's best to do so in a follow up. This pull request is already in docs review, and provides the core functionality needed; we can enhance the functionality in a follow up 👍

Copy link
Member
@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two minor comments, but LGTM after those are addressed 👍

```

### Rolling back to the previous version of a service
### Rolling back to the previous version of a service
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@redpanda I realise this wasn't added in your pull request, but can you address this comment as well?


### Roll back to the previous version of a service

This will revert the service to the configuration that was in place before the most recent docker service update command.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This" is a bit unclear, because here it doesn't have the introduction sentence that is present in the section it's copied from.

How about;

Use the `docker service rollback` command to roll back to the previous version
of a service. After executing this command, the service is reverted to the
configuration that was in place before the most recent `docker service update`
command.

@redpanda redpanda force-pushed the rollback branch 2 times, most recently from ac02d67 to 611c1d5 Compare August 15, 2017 09:35
Copy link
Contributor
@mdlinville mdlinville left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Just a couple more nitpicky changes please. :) 👼


# service rollback

```Markdown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably works just fine but the hint is usually markdown.

Copy link
Contributor Author
@redpanda redpanda Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I'm gonna fix it for all service_*.md files

@@ -0,0 +1,94 @@
---
title: "service rollback"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quotes not required in any of the front-matter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I replaced that line by: title: service rollback ?

Copy link
Contributor Author
@redpanda redpanda Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just read some information about the front-matter.
Should I changed it like that ?

---
title: service rollback
description: The service rollback command description and usage
keywords: ["service", "rollback"]
---

PS: I just keep the same front-matter used in other command line documentation but I can change it. ^^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to hurt anything. We can probably do a bulk fix later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

```Markdown
Usage: docker service rollback SERVICE

Rollback a service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "Revert changes to a service's configuration" so we are not using the word to describe the word. I realize this is in the --help output. Can you please change it there too?


## Description

Roll back a specified service to its previous version from the swarm. This command has to be run
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/has to be/must be

@redpanda redpanda force-pushed the rollback branch 2 times, most recently from 924fe65 to c14bc76 Compare August 16, 2017 10:12
@mdlinville
Copy link
Contributor

I feel like I confused you. Don't change the Markdown hint to markdown on files unrelated to the original intent of this commit. We can fix the other ones later.

@redpanda
Copy link
Contributor Author

You right! I will revert these changes. ^^

@redpanda redpanda force-pushed the rollback branch 3 times, most recently from ec7976e to 146baa4 Compare August 16, 2017 20:17
Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Implement runRollback to not use runUpdate

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Add version tag and add flag quiet to suppress progress output

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Removed flags from warnDetachDefault

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Used command.Cli interface

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Add detach flag on rollback command

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Create a fakeClient for service commands

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Added unit test for rollback command

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Used command.Cli interface instead of *command.DockerCli in service commands

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Revert "Removed flags from warnDetachDefault"

This reverts commit 3e4f601.

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Fixed test.NewFakeCli instanciation

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Removed unused receiver

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Replaced cli by dockerCli

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Revert "Removed unused receiver"

This reverts commit 604ef7c.

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>

Fixed last typo

Signed-off-by: Jimmy Leger <jimmy.leger@gmail.com>
@mdlinville
Copy link
Contributor

Ping @thaJeztah

Copy link
Member
@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@thaJeztah thaJeztah merged commit 3c7ede6 into docker:master Aug 19, 2017
@GordonTheTurtle GordonTheTurtle added this to the 17.08.0 milestone Aug 19, 2017
nobiit pushed a commit to nobidev/docker-cli that referenced this pull request Nov 19, 2025
[17.06] update changelog for 17.06.2-ce-rc1 release
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC] Add "docker service rollback" subcommand

7 participants

0