Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pieces of multiplatform support #696

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,16 @@ If there is already a `cypress/included` image with a specific version, but you

## Tagging the latest image

We build individual base images that match Node versions: `10.18.1`, `12.12.0`, `12.18.2`, etc. We also tag some of the images with major version: `base:10`, `base:12`. We also tag one image `base:latest`. In general, you should use the explicit version like `base:12.18.0` because it guarantees that the Docker image will never be suddenly updated.
We build individual base images that match Node versions: `10.18.1`, `12.12.0`, `12.18.2`, etc. We also tag some of the images with major version: `base:10`, `base:12`. We also tag one image `base:latest`. In general, consumers should use the explicit version like `base:12.18.0` because it guarantees that the Docker image will never be suddenly updated.

To tag new image, like `base:12.18.2` need to do the following from a local machine
To tag a new image, like `base:12.18.2`, you need to do the following from a local machine:

```text
# pull the image to tag
$ docker pull cypress/base:12.18.2
# install manifest-tool -- https://github.com/estesp/manifest-tool#installation
# tag that image with major version
$ docker tag cypress/base:12.18.2 cypress/base:12
$ ./retag-image cypress/base:12.18.2 cypress/base:12
# tag that image with "latest"
$ docker tag cypress/base:12.18.2 cypress/base:latest

# push the new images (which are the same)
$ docker push cypress/base:12
$ docker push cypress/base:latest
$ ./retag-image cypress/base:12.18.2 cypress/base:latest
```

## Bonus: smaller images
Expand Down
54 changes: 54 additions & 0 deletions retag-image
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env perl

use File::Temp qw/ tempfile /;
use File::Which;

my $default_tag='latest';

sub usage {
print STDERR "$0 IMAGE_TO_RETAG [TAG]

Use manifest-tool to assign an additional TAG to IMAGE_TO_RETAG.

TAG defaults to ${default_tag}
";
}

unless (which('manifest-tool')) {
print STDERR "Please install manifest-tool <https://github.com/estesp/manifest-tool>";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 hadn't seen this, I've only been messing with docker buildx and docker manifest, both of which have... limitations... I might pull this in after #700 to make it easier for us to add arm64 builds to existing tags.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm told one of these:

... might be a bit cleaner. But either way, downloading to just add a tag is silly (and potentially expensive use of bandwidth).

Copy link

@rnunezil rnunezil Jul 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsoref I noticed you removed the branch but I wanted to update you on what happened to my progress. I did remove the redirection and I then got passed that but then got the infamous qemu error that a lot of folks are getting with arm. Are you running your images on a Mac M1 or what machine are you using?

#0 64.71 [STARTED] Task without title.
#0 73.72 [FAILED] Cypress failed to start.
#0 73.72 [FAILED] 
#0 73.72 [FAILED] This may be due to a missing library or dependency. https://on.cypress.io/required-dependencies
#0 73.72 [FAILED] 
#0 73.72 [FAILED] Please refer to the error below for more details.
#0 73.72 [FAILED] 
#0 73.72 [FAILED] ----------
#0 73.72 [FAILED] 
#0 73.72 [FAILED] qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
#0 73.72 [FAILED] qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
#0 73.72 [FAILED] qemu: uncaught target signal 11 (Segmentation fault) - core dumped
#0 73.72 [FAILED] 
#0 73.72 [FAILED] ----------
#0 73.72 [FAILED] 
#0 73.72 [FAILED] Platform: linux-x64 (Debian - 10.11)
#0 73.72 [FAILED] Cypress Version: 10.3.0
#0 73.73 Cypress failed to start.
#0 73.73 
#0 73.73 This may be due to a missing library or dependency. https://on.cypress.io/required-dependencies
#0 73.73 
#0 73.73 Please refer to the error below for more details.
#0 73.73 
#0 73.73 ----------
#0 73.73 
#0 73.73 qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
#0 73.73 qemu: uncaught target signal 5 (Trace/breakpoint trap) - core dumped
#0 73.73 qemu: uncaught target signal 11 (Segmentation fault) - core dumped

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can still access them, either by giving a new branch name to a thing, by visiting https://github.com/cypress-io/cypress-docker-images/commits/b3465b26da55d3c41febc56dab3f5364ae9dd78e and using the branch chooser.

or by doing something like git fetch origin refs/pull/696/head:my-new-branch

As for the error, the goal is to run the arm version of cypress on our M1s, not the x64 versions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rnunezil: if you point me to the specific shas you're using and commands you're running, I'm happy to try to help.

(This isn't my primary task, but we do use cypress, so I'm glad to try to help out.)

exit 1;
}

my $image=shift @ARGV;
unless (defined $image) {
usage();
exit 1;
}

if ($image eq '--help' || $image eq '-h') {
usage();
exit 0;
}

