mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-18 21:27:54 +00:00
Update docker related dependencies
This bumps dockerode, removes resin-docker-build in favor of @balena/compose, and updates docker-delta and docker-progress packages. Change-type: patch
This commit is contained in:
parent
15bccbf6b3
commit
ae823fea18
2089
package-lock.json
generated
2089
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -39,6 +39,7 @@
|
||||
"npm": ">=10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@balena/compose": "^3.2.1",
|
||||
"@balena/contrato": "^0.6.0",
|
||||
"@balena/es-version": "^1.0.3",
|
||||
"@balena/lint": "^8.0.2",
|
||||
@ -48,7 +49,7 @@
|
||||
"@types/chai-like": "^1.1.1",
|
||||
"@types/chai-things": "0.0.38",
|
||||
"@types/common-tags": "^1.8.1",
|
||||
"@types/dockerode": "^2.5.34",
|
||||
"@types/dockerode": "^3.3.28",
|
||||
"@types/event-stream": "^3.3.34",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/json-mask": "^2.0.3",
|
||||
@ -66,6 +67,7 @@
|
||||
"@types/sinon": "^17.0.3",
|
||||
"@types/sinon-chai": "^3.2.12",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@types/tar-stream": "^3.1.3",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@types/yargs": "^17.0.32",
|
||||
"balena-auth": "^6.0.1",
|
||||
@ -81,9 +83,9 @@
|
||||
"common-tags": "^1.8.0",
|
||||
"copy-webpack-plugin": "^12.0.0",
|
||||
"deep-object-diff": "^1.1.0",
|
||||
"docker-delta": "^2.2.11",
|
||||
"docker-progress": "^4.0.3",
|
||||
"dockerode": "^2.5.8",
|
||||
"docker-delta": "^4.0.1",
|
||||
"docker-progress": "^5.2.3",
|
||||
"dockerode": "^4.0.2",
|
||||
"duration-js": "^4.0.0",
|
||||
"event-stream": "3.3.5",
|
||||
"express": "^4.17.1",
|
||||
@ -106,11 +108,11 @@
|
||||
"morgan": "^1.10.0",
|
||||
"network-checker": "^0.1.1",
|
||||
"nock": "^13.1.2",
|
||||
"node-loader": "^2.0.0",
|
||||
"nodemon": "^3.1.0",
|
||||
"pinejs-client-request": "^7.3.5",
|
||||
"pretty-ms": "^7.0.1",
|
||||
"request": "^2.88.2",
|
||||
"resin-docker-build": "^1.1.6",
|
||||
"resumable-request": "^2.0.1",
|
||||
"rewire": "^7.0.0",
|
||||
"rimraf": "^5.0.0",
|
||||
|
@ -506,7 +506,14 @@ export class Service {
|
||||
|
||||
const ulimits: ServiceConfig['ulimits'] = {};
|
||||
_.each(container.HostConfig.Ulimits, ({ Name, Soft, Hard }) => {
|
||||
ulimits[Name] = { soft: Soft, hard: Hard };
|
||||
// The Ulimit type in @types/dockerode allows any element to be
|
||||
// null which is probably wrong
|
||||
if (Name != null && Soft != null && Hard != null) {
|
||||
ulimits[Name] = {
|
||||
soft: Soft,
|
||||
hard: Hard,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const portMaps = PortMap.fromDockerOpts(container.HostConfig.PortBindings);
|
||||
|
@ -97,7 +97,7 @@ export class Volume {
|
||||
Name: Volume.generateDockerName(this.appId, this.name),
|
||||
Labels: this.config.labels,
|
||||
Driver: this.config.driver,
|
||||
DriverOpts: this.config.driverOpts,
|
||||
DriverOpts: this.config.driverOpts!,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import _ from 'lodash';
|
||||
import memoizee from 'memoizee';
|
||||
|
||||
import { applyDelta, OutOfSyncError } from 'docker-delta';
|
||||
import DockerToolbelt = require('docker-toolbelt');
|
||||
|
||||
import type { SchemaReturn } from '../config/schema-type';
|
||||
import { envArrayToObject } from './conversions';
|
||||
@ -43,9 +42,8 @@ type ImageNameParts = {
|
||||
const DELTA_TOKEN_TIMEOUT = 10 * 60 * 1000;
|
||||
|
||||
export const docker = new Dockerode();
|
||||
export const dockerToolbelt = new DockerToolbelt(undefined);
|
||||
export const dockerProgress = new DockerProgress({
|
||||
dockerToolbelt,
|
||||
docker,
|
||||
});
|
||||
|
||||
// Separate string containing registry and image name into its parts.
|
||||
@ -153,10 +151,10 @@ export async function fetchDeltaWithProgress(
|
||||
|
||||
logFn(`Starting delta to ${imgDest}`);
|
||||
|
||||
const [dstInfo, srcInfo] = await Promise.all([
|
||||
dockerToolbelt.getRegistryAndName(imgDest),
|
||||
dockerToolbelt.getRegistryAndName(deltaOpts.deltaSource),
|
||||
]);
|
||||
const [dstInfo, srcInfo] = [
|
||||
getRegistryAndName(imgDest),
|
||||
getRegistryAndName(deltaOpts.deltaSource),
|
||||
];
|
||||
|
||||
const token = await getAuthToken(srcInfo, dstInfo, deltaOpts);
|
||||
|
||||
@ -252,7 +250,7 @@ export async function fetchImageWithProgress(
|
||||
{ uuid, currentApiKey }: FetchOptions,
|
||||
onProgress: ProgressCallback,
|
||||
): Promise<string> {
|
||||
const { registry } = await dockerToolbelt.getRegistryAndName(image);
|
||||
const { registry } = getRegistryAndName(image);
|
||||
|
||||
const dockerOpts =
|
||||
// If no registry is specified, we assume the image is a public
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Docker from 'dockerode';
|
||||
import type { Dockerfile } from 'livepush';
|
||||
import { Builder } from 'resin-docker-build';
|
||||
import { build } from '@balena/compose';
|
||||
|
||||
import { promises as fs } from 'fs';
|
||||
import * as Path from 'path';
|
||||
@ -10,6 +10,8 @@ import * as readline from 'readline';
|
||||
|
||||
import { exec } from '../src/lib/fs-utils';
|
||||
|
||||
const { Builder } = build;
|
||||
|
||||
export function getDocker(deviceAddress: string): Docker {
|
||||
return new Docker({
|
||||
host: deviceAddress,
|
||||
|
@ -88,7 +88,10 @@ describe('LocalModeManager', () => {
|
||||
}),
|
||||
);
|
||||
dockerStub.listNetworks.returns(
|
||||
Promise.resolve([{ Id: 'network-1' }, { Id: 'network-2' }]),
|
||||
Promise.resolve([
|
||||
{ Id: 'network-1' },
|
||||
{ Id: 'network-2' },
|
||||
] as Docker.NetworkInspectInfo[]),
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
process.env.DOCKER_HOST = 'unix:///your/dockerode/mocks/are/not/working';
|
||||
|
||||
import * as dockerode from 'dockerode';
|
||||
import Dockerode from 'dockerode';
|
||||
import { Stream } from 'stream';
|
||||
import _ = require('lodash');
|
||||
import _ from 'lodash';
|
||||
import { NotFoundError } from '~/lib/errors';
|
||||
|
||||
const overrides: Dictionary<(...args: any[]) => Resolvable<any>> = {};
|
||||
@ -30,13 +30,13 @@ function addAction(name: string, parameters: Dictionary<any> = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
type DockerodeFunction = keyof dockerode;
|
||||
for (const fn of Object.getOwnPropertyNames(dockerode.prototype)) {
|
||||
type DockerodeFunction = keyof Omit<Dockerode, 'modem'>;
|
||||
for (const fn of Object.getOwnPropertyNames(Dockerode.prototype)) {
|
||||
if (
|
||||
fn !== 'constructor' &&
|
||||
typeof (dockerode.prototype as any)[fn] === 'function'
|
||||
typeof (Dockerode.prototype as any)[fn] === 'function'
|
||||
) {
|
||||
(dockerode.prototype as any)[fn] = async function (...args: any[]) {
|
||||
(Dockerode.prototype as any)[fn] = async function (...args: any[]) {
|
||||
console.log(`🐳 Calling ${fn}...`);
|
||||
if (overrides[fn] != null) {
|
||||
return overrides[fn](args);
|
||||
@ -66,8 +66,8 @@ registerOverride(
|
||||
*/
|
||||
export function registerOverride<
|
||||
T extends DockerodeFunction,
|
||||
P extends Parameters<dockerode[T]>,
|
||||
R extends ReturnType<dockerode[T]>,
|
||||
P extends Parameters<Dockerode[T]>,
|
||||
R extends ReturnType<Dockerode[T]>,
|
||||
>(name: T, fn: (...args: P) => R) {
|
||||
console.log(`Overriding ${name}...`);
|
||||
overrides[name] = fn;
|
||||
@ -87,14 +87,14 @@ export interface TestData {
|
||||
}
|
||||
|
||||
function createMockedDockerode(data: TestData) {
|
||||
const mockedDockerode = dockerode.prototype;
|
||||
const mockedDockerode = Dockerode.prototype;
|
||||
|
||||
mockedDockerode.listImages = async () => [];
|
||||
|
||||
mockedDockerode.listVolumes = async () => {
|
||||
addAction('listVolumes');
|
||||
return {
|
||||
Volumes: data.volumes as dockerode.VolumeInspectInfo[],
|
||||
Volumes: data.volumes as Dockerode.VolumeInspectInfo[],
|
||||
Warnings: [],
|
||||
};
|
||||
};
|
||||
@ -120,18 +120,18 @@ function createMockedDockerode(data: TestData) {
|
||||
},
|
||||
name: volume.name,
|
||||
modem: {},
|
||||
} as dockerode.Volume;
|
||||
} as Dockerode.Volume;
|
||||
};
|
||||
|
||||
mockedDockerode.createContainer = async (
|
||||
options: dockerode.ContainerCreateOptions,
|
||||
options: Dockerode.ContainerCreateOptions,
|
||||
) => {
|
||||
addAction('createContainer', { options });
|
||||
return {
|
||||
start: async () => {
|
||||
addAction('start');
|
||||
},
|
||||
} as dockerode.Container;
|
||||
} as Dockerode.Container;
|
||||
};
|
||||
|
||||
mockedDockerode.getContainer = (id: string) => {
|
||||
@ -167,7 +167,7 @@ function createMockedDockerode(data: TestData) {
|
||||
return c;
|
||||
});
|
||||
},
|
||||
} as dockerode.Container;
|
||||
} as Dockerode.Container;
|
||||
};
|
||||
|
||||
mockedDockerode.getNetwork = (id: string) => {
|
||||
@ -177,7 +177,7 @@ function createMockedDockerode(data: TestData) {
|
||||
addAction('inspect');
|
||||
return data.networks[id];
|
||||
},
|
||||
} as dockerode.Network;
|
||||
} as Dockerode.Network;
|
||||
};
|
||||
|
||||
mockedDockerode.getImage = (name: string) => {
|
||||
@ -193,7 +193,7 @@ function createMockedDockerode(data: TestData) {
|
||||
name,
|
||||
});
|
||||
},
|
||||
} as dockerode.Image;
|
||||
} as Dockerode.Image;
|
||||
};
|
||||
|
||||
return mockedDockerode;
|
||||
@ -232,16 +232,14 @@ export async function testWithData(
|
||||
};
|
||||
|
||||
// grab the original prototype...
|
||||
const basePrototype = clonePrototype(dockerode.prototype);
|
||||
|
||||
// @ts-expect-error setting a RO property
|
||||
dockerode.prototype = createMockedDockerode(mockedData);
|
||||
const basePrototype = clonePrototype(Dockerode.prototype);
|
||||
Dockerode.prototype = createMockedDockerode(mockedData);
|
||||
|
||||
try {
|
||||
// run the test...
|
||||
await test();
|
||||
} finally {
|
||||
// reset the original prototype...
|
||||
assignPrototype(dockerode.prototype, basePrototype);
|
||||
assignPrototype(Dockerode.prototype, basePrototype);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import dockerode from 'dockerode';
|
||||
import Dockerode from 'dockerode';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { randomUUID as uuidv4 } from 'crypto';
|
||||
@ -14,31 +14,31 @@ type DeepPartial<T> = {
|
||||
|
||||
// Partial container inspect info for receiving as testing data
|
||||
export type PartialContainerInspectInfo =
|
||||
DeepPartial<dockerode.ContainerInspectInfo> & {
|
||||
DeepPartial<Dockerode.ContainerInspectInfo> & {
|
||||
Id: string;
|
||||
};
|
||||
|
||||
export type PartialNetworkInspectInfo =
|
||||
DeepPartial<dockerode.NetworkInspectInfo> & {
|
||||
DeepPartial<Dockerode.NetworkInspectInfo> & {
|
||||
Id: string;
|
||||
};
|
||||
|
||||
export type PartialVolumeInspectInfo =
|
||||
DeepPartial<dockerode.VolumeInspectInfo> & {
|
||||
DeepPartial<Dockerode.VolumeInspectInfo> & {
|
||||
Name: string;
|
||||
};
|
||||
|
||||
export type PartialImageInspectInfo =
|
||||
DeepPartial<dockerode.ImageInspectInfo> & {
|
||||
DeepPartial<Dockerode.ImageInspectInfo> & {
|
||||
Id: string;
|
||||
};
|
||||
|
||||
type Methods<T> = {
|
||||
[K in keyof T]: T[K] extends (...args: any) => any ? T[K] : never;
|
||||
type Fake<T> = {
|
||||
[K in keyof T]: T[K] extends (...args: any[]) => any ? T[K] : never;
|
||||
};
|
||||
|
||||
function createFake<Prototype extends object>(prototype: Prototype) {
|
||||
return (Object.getOwnPropertyNames(prototype) as Array<keyof Prototype>)
|
||||
function createFake<T extends object>(prototype: T): Fake<T> {
|
||||
return (Object.getOwnPropertyNames(prototype) as Array<keyof T>)
|
||||
.filter((fn) => fn === 'constructor' || typeof prototype[fn] === 'function')
|
||||
.reduce(
|
||||
(res, fn) => ({
|
||||
@ -51,7 +51,7 @@ function createFake<Prototype extends object>(prototype: Prototype) {
|
||||
);
|
||||
},
|
||||
}),
|
||||
{} as Methods<Prototype>,
|
||||
{} as Fake<T>,
|
||||
);
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ export function createNetwork(network: PartialNetworkInspectInfo) {
|
||||
...networkInspect,
|
||||
};
|
||||
|
||||
const fakeNetwork = createFake(dockerode.Network.prototype);
|
||||
const fakeNetwork = createFake(Dockerode.Network.prototype);
|
||||
|
||||
return {
|
||||
...fakeNetwork, // by default all methods fail unless overriden
|
||||
@ -103,7 +103,7 @@ export type MockNetwork = ReturnType<typeof createNetwork>;
|
||||
export function createContainer(container: PartialContainerInspectInfo) {
|
||||
const createContainerInspectInfo = (
|
||||
partial: PartialContainerInspectInfo,
|
||||
): dockerode.ContainerInspectInfo => {
|
||||
): Dockerode.ContainerInspectInfo => {
|
||||
const {
|
||||
Id,
|
||||
State,
|
||||
@ -200,12 +200,12 @@ export function createContainer(container: PartialContainerInspectInfo) {
|
||||
],
|
||||
|
||||
...ContainerInfo,
|
||||
} as dockerode.ContainerInspectInfo;
|
||||
} as Dockerode.ContainerInspectInfo;
|
||||
};
|
||||
|
||||
const createContainerInfo = (
|
||||
containerInspectInfo: dockerode.ContainerInspectInfo,
|
||||
): dockerode.ContainerInfo => {
|
||||
containerInspectInfo: Dockerode.ContainerInspectInfo,
|
||||
): Dockerode.ContainerInfo => {
|
||||
const {
|
||||
Id,
|
||||
Name,
|
||||
@ -239,7 +239,7 @@ export function createContainer(container: PartialContainerInspectInfo) {
|
||||
NetworkSettings: {
|
||||
Networks: NetworkSettings.Networks,
|
||||
},
|
||||
Mounts: Mounts as dockerode.ContainerInfo['Mounts'],
|
||||
Mounts: Mounts as Dockerode.ContainerInfo['Mounts'],
|
||||
};
|
||||
};
|
||||
|
||||
@ -248,7 +248,7 @@ export function createContainer(container: PartialContainerInspectInfo) {
|
||||
|
||||
const { Id: id } = inspectInfo;
|
||||
|
||||
const fakeContainer = createFake(dockerode.Container.prototype);
|
||||
const fakeContainer = createFake(Dockerode.Container.prototype);
|
||||
|
||||
return {
|
||||
...fakeContainer, // by default all methods fail unless overriden
|
||||
@ -318,7 +318,7 @@ export function createImage(
|
||||
) {
|
||||
const createImageInspectInfo = (
|
||||
partialImage: PartialImageInspectInfo,
|
||||
): dockerode.ImageInspectInfo => {
|
||||
): Dockerode.ImageInspectInfo => {
|
||||
const { Id, ContainerConfig, Config, GraphDriver, RootFS, ...Info } =
|
||||
partialImage;
|
||||
|
||||
@ -357,7 +357,7 @@ export function createImage(
|
||||
Labels: {},
|
||||
|
||||
...ContainerConfig,
|
||||
} as dockerode.ImageInspectInfo['ContainerConfig'],
|
||||
} as Dockerode.ImageInspectInfo['ContainerConfig'],
|
||||
DockerVersion: '17.05.0-ce',
|
||||
Author: '',
|
||||
Config: {
|
||||
@ -385,7 +385,7 @@ export function createImage(
|
||||
...(Config?.Labels ?? {}),
|
||||
},
|
||||
...Config,
|
||||
} as dockerode.ImageInspectInfo['Config'],
|
||||
} as Dockerode.ImageInspectInfo['Config'],
|
||||
|
||||
Architecture: 'arm64',
|
||||
Os: 'linux',
|
||||
@ -400,7 +400,7 @@ export function createImage(
|
||||
Name: 'aufs',
|
||||
|
||||
...GraphDriver,
|
||||
} as dockerode.ImageInspectInfo['GraphDriver'],
|
||||
} as Dockerode.ImageInspectInfo['GraphDriver'],
|
||||
RootFS: {
|
||||
Type: 'layers',
|
||||
Layers: [
|
||||
@ -410,13 +410,13 @@ export function createImage(
|
||||
],
|
||||
|
||||
...RootFS,
|
||||
} as dockerode.ImageInspectInfo['RootFS'],
|
||||
} as Dockerode.ImageInspectInfo['RootFS'],
|
||||
|
||||
...Info,
|
||||
};
|
||||
};
|
||||
|
||||
const createImageInfo = (imageInspectInfo: dockerode.ImageInspectInfo) => {
|
||||
const createImageInfo = (imageInspectInfo: Dockerode.ImageInspectInfo) => {
|
||||
const {
|
||||
Id,
|
||||
Parent: ParentId,
|
||||
@ -470,7 +470,7 @@ export function createImage(
|
||||
const info = createImageInfo(inspectInfo);
|
||||
const { Id: id } = inspectInfo;
|
||||
|
||||
const fakeImage = createFake(dockerode.Image.prototype);
|
||||
const fakeImage = createFake(Dockerode.Image.prototype);
|
||||
|
||||
return {
|
||||
...fakeImage, // by default all methods fail unless overriden
|
||||
@ -492,20 +492,20 @@ export type MockImage = ReturnType<typeof createImage>;
|
||||
export function createVolume(volume: PartialVolumeInspectInfo) {
|
||||
const { Name, Labels, ...partialVolumeInfo } = volume;
|
||||
|
||||
const inspectInfo: dockerode.VolumeInspectInfo = {
|
||||
const inspectInfo: Dockerode.VolumeInspectInfo = {
|
||||
Name,
|
||||
Driver: 'local',
|
||||
Mountpoint: '/var/lib/docker/volumes/resin-data',
|
||||
Labels: {
|
||||
...Labels,
|
||||
} as dockerode.VolumeInspectInfo['Labels'],
|
||||
} as Dockerode.VolumeInspectInfo['Labels'],
|
||||
Scope: 'local',
|
||||
Options: {},
|
||||
|
||||
...partialVolumeInfo,
|
||||
};
|
||||
|
||||
const fakeVolume = createFake(dockerode.Volume.prototype);
|
||||
const fakeVolume = createFake(Dockerode.Volume.prototype);
|
||||
return {
|
||||
...fakeVolume, // by default all methods fail unless overriden
|
||||
name: Name,
|
||||
@ -630,7 +630,7 @@ export class MockEngine {
|
||||
return Promise.resolve(delete this.networks[network.id]);
|
||||
}
|
||||
|
||||
createNetwork(options: dockerode.NetworkCreateOptions) {
|
||||
createNetwork(options: Dockerode.NetworkCreateOptions) {
|
||||
const Id = uuidv4();
|
||||
const network = createNetwork({ Id, ...options });
|
||||
|
||||
@ -645,7 +645,7 @@ export class MockEngine {
|
||||
);
|
||||
}
|
||||
|
||||
createContainer(options: dockerode.ContainerCreateOptions) {
|
||||
createContainer(options: Dockerode.ContainerCreateOptions) {
|
||||
const Id = uuidv4();
|
||||
|
||||
const { name: Name, HostConfig, NetworkingConfig, ...Config } = options;
|
||||
@ -890,12 +890,12 @@ export class MockEngine {
|
||||
}
|
||||
|
||||
export function createMockerode(engine: MockEngine) {
|
||||
const dockerodeStubs: Stubs<dockerode> = (
|
||||
Object.getOwnPropertyNames(dockerode.prototype) as Array<keyof dockerode>
|
||||
const dockerodeStubs: Stubs<Dockerode> = (
|
||||
Object.getOwnPropertyNames(Dockerode.prototype) as Array<keyof Dockerode>
|
||||
)
|
||||
.filter((fn) => typeof dockerode.prototype[fn] === 'function')
|
||||
.filter((fn) => typeof Dockerode.prototype[fn] === 'function')
|
||||
.reduce((stubMap, fn) => {
|
||||
const stub = sinon.stub(dockerode.prototype, fn);
|
||||
const stub = sinon.stub(Dockerode.prototype, fn);
|
||||
const proto: any = MockEngine.prototype;
|
||||
|
||||
if (fn in proto) {
|
||||
@ -907,7 +907,7 @@ export function createMockerode(engine: MockEngine) {
|
||||
}
|
||||
|
||||
return { ...stubMap, [fn]: stub };
|
||||
}, {} as Stubs<dockerode>);
|
||||
}, {} as Stubs<Dockerode>);
|
||||
|
||||
const { removeImage, removeNetwork, removeVolume, removeContainer } = engine;
|
||||
|
||||
|
@ -131,6 +131,10 @@ module.exports = function (env) {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
loader: 'node-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
externals: (_context, request, callback) => {
|
||||
|
Loading…
Reference in New Issue
Block a user