Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Transform docker-app as a docker-cli plugin #469

Merged
merged 12 commits into from
Mar 8, 2019

Conversation

silvin-lubecki
Copy link
Contributor

- What I did
Transform docker-app as a docker-cli plugin using docker-cli helpers.

Add a new binary docker-app-standalone which is in fact the old docker-app before its pluginization.

Now each released tar.gz file per os comes with two binaries in it:

  • docker-app-plugin-{linux|darwin|windows}
  • docker-app-standalone-{linux|darwin|windows}

- How to verify it

With a master docker-cli built on your own:

$ make bin/docker-app
$ mkdir ~/.docker/cli-plugins && cp bin/docker-app ~/.docker/cli-plugins
$ docker
...
Management Commands:
  app*        Docker Application Packages (Docker Inc., v0.6.0...)
...

- Description for the changelog

  • Transform docker-app as a docker-cli plugin

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

Gopkg.toml Outdated
@@ -29,7 +29,7 @@ required = ["github.com/wadey/gocovmerge"]

[[override]]
name = "github.com/docker/cli"
revision = "f95ca8e1ba6c22c9abcdbf65e8dcc39c53958bba"
revision = "3ddb3133f5b5a74dd4e3f721ced21f4d0b9651b6"
Copy link
Contributor

Choose a reason for hiding this comment

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

(random location for comment on commit message)

The first commit here is titled Bump docker-cli to include the plugin work but actually it does far more than that -- it actually match the switch to being a plugin. I'd suggest a title like "Refactor as a CLI plugin" (or "Convert to...") and leave the mention of the CLI bump in the body of the commit message.

Copy link
Contributor

Choose a reason for hiding this comment

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

Another commit is rendered as:

Add a new binary docker-app-standalone which is in fact the old docke…
…r-app before its pluginization.

i.e. the first line (summary) is too long. I think:

Add a new binary docker-app-standalone

This is  in fact the old docker-app before its pluginization.
...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 👍

e2e/cnab_test.go Outdated
Env: []string{fmt.Sprintf("DUFFLE_HOME=%s", tmpDir.Path())},
Env: append(os.Environ(),
fmt.Sprintf("DUFFLE_HOME=%s", tmpDir.Path()),
fmt.Sprintf(manager.ReexecEnvvar+"="+dockerCli)),
Copy link
Contributor

Choose a reason for hiding this comment

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

IIRC since I did the PoC port in in #433 these tests now build a local dockerCli (because of the context stuff) and so that should be "plugin enabled" and IMHO we should use it here instead of doing this workaround.