my $tag=shift @ARGV || $default_tag;
my $manifest_info=`manifest-tool inspect "$image"`;
my ($fh, $manifest)=tempfile();

for (split /\n/, $manifest_info) {
if (/^Name:\s+(\S+):/) {
$name=$1;
print $fh "image: $name:$tag\n"."manifests:\n";
} elsif (/Digest: (\S+)/) {
$digest=$1;
} elsif (/OS: (\S+)/) {
$os=$1;
} elsif (/Arch: (\S+)/) {
print $fh "- image: $name\@$digest\n platform:\n architecture: $1\n os: $os\n";
$os="";
$digest="";
}
}
close $fh;
my $result=system "manifest-tool push from-spec $manifest";
exit $result if $result;
unlink $manifest;
17 changes: 16 additions & 1 deletion scripts/generate-base-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ RUN $(npm bin)/cypress run
\`\`\`
`

const platformsFallback = '${PLATFORMS:-linux/amd64,linux/arm64}'
const readmeFilename = path.join(outputFolder, "README.md")
fs.writeFileSync(readmeFilename, README.trim() + "\n", "utf8")

Expand All @@ -129,12 +130,26 @@ console.log("Saved %s", readmeFilename)
const buildScript = `
# WARNING: this file was autogenerated by ${path.basename(__filename)}
set e+x
PLATFORMS=${platformsFallback}

# build image with Cypress dependencies
LOCAL_NAME=cypress/base:${folderName}

docker context create multiarch 2> /dev/null || true

if [ "$(uname)" = "Linux" ]; then
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
fi

docker buildx use buildx-multiarch ||
docker buildx create --driver docker-container --use multiarch --name buildx-multiarch

if [ -n "$PLATFORMS" ]; then
PLATFORM_ARGS="--platform $PLATFORMS"
fi

echo "Building $LOCAL_NAME"
docker build -t $LOCAL_NAME .
docker buildx build $PLATFORM_ARGS -t $LOCAL_NAME . --push
`

const buildFilename = path.join(outputFolder, "build.sh")
Expand Down
19 changes: 18 additions & 1 deletion scripts/generate-browser-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ A complete image with all operating system depedencies for Cypress, and Chrome $
**Note:** this image uses the \`root\` user. You might want to switch to nonroot user like \`node\` when running this container for security
`

const platformsFallback = '${PLATFORMS:-linux/amd64,linux/arm64}'
const readmeFilename = path.join(outputFolder, "README.md")
fs.writeFileSync(readmeFilename, README.trim() + "\n", "utf8")
console.log("Saved %s", readmeFilename)
Expand All @@ -190,10 +191,26 @@ const buildScript = `
.map((arg) => arg)
.join(" ")}
set e+x
PLATFORMS=${platformsFallback}

LOCAL_NAME=cypress/browsers:${folderName}

docker context create multiarch 2> /dev/null || true

if [ "$(uname)" = "Linux" ]; then
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
fi

docker buildx use buildx-multiarch ||
docker buildx create --driver docker-container --use multiarch --name buildx-multiarch


if [ -n "$PLATFORMS" ]; then
PLATFORM_ARGS="--platform $PLATFORMS"
fi

echo "Building $LOCAL_NAME"
docker build -t $LOCAL_NAME .
docker buildx build $PLATFORM_ARGS -t $LOCAL_NAME . --push
`

const buildFilename = path.join(outputFolder, "build.sh")
Expand Down
19 changes: 18 additions & 1 deletion scripts/generate-included-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ $ docker run -it -v $PWD:/e2e -w /e2e cypress/included:${folderName}
[blog post url]: https://www.cypress.io/blog/2019/05/02/run-cypress-with-a-single-docker-command/
`

const platformsFallback = '${PLATFORMS:-linux/amd64,linux/arm64}'
const readmeFilename = path.join(outputFolder, "README.md")
fs.writeFileSync(readmeFilename, README.trim() + "\n", "utf8")
console.log("Saved %s", readmeFilename)
Expand All @@ -130,10 +131,26 @@ const buildScript = `
# using
# npm run add:included -- ${versionTag} ${baseImageTag}
set e+x
PLATFORMS=${platformsFallback}

LOCAL_NAME=cypress/included:${folderName}

docker context create multiarch 2> /dev/null || true

if [ "$(uname)" = "Linux" ]; then
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
fi

docker buildx use buildx-multiarch ||
docker buildx create --driver docker-container --use multiarch --name buildx-multiarch


if [ -n "$PLATFORMS" ]; then
PLATFORM_ARGS="--platform $PLATFORMS"
fi

echo "Building $LOCAL_NAME"
docker build -t $LOCAL_NAME .
docker buildx build $PLATFORM_ARGS -t $LOCAL_NAME . --push
`

const buildFilename = path.join(outputFolder, "build.sh")
Expand Down