diff --git a/cmd/weaver-kube/deploy.go b/cmd/weaver-kube/deploy.go index 8bf8895..9382eda 100644 --- a/cmd/weaver-kube/deploy.go +++ b/cmd/weaver-kube/deploy.go @@ -43,40 +43,36 @@ var ( Name: "deploy", Description: "Deploy a Service Weaver app", Help: `Usage: - weaver kube deploy + weaver kube deploy Flags: -h, --help Print this help message. Container Image Names: "weaver kube deploy" builds a container image locally, and optionally uploads - it to a container repository. The repository can be specified using the - "repo" field inside the "kube" section of the config file. For example, - consider the following config file: + it to a container repository. The name of the image and the repository to + which the image is uploaded are specified using the "image" and "repo" fields + inside the "kube" section of the config file. For example, consider the + following config file: [serviceweaver] binary = "./foo" [kube] - tag = "foo/foo:0.0.1" - repo = "docker.io/my_docker_hub_username/my_repo" - - Using this config file, "weaver kube deploy" will build a container - with a local build tag [1] "foo/foo:0.0.1", and upload it to the - "docker.io/my_docker_hub_username/my_repo" repository. If the "tag" is not - specified, it defaults to ":. If the "repo" - is not specified, the container is not uploaded and must be pushed - manually to the Kubernetes environments. - + image = "foo:0.0.1" + repo = "docker.io/my_docker_hub_username" + + Using this config file, "weaver kube deploy" will build an image named + "foo:0.0.1" and upload it to "docker.io/my_docker_hub_username/foo:0.0.1". If + the "image" field is not specified, the image name defaults to + ":". If the "repo" field is not specified, the + container is not uploaded. + Example repositories are: - - Docker Hub: docker.io/USERNAME/REPO_NAME - - Google Artifact Registry: LOCATION-docker.pkg.dev/PROJECT-ID/REPO_NAME - - GitHub Container Registry: ghcr.io/NAMESPACE - - Note that the final image tag for the application container will - be a concatenation of repo and tag fields, i.e., "repo/tag". - - [1]: https://docs.docker.com/engine/reference/commandline/tag/`, + + - Docker Hub: docker.io/USERNAME + - Google Artifact Registry: LOCATION-docker.pkg.dev/PROJECT-ID + - GitHub Container Registry: ghcr.io/NAMESPACE`, Flags: flags, Fn: deploy, } @@ -144,7 +140,7 @@ func deploy(ctx context.Context, args []string) error { } // Build the docker image for the deployment. - image, err := impl.BuildAndUploadDockerImage(ctx, dep, config.LocalTag, config.Repo) + image, err := impl.BuildAndUploadDockerImage(ctx, dep, config.Image, config.Repo) if err != nil { return err } @@ -183,13 +179,13 @@ func checkVersionCompatibility(appBinary string) error { github.com/ServiceWeaver/weaver module version %s. However, the 'weaver-kube' binary you're using was built with weaver module version %s. These versions are incompatible. - + We recommend updating both the weaver module your application is built with and updating the 'weaver-kube' command by running the following. - + go get github.com/ServiceWeaver/weaver@latest go install github.com/ServiceWeaver/weaver-kube/cmd/weaver-kube@latest - + Then, re-build your code and re-run 'weaver-kube deploy'. If the problem persists, please file an issue at https://github.com/ServiceWeaver/weaver/issues`, relativize(appBinary), versions.ModuleVersion, selfVersion) diff --git a/internal/impl/docker.go b/internal/impl/docker.go index 0f74787..deaaea3 100644 --- a/internal/impl/docker.go +++ b/internal/impl/docker.go @@ -51,17 +51,17 @@ ENTRYPOINT ["/weaver/weaver-kube"] // buildSpec holds information about a container image build. type buildSpec struct { - tag string // tag is the container build tag + image string // container image name files []string // files that should be copied to the container goInstall []string // binary targets that should be 'go install'-ed } // BuildAndUploadDockerImage builds a docker image and uploads it to a remote -// repo, if one is specified. It returns the docker image tag that should -// be used in the application containers. -func BuildAndUploadDockerImage(ctx context.Context, dep *protos.Deployment, buildTag, dockerRepo string) (string, error) { +// repo, if one is specified. It returns the image name that should be used in +// Kubernetes YAML files. +func BuildAndUploadDockerImage(ctx context.Context, dep *protos.Deployment, image, repo string) (string, error) { // Create the build specifications. - spec, err := dockerBuildSpec(dep, buildTag) + spec, err := dockerBuildSpec(dep, image) if err != nil { return "", fmt.Errorf("unable to build image spec: %w", err) } @@ -71,18 +71,18 @@ func BuildAndUploadDockerImage(ctx context.Context, dep *protos.Deployment, buil return "", fmt.Errorf("unable to create image: %w", err) } - tag := spec.tag - if dockerRepo != "" { + image = spec.image + if repo != "" { // Push the docker image to the repo. - if tag, err = pushImage(ctx, tag, dockerRepo); err != nil { + if image, err = pushImage(ctx, image, repo); err != nil { return "", fmt.Errorf("unable to push image: %w", err) } } - return tag, nil + return image, nil } // dockerBuildSpec creates a build specification for an app deployment. -func dockerBuildSpec(dep *protos.Deployment, buildTag string) (*buildSpec, error) { +func dockerBuildSpec(dep *protos.Deployment, image string) (*buildSpec, error) { // Figure out which tool binary will run inside the container. toolVersion, toolIsDev, err := ToolVersion() if err != nil { @@ -116,12 +116,12 @@ downloaded and installed in the container. Do you want to proceed? [Y/n] `) toInstall = append(toInstall, "github.com/ServiceWeaver/weaver-kube/cmd/weaver-kube@"+toolVersion) } - if buildTag == "" { - buildTag = fmt.Sprintf("%s:%s", dep.App.Name, dep.Id[:8]) + if image == "" { + image = fmt.Sprintf("%s:%s", dep.App.Name, dep.Id[:8]) } return &buildSpec{ - tag: buildTag, + image: image, files: toCopy, goInstall: toInstall, }, nil @@ -129,7 +129,7 @@ downloaded and installed in the container. Do you want to proceed? [Y/n] `) // buildImage builds a docker image with a given spec. func buildImage(ctx context.Context, spec *buildSpec) error { - fmt.Fprintf(os.Stderr, greenText(), fmt.Sprintf("Building image %s...", spec.tag)) + fmt.Fprintf(os.Stderr, greenText(), fmt.Sprintf("Building image %s...", spec.image)) // Create: // workDir/ // file1 @@ -167,24 +167,24 @@ func buildImage(ctx context.Context, spec *buildSpec) error { if err := dockerFile.Close(); err != nil { return err } - return dockerBuild(ctx, workDir, spec.tag) + return dockerBuild(ctx, workDir, spec.image) } -// dockerBuild builds a docker image given a directory and an image tag. -func dockerBuild(ctx context.Context, dir, tag string) error { - fmt.Fprintln(os.Stderr, "Building with tag:", tag) - c := exec.CommandContext(ctx, "docker", "build", dir, "-t", tag) +// dockerBuild builds a docker image given a directory and an image name. +func dockerBuild(ctx context.Context, dir, image string) error { + fmt.Fprintln(os.Stderr, "Building image ", image) + c := exec.CommandContext(ctx, "docker", "build", dir, "-t", image) c.Stdout = os.Stderr c.Stderr = os.Stderr return c.Run() } -// pushImage pushes a docker image with a given build tag to a docker -// repository, returning its tag in the repository. -func pushImage(ctx context.Context, tag, repo string) (string, error) { +// pushImage pushes the provided docker image to the provided repo, returning +// the repo-qualified image name. +func pushImage(ctx context.Context, image, repo string) (string, error) { fmt.Fprintf(os.Stderr, greenText(), fmt.Sprintf("\nUploading image to %s...", repo)) - repoTag := path.Join(repo, tag) - cTag := exec.CommandContext(ctx, "docker", "tag", tag, repoTag) + repoTag := path.Join(repo, image) + cTag := exec.CommandContext(ctx, "docker", "tag", image, repoTag) cTag.Stdout = os.Stderr cTag.Stderr = os.Stderr if err := cTag.Run(); err != nil { diff --git a/internal/impl/kube.go b/internal/impl/kube.go index f3a11fd..5068b61 100644 --- a/internal/impl/kube.go +++ b/internal/impl/kube.go @@ -93,28 +93,27 @@ type ListenerOptions struct { // KubeConfig stores the configuration information for one execution of a // Service Weaver application deployed using the Kube deployer. type KubeConfig struct { - // LocalTag is the build tag for the application container on the local - // machine. + // Image is the name of the container image hosting the Service Weaver + // application. // - // If empty, the tag defaults to ":", where - // is the unique version id of the application deployment. - LocalTag string `toml:"local_tag"` - - // Repo is the name of the repository the container should be uploaded to. - // For example, if set to "docker.io/alanturing/repo", "weaver kube deploy" - // will build the container locally, tag it with the appropriate Tag, and - // then push it to "docker.io/alanturing/repo". + // If empty, the image name defaults to ":", where + // is the name of the app, and is the unique + // version id of the application deployment. + Image string + + // Repo is the name of the repository where the container image is uploaded. // - // If empty, the container is built and tagged locally, but is not pushed - // to a repository. + // For example, if Image is "mycontainer:v1" and Repo is + // "docker.io/alanturing", then "weaver kube deploy" will build the image + // locally as "mycontainer:v1" and then push it to + // "docker.io/alanturing/mycontainer:v1". // - // Example repositories are: - // - Docker Hub : docker.io/USERNAME/REPO_NAME - // - Google Artifact Registry : LOCATION-docker.pkg.dev/PROJECT-ID/REPO_NAME - // - GitHub Container Registry: ghcr.io/NAMESPACE + // If empty, the image is not pushed to a repository. // - // Note that the final image tag for the application container will - // be a concatenation of Repo and Tag, i.e., "Repo/Tag". + // Example repositories are: + // - Docker Hub : docker.io/USERNAME + // - Google Artifact Registry : LOCATION-docker.pkg.dev/PROJECT-ID + // - GitHub Container Registry : ghcr.io/NAMESPACE Repo string // Namespace is the name of the Kubernetes namespace where the application