Skip to content

Commit

Permalink
feat: support different architectures when copying images
Browse files Browse the repository at this point in the history
  • Loading branch information
uncledru committed Mar 15, 2024
1 parent b80402d commit 687d64b
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 12 deletions.
1 change: 1 addition & 0 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ func handler(ctx context.Context, event cfn.Event) (physicalResourceID string, d
if err != nil {
return physicalResourceID, data, err
}
arch, err := getStrProps(event.ResourceProperties, ARCHITECTURE)
if !IsValidGOARCH(arch) {
return physicalResourceID, data, fmt.Errorf("invalid GOARCH %s", arch)
}
if err != nil {
return physicalResourceID, data, err
}
srcCreds, err := getStrPropsDefault(event.ResourceProperties, SRC_CREDS, "")
if err != nil {
return physicalResourceID, data, err
Expand All @@ -71,7 +78,7 @@ func handler(ctx context.Context, event cfn.Event) (physicalResourceID string, d
return physicalResourceID, data, err
}

log.Printf("SrcImage: %v DestImage: %v", srcImage, destImage)
log.Printf("SrcImage: %v DestImage: %v Architecture: %v", srcImage, destImage, arch)

srcRef, err := alltransports.ParseImageName(srcImage)
if err != nil {
Expand All @@ -82,13 +89,13 @@ func handler(ctx context.Context, event cfn.Event) (physicalResourceID string, d
return physicalResourceID, data, err
}

srcOpts := NewImageOpts(srcImage)
srcOpts := NewImageOpts(srcImage, arch)
srcOpts.SetCreds(srcCreds)
srcCtx, err := srcOpts.NewSystemContext()
if err != nil {
return physicalResourceID, data, err
}
destOpts := NewImageOpts(destImage)
destOpts := NewImageOpts(destImage, arch)
destOpts.SetCreds(destCreds)
destCtx, err := destOpts.NewSystemContext()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions lambda/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ func TestMain(t *testing.T) {
destRef, err := alltransports.ParseImageName(destImage)
assert.NoError(t, err)

srcOpts := NewImageOpts(srcImage)
srcOpts := NewImageOpts(srcImage, "arm64")
srcCtx, err := srcOpts.NewSystemContext()
assert.NoError(t, err)
destOpts := NewImageOpts(destImage)
destOpts := NewImageOpts(destImage, "arm64")
destCtx, err := destOpts.NewSystemContext()
assert.NoError(t, err)

Expand Down
54 changes: 47 additions & 7 deletions lambda/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import (
)

const (
SRC_IMAGE string = "SrcImage"
DEST_IMAGE string = "DestImage"
SRC_CREDS string = "SrcCreds"
DEST_CREDS string = "DestCreds"
SRC_IMAGE string = "SrcImage"
DEST_IMAGE string = "DestImage"
SRC_CREDS string = "SrcCreds"
DEST_CREDS string = "DestCreds"
ARCHITECTURE string = "Architecture"
)

type ECRAuth struct {
Expand All @@ -35,6 +36,33 @@ type ECRAuth struct {
ExpiresAt time.Time
}

var validArchs = []string{
"386",
"amd64",
"amd64p32",
"arm",
"arm64",
"arm64be",
"armbe",
"loong64",
"mips",
"mips64",
"mips64le",
"mips64p32",
"mips64p32le",
"mipsle",
"ppc",
"ppc64",
"ppc64le",
"riscv",
"riscv64",
"s390",
"s390x",
"sparc",
"sparc64",
"wasm",
}

func GetECRRegion(uri string) string {
re := regexp.MustCompile(`dkr\.ecr\.(.+?)\.`)
m := re.FindStringSubmatch(uri)
Expand Down Expand Up @@ -86,14 +114,15 @@ type ImageOpts struct {
requireECRLogin bool
region string
creds string
architecture string
}

func NewImageOpts(uri string) *ImageOpts {
func NewImageOpts(uri string, arch string) *ImageOpts {
requireECRLogin := strings.Contains(uri, "dkr.ecr")
if requireECRLogin {
return &ImageOpts{uri, requireECRLogin, GetECRRegion(uri), ""}
return &ImageOpts{uri, requireECRLogin, GetECRRegion(uri), "", arch}
} else {
return &ImageOpts{uri, requireECRLogin, "", ""}
return &ImageOpts{uri, requireECRLogin, "", "", arch}
}
}

Expand All @@ -109,6 +138,7 @@ func (s *ImageOpts) NewSystemContext() (*types.SystemContext, error) {
ctx := &types.SystemContext{
DockerRegistryUserAgent: "ecr-deployment",
DockerAuthConfig: &types.DockerAuthConfig{},
ArchitectureChoice: s.architecture,
}

if s.creds != "" {
Expand Down Expand Up @@ -184,3 +214,13 @@ func GetSecret(secretId string) (secret string, err error) {
}
return *resp.SecretString, nil
}

func IsValidGOARCH(arch string) bool {
for _, validArch := range validArchs {
if arch == validArch {
return true
}
}

return false
}
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export interface ECRDeploymentProps {
*/
readonly dest: IImageName;

/**
* The architecture of the docker image.
*/
readonly architecture?: string;

/**
* The amount of memory (in MiB) to allocate to the AWS Lambda function which
* replicates the files from the CDK bucket to the destination bucket.
Expand Down Expand Up @@ -192,6 +197,7 @@ export class ECRDeployment extends Construct {
SrcCreds: props.src.creds,
DestImage: props.dest.uri,
DestCreds: props.dest.creds,
Architecture: props.architecture,
},
});
}
Expand Down
2 changes: 2 additions & 0 deletions test/example.ecr-deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ class TestECRDeployment extends Stack {
new ecrDeploy.ECRDeployment(this, 'DeployECRImage', {
src: new ecrDeploy.DockerImageName(image.imageUri),
dest: new ecrDeploy.DockerImageName(`${repo.repositoryUri}:latest`),
architecture: 'arm64',
});

new ecrDeploy.ECRDeployment(this, 'DeployDockerImage', {
src: new ecrDeploy.DockerImageName('javacs3/javacs3:latest', 'dockerhub'),
dest: new ecrDeploy.DockerImageName(`${repo.repositoryUri}:dockerhub`),
architecture: 'arm64',
}).addToPrincipalPolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
Expand Down

0 comments on commit 687d64b

Please sign in to comment.