Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Handle multiple compose versions #854

Conversation

silvin-lubecki
Copy link
Contributor

- What I did
A new compose component for Kubernetes version has been released (v1beta2), and I added support for both versions. I also added an Orchestrator section in the docker version command to log the compose component version and Kubernetes version we are working against.

$ docker version
Client:
 Version:       18.02.0-dev
 API version:   1.35 (downgraded from 1.36)
 Go version:    go1.9.3
 Git commit:    0d6a70514
 Built: Wed Jan 31 16:22:38 2018
 OS/Arch:       darwin/amd64
 Experimental:  true
 Orchestrator:  kubernetes

Server:
 Engine:
  Version:      18.01.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   03596f5
  Built:        Wed Jan 10 20:13:12 2018
  OS/Arch:      linux/amd64
  Experimental: true
 Orchestrator:
   Kubernetes:  v1.8.2
   Compose:     v1beta2

- How I did it
I put an interface on the compose client used by docker stack subcommands and added an implementation for each compose version.

- How to verify it

- Description for the changelog

  • New Orchestrator section in docker version command and added support of kubernetes compose component v1beta2

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

@silvin-lubecki silvin-lubecki changed the title Handle multiple compose versions WIP Handle multiple compose versions Jan 31, 2018
@vdemeester vdemeester requested a review from thaJeztah January 31, 2018 17:19
flags.SetAnnotation("namespace", "experimentalCLI", nil)
flags.String("kubeconfig", "", "Kubernetes config file")
flags.SetAnnotation("kubeconfig", "kubernetes", nil)
flags.SetAnnotation("kubeconfig", "experimentalCLI", nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do these need to move to common? They aren't common to both orchestrators

Copy link
Contributor Author

@silvin-lubecki silvin-lubecki Feb 1, 2018

Choose a reason for hiding this comment

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

Well I mostly need kubeconfig (not namespace) to be common, or at least available, for docker version command, as you may specify different kubernetes configs and check the version against the pointed kubernetes.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, but this flag isn't added to the version command, so how is it going to be read?

@codecov-io
Copy link

codecov-io commented Feb 1, 2018

Codecov Report

Merging #854 into master will decrease coverage by 0.45%.
The diff coverage is 23.31%.

@@            Coverage Diff            @@
##           master    #854      +/-   ##
=========================================
- Coverage   53.26%   52.8%   -0.46%     
=========================================
  Files         258     263       +5     
  Lines       16357   16702     +345     
=========================================
+ Hits         8712    8820     +108     
- Misses       7081    7316     +235     
- Partials      564     566       +2

@silvin-lubecki silvin-lubecki force-pushed the handle-multiple-compose-versions branch 2 times, most recently from 933a508 to 60106c6 Compare February 1, 2018 13:55
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.

This is a large PR, and it seems there are two logical changes here. 1) add kube version/stack api version to the API 2) update to include a new API version.

Could you split this into two separate PRs so it's easier to review?

)

