Extracting image tag from GCR Pub/Sub trigger (Kubernetes V1 provider) [solved]


#1

Goal

I have a simple pipeline that consists of “Docker Registry” trigger (that is triggered whenever a new image gets pushed to a registry) and Kubernetes V1 “Deploy” step that deploys that new image to a cluster. To reduce polling load on GCR I’d like to use a “Pub/Sub” trigger instead of “Docker Registry”

Problem

I’m following the guide to trigger my pipelines using Pub/Sub messages from GCR.

The triggering itself works well: my pipeline is started as soon as a new image is pushed to GCR. But I cannot figure out how to use the new tag/digest in a subsequent deployment phase to deploy the new image to a Kubernetes cluster.

If a pipeline is started using “Docker registry” trigger then subsequent deployment step can contain:

              "imageDescription": {
                "account": "gcr-bolcom-sbx-vso-sbx-dpitc-e18",
                "fromTrigger": true,
                "imageId": "eu.gcr.io/bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot (Tag resolved at runtime)",
                "registry": "eu.gcr.io",
                "repository": "bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot"
              },

If I insert the same section into a pipeline that has “Pub/Sub” trigger I get “No tag found for image eu.gcr.io/bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot in trigger context.” when the pipeline is started. Also I don’t see any ways to set it up via UI.

So how can I setup my pipeline with Pub/Sub trigger to be able use image tag in deployment stage(s)?

I’m using Spinnaker 1.8.5.


Using PubSub for GCR Trigger [solved]
#2

@briananderson1222 any ideas?


#3

@wheleph : One option would be to configure the docker image as an expected artifact of the Pub/Sub trigger. I’ve you’ve configured the pubsub subscription with a messageFormat of GCR then the message will automatically inflate an artifact upon being received by Spinnaker.

You can then select that artifact from the deploy stage, and it will automatically bind to the tag that was used to trigger the pipeline.

You mentioned that you’re using Spinnaker 1.8.5—the ability to reference an artifact in the deploy stage of the V1 Kubernetes provider was only added in Spinnaker 1.9 so you’d need to upgrade if you want to use this workflow.


#4

@ezimanyi your suggestion does work! After upgrade to Spinnaker 1.9.2 I was able to reference artifacts in deploy stages.

However if I want to trigger the pipeline manually by pressing “Start Manual Execution” in Spinnaker UI, it fails because there’s no input field to specify image tag. To fix it I added “Docker Registry” trigger so my pipeline trigger config looks like this:

  "triggers": [
    {
      "attributeConstraints": {},
      "enabled": true,
      "expectedArtifactIds": [
        "15fd9fd4-7f5b-4236-bc79-3165f5fedada"
      ],
      "payloadConstraints": {},
      "pubsubSystem": "google",
      "subscriptionName": "gcr-manual-subscription-with-sa",
      "type": "pubsub"
    },
    {
      "account": "gcr-bolcom-sbx-vso-sbx-dpitc-e18",
      "enabled": false,
      "expectedArtifactIds": [
        "15fd9fd4-7f5b-4236-bc79-3165f5fedada"
      ],
      "organization": "bolcom-sbx-vso-sbx-dpitc-e18",
      "registry": "eu.gcr.io",
      "repository": "bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot",
      "type": "docker"
    }
  ],

That trigger is disabled to avoid conflicts with “Pub/Sub”. Otherwise if a new image is pushed to the registry then the pipeline is triggered twice: 1 per each trigger.

I this case I can specify a tag when triggering pipeline manually:
27%20PM

Is there a way to do it with only a “Pub/Sub” trigger?


#5

@wheleph: There is not currently a way to do this with Pub/Sub triggers. Being able to inject artifacts into manual executions is something that isn’t yet supported in the general case, but is something that we’re definitely looking at as we work on improving artifact support. So for now, using a workaround for manual triggers is probably the only approach.

That being said, I’m not sure the workaround you’ve describe will completely work. The docker trigger doesn’t convert the tag into an artifact, so if the deploy stage is referencing the artifact, it won’t be able to deploy when the manual trigger is used. Though let me know if I’m mis-understanding and this is somehow working!


#6

@ezimanyi, the workaround I described above works for me: my pipeline is triggered automatically by a Pub/Sub trigger and also can be triggered manually through Docker Registry trigger.

