fix(docker): handle container name conflict usecase. (#17379)

Drive-by: typo in the JSON docker status field.
This commit is contained in:
Andrey Lushnikov 2022-09-15 16:59:41 -07:00 committed by GitHub
parent 85a5c690a4
commit 24d3a23a66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 2 deletions

View File

@ -175,7 +175,7 @@ export async function printDockerStatus() {
dockerEngineRunning: isDockerEngine,
imageName: VRT_IMAGE_NAME,
imageIsPulled,
containerWSEndpoing: info?.wsEndpoint ?? '',
containerWSEndpoint: info?.wsEndpoint ?? '',
containerVNCEndpoint: info?.vncSession ?? '',
}, null, 2));
}
@ -227,6 +227,40 @@ async function ensurePlaywrightContainerOrDie(): Promise<ContainerInfo> {
if (info)
return info;
// The `npx playwright docker build` command is *NOT GUARANTEED* to produce
// images with the same SHA.
//
// Consider the following sequence of actions:
// 1. Build first version of image: `npx playwright docker build`
// 2. Run container off the image: `npx playwright docker start`
// 3. Build second version of image: `npx playwright docker build`
//
// Our container auto-detection is based on the parent image SHA.
// If the image produced at Step 3 has a different SHA then the one produced on Step 1,
// then we **won't be able** to auto-detect the container from Step 2.
//
// Additionally, we won't be able to launch a new container based off image
// from Step 3, since it will have a conflicting container name.
//
// We check if there's a same-named container running to detect & handle this situation.
const hasSameNamedContainer = async () => (await dockerApi.listContainers()).some(container => container.names.includes(VRT_CONTAINER_NAME));
if (await hasSameNamedContainer()) {
// Since we mark all our containers with labels, we'll be able to stop it.
await stopAllPlaywrightContainers();
// If it wasn't our container, then it was launched manually and has to be
// stopped manually as well.
if (await hasSameNamedContainer()) {
throw createStacklessError('\n' + utils.wrapInASCIIBox([
`There is already a container with name ${VRT_CONTAINER_NAME}`,
`Please stop this container manually and rerun tests:`,
``,
` docker kill ${VRT_CONTAINER_NAME}`,
``,
`<3 Playwright Team`,
].join('\n'), 1));
}
}
await dockerApi.launchContainer({
imageId: pwImage.imageId,
name: VRT_CONTAINER_NAME,

View File

@ -46,7 +46,9 @@ export async function listContainers(): Promise<DockerContainer[]> {
containerId: container.Id,
imageId: container.ImageID,
state: container.State,
names: container.Names,
// Note: container names are usually prefixed with '/'.
// See https://github.com/moby/moby/issues/6705
names: (container.Names ?? []).map((name: string) => name.startsWith('/') ? name.substring(1) : name),
portBindings: container.Ports?.map((portInfo: any) => ({
ip: portInfo.IP,
hostPort: portInfo.PublicPort,