Basically where below you transform []string{dockerApp, "install" into []string{dockerApp, "app", "install" you should instead transform it to []string{dockerCli, "app", "install" having arranged for the plugin binary to be in ${DOCKER_CONFIG}/cli-plugins or setup ``${DOCKER_CONFIG}/config.json` so it includes the right path.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you built most of the scaffolding you need for TestInvokePluginFromCLI below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep indeed we should test docker-app as a plugin, called by the CLI, as it is now the preferred way to use docker-app. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 👍

validate Checks the rendered application is syntactically correct
version Print version information

Run 'docker app COMMAND --help' for more information on a command.`
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 you should use golden for this block

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 👍

@@ -31,7 +31,7 @@ func findApp() (string, error) {
for _, c := range content {
if strings.HasSuffix(c.Name(), internal.AppExtension) {
if hit != "" {
return "", fmt.Errorf("multiple applications found in current directory, specify the application name on the command line")
return "", fmt.Errorf("Error: multiple applications found in current directory, specify the application name on the command line")
Copy link
Contributor

Choose a reason for hiding this comment

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

Elsewhere we needed to remove the Error: prefix (because core plugin framework deals with it), so is this case correct (doesn't result in Error: Error:)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's an e2e test which checks this error. It failed until I added this "Error: "...

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right, I even realised this in my WIP PR where I wrote in the commit message:

    Finally, the idiom in docker/cli (for better or worse) is to include an "Error:
    " prefix in the error string itself, rather than injecting it when printing.
    Since CLI plugins follow the behaviour of the CLI here it is necessary to
    prepend "Error: " to some messages. I've only done exactly those necessary to
    pass the e2e tests, a fuller audit is very likely required.
    

(and then forgot about it, obviously)

Feel free to steal some or all of my words for your commit message.

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 let this fuller audit as an exercise for the reviewers :trollface:

cmd := &cobra.Command{
Use: "app",
// NewRootCmd returns the base root command.
func NewRootCmd() *cobra.Command {
Copy link
Contributor

Choose a reason for hiding this comment

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

Either add to the comment users must set the Use field on the result or make it an argument and deal with it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I could have done that 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 👍

Short: "Docker Application Packages",
Long: `Build and deploy Docker Application Packages.`,
}
addCommands(cmd, dockerCli)
Copy link
Contributor

Choose a reason for hiding this comment

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

Both callers do app.AddCommands(cmd, dockerCli) on the result -- maybe just pass dockerCli as an argument and do it here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 👍

docker.Makefile Show resolved Hide resolved
@silvin-lubecki silvin-lubecki force-pushed the cli-plugin branch 2 times, most recently from 911065d to f1c7f52 Compare February 28, 2019 16:06
@ijc
Copy link
Contributor

ijc commented Mar 1, 2019

At least the pr-merge CI job is suffering from docker/cli#1654 (comment) (that CI has a daemon <18.09). Awaiting maintainer feedback before deciding how to address.

@ijc
Copy link
Contributor

ijc commented Mar 1, 2019

pr-head seems to be a different problem (at least so far), vendoring is unclean apparently:


These files were changed:

 M vendor/github.com/docker/cli/cli/command/cli.go

@jcsirot jcsirot force-pushed the cli-plugin branch 4 times, most recently from 48b7ac0 to 44d0886 Compare March 4, 2019 09:19
@ulyssessouza ulyssessouza force-pushed the cli-plugin branch 10 times, most recently from 97f22cf to 98407b9 Compare March 5, 2019 17:32
@ulyssessouza ulyssessouza force-pushed the cli-plugin branch 3 times, most recently from a72c61e to 4b49845 Compare March 7, 2019 12:46
@codecov
Copy link

codecov bot commented Mar 7, 2019

Codecov Report

Merging #469 into master will increase coverage by 0.02%.
The diff coverage is 94.44%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #469      +/-   ##
==========================================
+ Coverage   69.38%   69.41%   +0.02%     
==========================================
  Files          50       50              
  Lines        2515     2501      -14     
==========================================
- Hits         1745     1736       -9     
+ Misses        540      537       -3     
+ Partials      230      228       -2
Impacted Files Coverage Δ
internal/commands/bundle.go 66.07% <ø> (ø)
internal/commands/validate.go 88.88% <ø> (ø)
internal/commands/split.go 80% <ø> (ø)
internal/commands/pull.go 80% <ø> (ø)
internal/commands/init.go 100% <ø> (ø)
internal/commands/render.go 57.5% <ø> (ø)
internal/commands/merge.go 61.01% <ø> (ø)
internal/commands/completion.go 48.48% <ø> (ø)
internal/commands/push.go 38.6% <ø> (ø)
internal/commands/parameters.go 90.69% <ø> (ø)
... and 10 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 36fd67f...30fda72. Read the comment docs.

@ulyssessouza ulyssessouza force-pushed the cli-plugin branch 2 times, most recently from 7f7e65c to 6b31ce3 Compare March 7, 2019 13:26
Copy link
Member

@chris-crone chris-crone left a comment

Choose a reason for hiding this comment

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

Just minor changes

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved

### Linux or macOS

Download your OS tarball:
```bash
export OSTYPE="$(uname | tr A-Z a-z)"
curl -fsSL --output "/tmp/docker-app-${OSTYPE}.tar.gz" "https://github.com/docker/app/releases/download/v0.6.0/docker-app-${OSTYPE}.tar.gz"
Copy link
Member

Choose a reason for hiding this comment

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

Must remember to bump the version when we do a release.

README.md Outdated
```


**Note:** To use Application Packages as images (i.e.: `save`, `push`, or `install` when package is not present locally) on Windows, one must be in Linux container mode.
Copy link
Member

Choose a reason for hiding this comment

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

For this PR, there is no applications as images.

Copy link
Member

Choose a reason for hiding this comment

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

(We can clean this up after Simon's push/pull PR is merged)

e2e/main_test.go Outdated Show resolved Hide resolved
Copy link
Member

@chris-crone chris-crone 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 @ulyssessouza and @silvin-lubecki!

Copy link
Contributor

@simonferquel simonferquel left a comment

Choose a reason for hiding this comment

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

A few nits

Gopkg.toml Outdated
@@ -27,9 +27,15 @@ required = ["github.com/wadey/gocovmerge"]
name = "github.com/opencontainers/runc"
version = "v1.0.0-rc6"

#[[override]]
Copy link
Contributor

Choose a reason for hiding this comment

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

remove commented vendoring

Copy link
Member

Choose a reason for hiding this comment

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

Done

icmd.RunCmd(cmd).Assert(t, icmd.Success)
}

func TestBundle(t *testing.T) {
tmpDir := fs.NewDir(t, t.Name())
defer tmpDir.Remove()
// Using a custom DOCKER_CONFIG to store contexts in a temporary directory
cmd := icmd.Cmd{Env: append(os.Environ(), "DOCKER_CONFIG="+tmpDir.Path())}
cmd := icmd.Cmd{Env: os.Environ()}
Copy link
Contributor

Choose a reason for hiding this comment

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

need to patch DOCKER_CONFIG here

Copy link
Member

Choose a reason for hiding this comment

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

This has been reworked so that we use a new config dir for each test.

We can actually remove the Env: os.Environ() as it's redundant. Let's do so in a followup @ulyssessouza

Copy link
Contributor

Choose a reason for hiding this comment

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

Looked at the new dir for each test thing. The main problem is that it changes the environment for the whole test project, while only the child processes we invoke require these environment variables changes. Also, this dockerCli global variable makes it impossible to run tests in parallel.

internal/commands/inspect.go Outdated Show resolved Hide resolved
internal/commands/install.go Show resolved Hide resolved
Dockerfile Outdated
@@ -8,7 +8,10 @@ RUN apt-get install -y -q --no-install-recommends \

WORKDIR /go/src/github.com/docker/cli

RUN git clone https://github.com/docker/cli.git .
RUN git clone https://github.com/ulyssessouza/cli . && git checkout 29d30ec1a05e8a285007240cc0f85864067e7344
# FIXME(ulyssessouza): Go back to the line below when PRs https://github.com/docker/cli/pull/1710 and https://github.com/docker/cli/pull/1690 hits the cli
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to change, but it might actually end up being docker/cli#1718 in preference to docker/cli#1710

Copy link
Member

Choose a reason for hiding this comment

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

I made this change in my rebase

Gopkg.toml Outdated
[[override]]
name = "github.com/docker/cli"
revision = "f95ca8e1ba6c22c9abcdbf65e8dcc39c53958bba"
source = "https://github.com/ulyssessouza/cli"
revision="29d30ec1a05e8a285007240cc0f85864067e7344"
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop the first commented out one and write:

[[override]]
  name = "github.com/docker/cli"
  revision = "f95ca8e1ba6c22c9abcdbf65e8dcc39c53958bba"
  ### Waiting on PR https://github.com/docker/cli/pull/1710 to land on cli ###
  source = "https://github.com/ulyssessouza/cli"
  revision="29d30ec1a05e8a285007240cc0f85864067e7344"

there's no need to keep the other staza around,it's not a useful reference.

"--description", "my cool app",
"--maintainer", "bob",
"--maintainer", "joe:joe@joe.com",
"--single-file",
Copy link
Contributor

Choose a reason for hiding this comment

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

These are due to docker/cli#1699 I think?

You didn't actually remove the short versions so there is no followup to do when that is fixed, right?

Copy link
Member

Choose a reason for hiding this comment

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

Yep, that's correct

silvin-lubecki and others added 11 commits March 8, 2019 11:59
* Use the docker/cli/cli-plugins/plugin.Run helper to create and execute the commands as a plugin
* Refactor e2e tests to use “docker app” (docker cli invoking docker-app plugin)
* Add CLI plugin invocation e2e tests
* Bump docker-cli to include the plugin work
* Bump gotest.tools to 2.3.0

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
…can be re-used by another binary.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
This is in fact the old docker-app before its pluginization.
Added it to cross compilation
Now each released tar.gz file per os comes with two binaries in it: docker-app-plugin-os and docker-app-standalone-os

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
* Update windows installation too, which seems obsolete

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
Perform the git clone and a chechout to avoid
that a Dockerfile cache and enforce determinism

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
- Update docker/cli is now pointing to chris-crone/cli.
The change needs the merge of docker/cli#1718
and docker/cli#1690
- Fix issues relative paths in Jenkinsfile and Jenkinsfile.baguette
- Avoid using '--config' in favor of env variable 'DOCKER_CONFIG'

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
e2e/main_test.go Outdated
panic(err)
}
err = os.Setenv("DOCKER_CONFIG", configDir)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to change the current process environment car but only impact the child process environment (setting this on the process level makes actually tests having huge side effects, preventing them to run in parallel in the future)

Copy link
Contributor

Choose a reason for hiding this comment

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

The common rule for this kind of member function of a globally shared object is that it should not have side effects on the current process shared state (e.g. should not change process-wide environement variable).

It should return 2 values:

  • one string for the config dir
  • one map[string]string usable to set child processes environment

Copy link
Member

Choose a reason for hiding this comment

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

Instead of this I've renamed the function createTestCmd, it returns an icmd.Command with the Env prefilled and a cleanup function.

icmd.RunCmd(cmd).Assert(t, icmd.Success)
}

func TestBundle(t *testing.T) {
tmpDir := fs.NewDir(t, t.Name())
defer tmpDir.Remove()
// Using a custom DOCKER_CONFIG to store contexts in a temporary directory
cmd := icmd.Cmd{Env: append(os.Environ(), "DOCKER_CONFIG="+tmpDir.Path())}
cmd := icmd.Cmd{Env: os.Environ()}
Copy link
Contributor

Choose a reason for hiding this comment

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

Looked at the new dir for each test thing. The main problem is that it changes the environment for the whole test project, while only the child processes we invoke require these environment variables changes. Also, this dockerCli global variable makes it impossible to run tests in parallel.

internal/commands/install.go Show resolved Hide resolved
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
Copy link
Contributor

@simonferquel simonferquel left a comment

Choose a reason for hiding this comment

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

lgtm

@simonferquel simonferquel merged commit 207a945 into docker:master Mar 8, 2019
@silvin-lubecki silvin-lubecki deleted the cli-plugin branch March 26, 2019 15:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants