diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index 56074f576..d9c63ce3e 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -48,6 +48,7 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil; import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty; import org.springframework.ide.vscode.commons.yaml.schema.YValueHint; import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema; +import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint; import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraints; import org.springframework.ide.vscode.concourse.ConcourseModel.ResourceModel; import org.springframework.ide.vscode.concourse.ConcourseModel.StepModel; @@ -596,6 +597,12 @@ public class PipelineYmlSchema implements YamlSchema { } //docker-image: { + + AbstractType registry_mirror = f.ybean("RegistryMirror"); + addProp(registry_mirror, "host", t_ne_string).isPrimary(true); + addProp(registry_mirror, "username", t_ne_string); + addProp(registry_mirror, "password", t_ne_string); + AbstractType source = f.ybean("DockerImageSource"); addProp(source, "repository", t_ne_string).isPrimary(true); addProp(source, "tag", t_ne_string); @@ -605,7 +612,7 @@ public class PipelineYmlSchema implements YamlSchema { addProp(source, "aws_secret_access_key", t_ne_string); addProp(source, "aws_session_token", t_ne_string); addProp(source, "insecure_registries", t_strings); - addProp(source, "registry_mirror", t_ne_string); + addProp(source, "registry_mirror", registry_mirror); addProp(source, "ca_certs", f.yseq(f.ybean("CaCertsEntry", f.yprop("domain", t_ne_string), f.yprop("cert", t_ne_string) diff --git a/headless-services/concourse-language-server/src/main/resources/desc/DockerImageSource/registry_mirror.md b/headless-services/concourse-language-server/src/main/resources/desc/DockerImageSource/registry_mirror.md index 01e59e6f1..92d86c170 100644 --- a/headless-services/concourse-language-server/src/main/resources/desc/DockerImageSource/registry_mirror.md +++ b/headless-services/concourse-language-server/src/main/resources/desc/DockerImageSource/registry_mirror.md @@ -1 +1 @@ -*Optional.* A URL pointing to a docker registry mirror service. +*Optional.* Hostname and credentials pointing to a docker registry mirror service. diff --git a/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/host.md b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/host.md new file mode 100644 index 000000000..440654197 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/host.md @@ -0,0 +1 @@ +A hostname pointing to a Docker registry mirror service. Note that this is only used if no registry hostname prefix is specified in the `repository` key. If the `repository` contains a registry hostname, such as `my-registry.com/foo/bar`, the `registry_mirror` is ignored and the explicitly declared registry in the `repository` key is used. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/password.md b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/password.md new file mode 100644 index 000000000..1c4c2c7f2 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/password.md @@ -0,0 +1 @@ +A password to use when authenticating to the mirror. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/username.md b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/username.md new file mode 100644 index 000000000..b92699c22 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/RegistryMirror/username.md @@ -0,0 +1 @@ +A username to use when authenticating to the mirror. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java index e5daeb706..66d5fb2c6 100644 --- a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java +++ b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java @@ -74,6 +74,31 @@ public class ConcourseEditorTest { serverInitializer.setMaxCompletions(100); } + @Test public void GH_752_repo_mirror() throws Exception { + //See: + // - https://github.com/concourse/registry-image-resource#:~:text=registry_mirror%3A%20Optional. + // - https://github.com/spring-projects/sts4/issues/752 + Editor editor = harness.newEditor(LanguageId.CONCOURSE_TASK, + "platform: linux\n" + + "image_resource:\n" + + " type: docker-image\n" + + " source:\n" + + " repository: alpine\n" + + " tag: latest\n" + + " registry_mirror:\n" + + " host: my-registry.com\n" + + " username: myuser\n" + + " password: mypass\n" + + " bad: unknown\n" + + "run:\n" + + " path: sh\n" + + " args:\n" + + " - -exc\n" + + " - sleep 60\n" + ); + editor.assertProblems("bad|Unknown"); + } + @Test public void GH_639_globStar() throws Exception { Editor editor = harness.newEditor( "groups:\n" + @@ -2351,12 +2376,15 @@ public class ConcourseEditorTest { " repository: kdvolder/sts4-build-env\n" + " tag: latest\n" + " username: kdvolder\n" + - " password: {{docker_password}}\n" + + " password: {{docker_pass}}\n" + " aws_access_key_id: {{aws_access_key}}\n" + " aws_secret_access_key: {{aws_secret_key}}\n" + " aws_session_token: ((aws_token))\n" + " insecure_registries: no-list\n" + - " registry_mirror: https://my-docker-registry.com\n" + + " registry_mirror:\n" + + " host: dockermirror.com\n" + + " username: mirroruser\n" + + " password: ((mirror_pass))\n" + " max_concurrent_downloads: num-down\n" + " max_concurrent_uploads: num-up\n" + " ca_certs:\n" + @@ -2395,7 +2423,11 @@ public class ConcourseEditorTest { editor.assertHoverContains("aws_secret_access_key", "AWS secret key to use"); editor.assertHoverContains("aws_session_token", "AWS session token (assumed role)"); editor.assertHoverContains("insecure_registries", "array of CIDRs"); - editor.assertHoverContains("registry_mirror", "URL pointing to a docker registry"); + editor.assertHoverContains("registry_mirror", "Hostname and credentials pointing to a docker registry mirror service"); + editor.assertHoverContains("host", "hostname pointing to a Docker registry mirror service"); + editor.assertHoverContains("username", 2, "username to use when authenticating to the mirror"); + editor.assertHoverContains("password", 2, "password to use when authenticating to the mirror"); + editor.assertHoverContains("ca_certs", "Each entry specifies the x509 CA certificate for"); editor.assertHoverContains("client_certs", "Each entry specifies the x509 certificate and key"); editor.assertHoverContains("max_concurrent_downloads", "Limits the number of concurrent download threads"); diff --git a/headless-services/concourse-language-server/src/test/resources/workspace/gh_752_task.yml b/headless-services/concourse-language-server/src/test/resources/workspace/gh_752_task.yml new file mode 100644 index 000000000..698aef522 --- /dev/null +++ b/headless-services/concourse-language-server/src/test/resources/workspace/gh_752_task.yml @@ -0,0 +1,16 @@ +platform: linux +image_resource: + type: docker-image + source: + repository: alpine + tag: latest + registry_mirror: + host: my-registry.com + username: myuser + password: mypass + bad: unknown +run: + path: sh + args: + - -exc + - sleep 60