#Pushing to ECR with the Go SDK?

1 messages · Page 1 of 1 (latest)

jaunty nacelle
#

Has anyone had any luck using the Go SDK to push to a private ECR? I'm running the Dagger Go SDK on ECS and getting failures trying to publish the image. I saw the CDK example but looking for the right methods to verify how/what is pushed. I double checked permissions and even did the whole "ecr:*" trick but still nothing.

This is the error:

container.from.withDirectory.withDirectory.withDirectory.withDirectory.withNewFile.withRegistryAuth.publish failed to solve: failed to push <account>.dkr.ecr.us-west-2.amazonaws.com/<repo>:<tag>: failed to do request: Post \"https://<account>.dkr.ecr.us-west-2.amazonaws.com/v2/<repo>/blobs/uploads/\": EOF\n\nPlease visit https://dagger.io/help#go for troubleshooting guidance.
rigid blaze
#

👋 yes, we're currently doing that internally at Dagger. Here's a snippet about how we're doing that:

// publish publishes the api container image to an image registry
func (t Api) Publish(ctx context.Context, imageUrl string) error {
    c, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr))
    if err != nil {
        return err
    }
    defer c.Close()

    c = c.Pipeline("api").Pipeline("publish")
    apiBin := t.build(ctx, c)

    // Read Registry info from the env
    ecrRegistry := os.Getenv("ECR_REGISTRY")
    ecrUser := os.Getenv("ECR_USER")
    ecrToken := os.Getenv("ECR_TOKEN")

    if ecrRegistry != "" {
        secret := c.SetSecret("password", ecrToken)
        apiBin = apiBin.WithRegistryAuth(ecrRegistry, ecrUser, secret)
    }

    addr, err := apiBin.Publish(ctx, imageUrl)
    if err != nil {
        return err
    }

    fmt.Println("Published at:", addr)
    return nil
}
jaunty nacelle
#

Thank you @rigid blaze! A few follow up questions:

  1. How are you setting the ECR_* env vars? We are using the IAM credentials from the machine's AWS_* env vars
  2. Is the URI format the same URI that is detailed in the "View Push Commands" in the AWS Console?

I tried to use the Go SDK to get a token for pushing, because I was not sure what the "username" and password would be for pushing to ECR

https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ecr#GetAuthorizationTokenOutput

rigid blaze
#

the auth part is something that we're currently doing in GHA since we haven't migrated that to dagger yet. Here's how we're doing it:

      id: creds
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1

    - name: Login ECR
      id: login-ecr
      # We're using an untagged version since we need to support to
      # fetch ECR credentials through the action output
      uses: aws-actions/amazon-ecr-login@5136be0451dc9b3900f85320f310d53ad7570608

    - name: Setup go
      uses: actions/setup-go@v3
      with:
        go-version: "1.20"

    - name: Build & push image
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: ${{ needs.api-infrastructure.outputs.env-name }}-api
        IMAGE_TAG: ${{ github.sha }}
      # We have to do some jq magic below since the login-ecr outputs are
      # dynamic
      run: |
        ECR_USER=$(echo '${{ toJSON(steps.login-ecr.outputs) }}' | jq -r 'with_entries(select(.key | contains("docker_username")))[]') \
        ECR_TOKEN=$(echo '${{ toJSON(steps.login-ecr.outputs) }}' | jq -r 'with_entries(select(.key | contains("docker_password")))[]') \
        ./hack/make api:publish "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
        echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
lethal basin
rigid blaze
jaunty nacelle
rigid blaze
#

hey @jaunty nacelle just checking if you were able to get past through this 🙏 or if we can help in some way

patent flower
#

yet another way to get ecr token

assumes that the credentials (or SSO session) are available in your env


import (
        ...

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ecr"

    "dagger.io/dagger"
)

func getEcrToken() string {
    os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    svc := ecr.NewFromConfig(cfg)
    token, err := svc.GetAuthorizationToken(context.TODO(), &ecr.GetAuthorizationTokenInput{})
    if err != nil {
        log.Fatal(err)
    }

    authData := token.AuthorizationData[0].AuthorizationToken
    data, err := base64.StdEncoding.DecodeString(*authData)
    if err != nil {
        log.Fatal(err)
    }

    parts := strings.SplitN(string(data), ":", 2)
    return parts[1]
}