Here’s the pipeline definition:

{
  "appConfig": {},
  "expectedArtifacts": [
    {
      "defaultArtifact": {
        "kind": "custom"
      },
      "id": "40c32339-d021-410b-8837-cdad4c8b86d7",
      "matchArtifact": {
        "kind": "docker",
        "name": "eu.gcr.io/bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot",
        "type": "docker/image"
      },
      "useDefaultArtifact": false,
      "usePriorExecution": false
    }
  ],
  "keepWaitingPipelines": false,
  "lastModifiedBy": "anonymous",
  "limitConcurrent": true,
  "stages": [
    {
      "clusters": [
        {
          "account": "spinnaker-bolcom-sbx-vso-sbx-dpitc-e18",
          "application": "dpitc",
          "cloudProvider": "kubernetes",
          "containers": [
            {
              "args": [],
              "command": [],
              "envFrom": [],
              "envVars": [],
              "imageDescription": {
                "artifactId": "40c32339-d021-410b-8837-cdad4c8b86d7",
                "fromArtifact": true,
                "imageId": "undefined (Artifact resolved at runtime)"
              },
              "imagePullPolicy": "IFNOTPRESENT",
              "limits": {},
              "name": "eu-gcr-io-bolcom-sbx-vso-sbx-dpitc-e18-nginx-nonroot",
              "ports": [
                {
                  "containerPort": 80,
                  "name": "http",
                  "protocol": "TCP"
                }
              ],
              "requests": {},
              "securityContext": {
                "runAsNonRoot": true,
                "runAsUser": 100
              },
              "volumeMounts": []
            }
          ],
          "deployment": {
            "deploymentStrategy": {
              "rollingUpdate": {
                "maxSurge": 1,
                "maxUnavailable": 1
              },
              "type": "RollingUpdate"
            },
            "enabled": false,
            "minReadySeconds": 0
          },
          "dnsPolicy": "ClusterFirst",
          "initContainers": [],
          "interestingHealthProviderNames": [
            "KubernetesContainer",
            "KubernetesPod"
          ],
          "namespace": "vso-sbx-dpitc",
          "nodeSelector": {},
          "podAnnotations": {},
          "provider": "kubernetes",
          "region": "vso-sbx-dpitc",
          "replicaSetAnnotations": {},
          "strategy": "highlander",
          "targetSize": 1,
          "terminationGracePeriodSeconds": 30,
          "useSourceCapacity": false,
          "volumeSources": []
        }
      ],
      "name": "Deploy",
      "refId": "1",
      "requisiteStageRefIds": [],
      "type": "deploy"
    }
  ],
  "triggers": [
    {
      "attributeConstraints": {},
      "enabled": true,
      "expectedArtifactIds": [
        "40c32339-d021-410b-8837-cdad4c8b86d7"
      ],
      "payloadConstraints": {},
      "pubsubSystem": "google",
      "subscriptionName": "gcr-manual-subscription-with-sa",
      "type": "pubsub"
    },
    {
      "account": "gcr-bolcom-sbx-vso-sbx-dpitc-e18",
      "enabled": false,
      "organization": "bolcom-sbx-vso-sbx-dpitc-e18",
      "registry": "eu.gcr.io",
      "repository": "bolcom-sbx-vso-sbx-dpitc-e18/nginx-nonroot",
      "type": "docker"
    }
  ],
  "updateTs": "1536218066604"
}

Although I noticed one annoyance that seems to be related to the fact that I have multiple triggers.


#7

You’re entirely correct that this will work—I actually hadn’t realized that the docker trigger actually inflates the received image into an artifact, allowing it to be used as an artifact in later stages.

Thanks for reporting the bug with container selection: I’ve fixed it here


#8

Fantastic! Will the fix be available in Spinnaker 1.9.3?


#9

Yes, I’ve pulled the fix into the 1.9.x branch, so it will be included in 1.9.3.


#10

@ezimanyi do you also have an idea about this bug: https://github.com/spinnaker/spinnaker/issues/3290 ?
It also seems to be artifact-related.


#11

Thanks for reporting it; the bug was that Spinnaker was only replacing the first period in the registry name (thus breaking for any registry with more than one period). It’s fixed in https://github.com/spinnaker/deck/pull/5711 and will be in 1.9.3.