| 171 | } |
| 172 | |
| 173 | export async function removeContainer(params: DockerCLIParameters | PartialExecParameters | DockerResolverParameters, nameOrId: string) { |
| 174 | const useEvents = !('cliVariant' in params && params.cliVariant === CLIVariant.Wslc); |
| 175 | let eventsProcess: Exec | undefined; |
| 176 | let removedSeenP: Promise<void> | undefined; |
| 177 | try { |
| 178 | for (let i = 0, n = 7; i < n; i++) { |
| 179 | try { |
| 180 | await dockerCLI(params, 'rm', '-f', nameOrId); |
| 181 | return; |
| 182 | } catch (err) { |
| 183 | // https://github.com/microsoft/vscode-remote-release/issues/6509 |
| 184 | const stderr: string = err?.stderr?.toString().toLowerCase() || ''; |
| 185 | if (i === n - 1 || !stderr.includes('already in progress')) { |
| 186 | throw err; |
| 187 | } |
| 188 | if (useEvents && !removedSeenP) { |
| 189 | eventsProcess = await getEvents(params, { |
| 190 | container: [nameOrId], |
| 191 | event: ['destroy'], |
| 192 | }); |
| 193 | removedSeenP = new Promise<void>(resolve => { |
| 194 | eventsProcess!.stdout.on('data', () => { |
| 195 | resolve(); |
| 196 | eventsProcess!.terminate(); |
| 197 | removedSeenP = new Promise(() => {}); // safeguard in case we see the 'removal already in progress' error again |
| 198 | }); |
| 199 | }); |
| 200 | } |
| 201 | if (removedSeenP) { |
| 202 | await Promise.race([removedSeenP, delay(1000)]); |
| 203 | } else { |
| 204 | await delay(1000); |
| 205 | } |
| 206 | } |
| 207 | } |
| 208 | } finally { |
| 209 | if (eventsProcess) { |
| 210 | eventsProcess.terminate(); |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | export async function getEvents(params: DockerCLIParameters | PartialExecParameters | DockerResolverParameters, filters?: Record<string, string[]>) { |
| 216 | const { exec, cmd, args, env, output } = toExecParameters(params); |