// GetAPIVersion returns the most recent stack API installed.
func (c *KubeCli) GetAPIVersion() (StackVersion, error) {
Copy link
Contributor

@dnephin dnephin Feb 1, 2018

Choose a reason for hiding this comment

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

I don't think this should be a method on KubeCLI. It only uses KubeConfig, so it could be just a function which accepts a config and returns the version.

This should make it much easier to use from the version command.

I think it will also remove the need to export KubeConfig

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'll change this.


const (
// StackNotFound is returned when no stack api at all is detected on kubernetes.
StackNotFound = "notFound"
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be an error instead of a string? It looks like it's only used in the error case, so this const probably doesn't need to exist. Just use "".

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! It was only to be consistent with the "enum" values. But "" is fine.

case findVersion(apiv1beta1.SchemeGroupVersion, groups.Groups):
return StackAPIV1Beta1, nil
default:
return StackNotFound, fmt.Errorf("could not find %s api. Install it on your cluster first", apiv1beta1.SchemeGroupVersion.Group)
Copy link
Contributor

Choose a reason for hiding this comment

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

s/fmt.Errorf/errors.Errorf/ (from pkg/errors)

This prints the V1beta1 api version, which might be confusing if the user is expecting to use v2. Maybe it should just say "failed to find a Stack API version" or something like 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.

Done

case StackAPIV1Beta2:
return c.newStackV1Beta2()
default:
return nil, fmt.Errorf("could not find matching Stack API version")
Copy link
Contributor

Choose a reason for hiding this comment

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

s/fmt.Errorf/errors.New/

Maybe something like "No supported Stack API version" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

kubeConfig *restclient.Config
kubeNamespace string
KubeConfig *restclient.Config
KubeNamespace string
}

// WrapCli wraps command.Cli with kubernetes specifics
func WrapCli(dockerCli command.Cli, cmd *cobra.Command) (*KubeCli, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of accepting a *cobra.Command I think this should accept a

type Options struct {
    Namespace string
    Config string
}

the Options struct would be populated by flag parsing before calling WrapCli().

cobra.Command is a huge struct and we don't use anything but a single method (.Flags()), depending on the whole struct makes it harder to re-use (as we can see from the version command).

It should also make the code more obvious. Right now it's assumed that this will get the flag value, but in reality, when used with a different cmd the flag is never presented to the user, so the flag will never be set.

@@ -75,12 +82,21 @@ type clientVersion struct {
Orchestrator string `json:",omitempty"`
}

type kubernetesVersion struct {
Kubernetes string
ComposeAPI string
Copy link
Contributor

Choose a reason for hiding this comment

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

StackAPI not ComposeAPI

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

}

apiVersion, err := kli.GetAPIVersion()
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.

If this fails it should still attempt to get the kube version, so maybe this should be split into two functions.

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, done

return nil, nil
}

kli, err := kubernetes.WrapCli(dockerCli, cmd)
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of WrapCLI() if this could call a method that returns KubeConfig then it can be used for both GetAPIVersion and getting a kubeClient without the need for KubeCli.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -109,7 +125,7 @@ func reformatDate(buildTime string) string {
return buildTime
}

func runVersion(dockerCli command.Cli, opts *versionOptions) error {
func runVersion(dockerCli command.Cli, cmd *cobra.Command, opts *versionOptions) error {
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 not be passing in cobra.Command to the run functions. With the other suggestions (refactoring to remove the need to use KubeCli to get version, and getting the kube config from a path string arg instead of flags this shouldn't be necessary any more and can be reverted.

@@ -52,25 +51,27 @@ func WrapCli(dockerCli command.Cli, cmd *cobra.Command) (*KubeCli, error) {
if err != nil {
return nil, fmt.Errorf("Failed to load kubernetes configuration file '%s'", kubeConfig)
}
cli.kubeConfig = config
cli.KubeConfig = config
Copy link
Contributor

Choose a reason for hiding this comment

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

Related to other changes, this "get KubeConfig from flag or env" can be extracted into a function that just takes a single path string argument.

@silvin-lubecki
Copy link
Contributor Author

@dnephin Let me just fix your comments before I split it into 2 PR? Otherwise they may "disappear".

@@ -1,4 +0,0 @@
# Kubernetes client libraries
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should not remove that 👼

yaml "gopkg.in/yaml.v2"
)

// Scale scale a service to the specified number of replicas
Copy link
Collaborator

Choose a reason for hiding this comment

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

v1beta1 didn't support scale, it should still not support it (i.e. it comes in v1beta2).. so this should not be required

type Stack struct {
StackImpl
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this is required at all 🤔 (there shouldn't be any code change in v1beta1)

@silvin-lubecki silvin-lubecki force-pushed the handle-multiple-compose-versions branch 4 times, most recently from f14ed2f to 68e09cb Compare February 21, 2018 16:45
…nent version in docker version command.

Signed-off-by: Silvin Lubecki <[email protected]>
* Upgrade v1beta1 client to remove generated code

Signed-off-by: Silvin Lubecki <[email protected]>
…use it kubernetes stack commands

Signed-off-by: Silvin Lubecki <[email protected]>
Signed-off-by: Silvin Lubecki <[email protected]>
* Remove dependency from command in Kubernetes version checker

Signed-off-by: Silvin Lubecki <[email protected]>
Signed-off-by: Silvin Lubecki <[email protected]>
* Refactor the internal stack model to use the v1beta2 stack model instead of compose type config

Signed-off-by: Silvin Lubecki <[email protected]>
@silvin-lubecki silvin-lubecki force-pushed the handle-multiple-compose-versions branch from 68e09cb to 2e8f25d Compare February 22, 2018 10:37
@silvin-lubecki
Copy link
Contributor Author

Split and reopened in #898 and #899

@silvin-lubecki silvin-lubecki deleted the handle-multiple-compose-versions branch May 30, 2018 14:29
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.

5 participants