@lakutata/containerd 0.0.0-stage → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +409 -2
- package/THIRD_PARTY_NOTICES.md +310 -0
- package/dist/cjs/client/BuildKit.d.ts +176 -0
- package/dist/cjs/client/BuildKit.js +536 -0
- package/dist/cjs/client/BuildKitMessages.d.ts +35 -0
- package/dist/cjs/client/BuildKitMessages.js +123 -0
- package/dist/cjs/client/ContainerStore.d.ts +558 -0
- package/dist/cjs/client/ContainerStore.js +1384 -0
- package/dist/cjs/client/ContainerdClient.d.ts +244 -0
- package/dist/cjs/client/ContainerdClient.js +455 -0
- package/dist/cjs/client/DockerIgnore.d.ts +44 -0
- package/dist/cjs/client/DockerIgnore.js +186 -0
- package/dist/cjs/client/Fifo.d.ts +31 -0
- package/dist/cjs/client/Fifo.js +66 -0
- package/dist/cjs/client/ImageStore.d.ts +258 -0
- package/dist/cjs/client/ImageStore.js +636 -0
- package/dist/cjs/client/Messages.d.ts +103 -0
- package/dist/cjs/client/Messages.js +397 -0
- package/dist/cjs/client/Networks.d.ts +221 -0
- package/dist/cjs/client/Networks.js +630 -0
- package/dist/cjs/client/Platforms.d.ts +53 -0
- package/dist/cjs/client/Platforms.js +169 -0
- package/dist/cjs/client/Reference.d.ts +33 -0
- package/dist/cjs/client/Reference.js +70 -0
- package/dist/cjs/client/Registry.d.ts +145 -0
- package/dist/cjs/client/Registry.js +272 -0
- package/dist/cjs/client/Rootfs.d.ts +83 -0
- package/dist/cjs/client/Rootfs.js +245 -0
- package/dist/cjs/client/Seccomp.d.ts +36 -0
- package/dist/cjs/client/Seccomp.js +156 -0
- package/dist/cjs/client/Spec.d.ts +151 -0
- package/dist/cjs/client/Spec.js +227 -0
- package/dist/cjs/client/Volumes.d.ts +42 -0
- package/dist/cjs/client/Volumes.js +80 -0
- package/dist/cjs/containerd/Containerd.d.ts +442 -0
- package/dist/cjs/containerd/Containerd.js +929 -0
- package/dist/cjs/containerd/exceptions/ContainerdConnectionException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdConnectionException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerNameConflictException.d.ts +8 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerNameConflictException.js +15 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerNotFoundException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerNotFoundException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerStateException.d.ts +10 -0
- package/dist/cjs/containerd/exceptions/ContainerdContainerStateException.js +17 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageBuildException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageBuildException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageExportException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageExportException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageImportException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageImportException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageNotFoundException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdImageNotFoundException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdImagePullException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdImagePullException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdImagePushException.d.ts +8 -0
- package/dist/cjs/containerd/exceptions/ContainerdImagePushException.js +15 -0
- package/dist/cjs/containerd/exceptions/ContainerdNetworkConflictException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdNetworkConflictException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdNetworkNotFoundException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdNetworkNotFoundException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdPathNotFoundException.d.ts +8 -0
- package/dist/cjs/containerd/exceptions/ContainerdPathNotFoundException.js +15 -0
- package/dist/cjs/containerd/exceptions/ContainerdPlatformException.d.ts +9 -0
- package/dist/cjs/containerd/exceptions/ContainerdPlatformException.js +16 -0
- package/dist/cjs/containerd/exceptions/ContainerdVolumeInUseException.d.ts +8 -0
- package/dist/cjs/containerd/exceptions/ContainerdVolumeInUseException.js +15 -0
- package/dist/cjs/containerd/exceptions/ContainerdVolumeNotFoundException.d.ts +8 -0
- package/dist/cjs/containerd/exceptions/ContainerdVolumeNotFoundException.js +15 -0
- package/dist/cjs/containerd/lib/ContainerdContainer.d.ts +292 -0
- package/dist/cjs/containerd/lib/ContainerdContainer.js +536 -0
- package/dist/cjs/containerd/lib/ContainerdContainerTTY.d.ts +116 -0
- package/dist/cjs/containerd/lib/ContainerdContainerTTY.js +178 -0
- package/dist/cjs/containerd/lib/ContainerdErrors.d.ts +6 -0
- package/dist/cjs/containerd/lib/ContainerdErrors.js +37 -0
- package/dist/cjs/containerd/lib/ContainerdImage.d.ts +149 -0
- package/dist/cjs/containerd/lib/ContainerdImage.js +222 -0
- package/dist/cjs/containerd/options/ContainerdPruneOptions.d.ts +44 -0
- package/dist/cjs/containerd/options/ContainerdPruneOptions.js +51 -0
- package/dist/cjs/containerd/options/ContainerdRegistryAuthOptions.d.ts +32 -0
- package/dist/cjs/containerd/options/ContainerdRegistryAuthOptions.js +45 -0
- package/dist/cjs/containerd/options/container/ContainerCommitOptions.d.ts +57 -0
- package/dist/cjs/containerd/options/container/ContainerCommitOptions.js +66 -0
- package/dist/cjs/containerd/options/container/ContainerCreateOptions.d.ts +273 -0
- package/dist/cjs/containerd/options/container/ContainerCreateOptions.js +239 -0
- package/dist/cjs/containerd/options/container/ContainerExecOptions.d.ts +53 -0
- package/dist/cjs/containerd/options/container/ContainerExecOptions.js +63 -0
- package/dist/cjs/containerd/options/container/ContainerExportDirectoryOptions.d.ts +32 -0
- package/dist/cjs/containerd/options/container/ContainerExportDirectoryOptions.js +45 -0
- package/dist/cjs/containerd/options/container/ContainerKillOptions.d.ts +30 -0
- package/dist/cjs/containerd/options/container/ContainerKillOptions.js +41 -0
- package/dist/cjs/containerd/options/container/ContainerLogsOptions.d.ts +34 -0
- package/dist/cjs/containerd/options/container/ContainerLogsOptions.js +44 -0
- package/dist/cjs/containerd/options/container/ContainerRemoveOptions.d.ts +22 -0
- package/dist/cjs/containerd/options/container/ContainerRemoveOptions.js +34 -0
- package/dist/cjs/containerd/options/container/ContainerResourceOptions.d.ts +63 -0
- package/dist/cjs/containerd/options/container/ContainerResourceOptions.js +67 -0
- package/dist/cjs/containerd/options/container/ContainerStopOptions.d.ts +30 -0
- package/dist/cjs/containerd/options/container/ContainerStopOptions.js +41 -0
- package/dist/cjs/containerd/options/container/ContainerTTYConsoleSizeOptions.d.ts +26 -0
- package/dist/cjs/containerd/options/container/ContainerTTYConsoleSizeOptions.js +40 -0
- package/dist/cjs/containerd/options/container/ContainerTTYOptions.d.ts +50 -0
- package/dist/cjs/containerd/options/container/ContainerTTYOptions.js +63 -0
- package/dist/cjs/containerd/options/image/ImageBuildOptions.d.ts +88 -0
- package/dist/cjs/containerd/options/image/ImageBuildOptions.js +95 -0
- package/dist/cjs/containerd/options/image/ImageExportOptions.d.ts +25 -0
- package/dist/cjs/containerd/options/image/ImageExportOptions.js +39 -0
- package/dist/cjs/containerd/options/image/ImageImportOptions.d.ts +38 -0
- package/dist/cjs/containerd/options/image/ImageImportOptions.js +47 -0
- package/dist/cjs/containerd/options/image/ImagePullOptions.d.ts +53 -0
- package/dist/cjs/containerd/options/image/ImagePullOptions.js +66 -0
- package/dist/cjs/containerd/options/image/ImagePushOptions.d.ts +44 -0
- package/dist/cjs/containerd/options/image/ImagePushOptions.js +58 -0
- package/dist/cjs/containerd/options/network/NetworkCreateOptions.d.ts +82 -0
- package/dist/cjs/containerd/options/network/NetworkCreateOptions.js +83 -0
- package/dist/cjs/containerd/options/volume/VolumeCreateOptions.d.ts +26 -0
- package/dist/cjs/containerd/options/volume/VolumeCreateOptions.js +40 -0
- package/dist/cjs/containerd/types/ContainerdBind.d.ts +28 -0
- package/dist/cjs/containerd/types/ContainerdBind.js +2 -0
- package/dist/cjs/containerd/types/ContainerdBuildOutputCallback.d.ts +6 -0
- package/dist/cjs/containerd/types/ContainerdBuildOutputCallback.js +2 -0
- package/dist/cjs/containerd/types/ContainerdContainerNetwork.d.ts +40 -0
- package/dist/cjs/containerd/types/ContainerdContainerNetwork.js +2 -0
- package/dist/cjs/containerd/types/ContainerdContainerPort.d.ts +22 -0
- package/dist/cjs/containerd/types/ContainerdContainerPort.js +2 -0
- package/dist/cjs/containerd/types/ContainerdContainerState.d.ts +42 -0
- package/dist/cjs/containerd/types/ContainerdContainerState.js +2 -0
- package/dist/cjs/containerd/types/ContainerdContainerStats.d.ts +107 -0
- package/dist/cjs/containerd/types/ContainerdContainerStats.js +2 -0
- package/dist/cjs/containerd/types/ContainerdDevice.d.ts +25 -0
- package/dist/cjs/containerd/types/ContainerdDevice.js +2 -0
- package/dist/cjs/containerd/types/ContainerdExecResult.d.ts +18 -0
- package/dist/cjs/containerd/types/ContainerdExecResult.js +2 -0
- package/dist/cjs/containerd/types/ContainerdImageConfig.d.ts +46 -0
- package/dist/cjs/containerd/types/ContainerdImageConfig.js +2 -0
- package/dist/cjs/containerd/types/ContainerdNetworkInfo.d.ts +49 -0
- package/dist/cjs/containerd/types/ContainerdNetworkInfo.js +2 -0
- package/dist/cjs/containerd/types/ContainerdProgressCallback.d.ts +29 -0
- package/dist/cjs/containerd/types/ContainerdProgressCallback.js +2 -0
- package/dist/cjs/containerd/types/ContainerdPruneResult.d.ts +21 -0
- package/dist/cjs/containerd/types/ContainerdPruneResult.js +2 -0
- package/dist/cjs/containerd/types/ContainerdRestartPolicy.d.ts +13 -0
- package/dist/cjs/containerd/types/ContainerdRestartPolicy.js +2 -0
- package/dist/cjs/containerd/types/ContainerdTmpfs.d.ts +20 -0
- package/dist/cjs/containerd/types/ContainerdTmpfs.js +2 -0
- package/dist/cjs/containerd/types/ContainerdVolume.d.ts +19 -0
- package/dist/cjs/containerd/types/ContainerdVolume.js +2 -0
- package/dist/cjs/containerd/types/ContainerdVolumeInfo.d.ts +26 -0
- package/dist/cjs/containerd/types/ContainerdVolumeInfo.js +2 -0
- package/dist/cjs/exports/Containerd.d.ts +69 -0
- package/dist/cjs/exports/Containerd.js +87 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/client/BuildKit.js +488 -0
- package/dist/esm/client/BuildKitMessages.js +120 -0
- package/dist/esm/client/ContainerStore.js +1339 -0
- package/dist/esm/client/ContainerdClient.js +416 -0
- package/dist/esm/client/DockerIgnore.js +179 -0
- package/dist/esm/client/Fifo.js +59 -0
- package/dist/esm/client/ImageStore.js +628 -0
- package/dist/esm/client/Messages.js +393 -0
- package/dist/esm/client/Networks.js +621 -0
- package/dist/esm/client/Platforms.js +156 -0
- package/dist/esm/client/Reference.js +66 -0
- package/dist/esm/client/Registry.js +263 -0
- package/dist/esm/client/Rootfs.js +234 -0
- package/dist/esm/client/Seccomp.js +152 -0
- package/dist/esm/client/Spec.js +220 -0
- package/dist/esm/client/Volumes.js +73 -0
- package/dist/esm/containerd/Containerd.js +923 -0
- package/dist/esm/containerd/exceptions/ContainerdConnectionException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdContainerNameConflictException.js +11 -0
- package/dist/esm/containerd/exceptions/ContainerdContainerNotFoundException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdContainerStateException.js +13 -0
- package/dist/esm/containerd/exceptions/ContainerdImageBuildException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdImageExportException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdImageImportException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdImageNotFoundException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdImagePullException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdImagePushException.js +11 -0
- package/dist/esm/containerd/exceptions/ContainerdNetworkConflictException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdNetworkNotFoundException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdPathNotFoundException.js +11 -0
- package/dist/esm/containerd/exceptions/ContainerdPlatformException.js +12 -0
- package/dist/esm/containerd/exceptions/ContainerdVolumeInUseException.js +11 -0
- package/dist/esm/containerd/exceptions/ContainerdVolumeNotFoundException.js +11 -0
- package/dist/esm/containerd/lib/ContainerdContainer.js +533 -0
- package/dist/esm/containerd/lib/ContainerdContainerTTY.js +175 -0
- package/dist/esm/containerd/lib/ContainerdErrors.js +34 -0
- package/dist/esm/containerd/lib/ContainerdImage.js +219 -0
- package/dist/esm/containerd/options/ContainerdPruneOptions.js +47 -0
- package/dist/esm/containerd/options/ContainerdRegistryAuthOptions.js +41 -0
- package/dist/esm/containerd/options/container/ContainerCommitOptions.js +62 -0
- package/dist/esm/containerd/options/container/ContainerCreateOptions.js +235 -0
- package/dist/esm/containerd/options/container/ContainerExecOptions.js +59 -0
- package/dist/esm/containerd/options/container/ContainerExportDirectoryOptions.js +41 -0
- package/dist/esm/containerd/options/container/ContainerKillOptions.js +37 -0
- package/dist/esm/containerd/options/container/ContainerLogsOptions.js +40 -0
- package/dist/esm/containerd/options/container/ContainerRemoveOptions.js +30 -0
- package/dist/esm/containerd/options/container/ContainerResourceOptions.js +63 -0
- package/dist/esm/containerd/options/container/ContainerStopOptions.js +37 -0
- package/dist/esm/containerd/options/container/ContainerTTYConsoleSizeOptions.js +36 -0
- package/dist/esm/containerd/options/container/ContainerTTYOptions.js +59 -0
- package/dist/esm/containerd/options/image/ImageBuildOptions.js +91 -0
- package/dist/esm/containerd/options/image/ImageExportOptions.js +35 -0
- package/dist/esm/containerd/options/image/ImageImportOptions.js +43 -0
- package/dist/esm/containerd/options/image/ImagePullOptions.js +62 -0
- package/dist/esm/containerd/options/image/ImagePushOptions.js +54 -0
- package/dist/esm/containerd/options/network/NetworkCreateOptions.js +79 -0
- package/dist/esm/containerd/options/volume/VolumeCreateOptions.js +36 -0
- package/dist/esm/containerd/types/ContainerdBind.js +1 -0
- package/dist/esm/containerd/types/ContainerdBuildOutputCallback.js +1 -0
- package/dist/esm/containerd/types/ContainerdContainerNetwork.js +1 -0
- package/dist/esm/containerd/types/ContainerdContainerPort.js +1 -0
- package/dist/esm/containerd/types/ContainerdContainerState.js +1 -0
- package/dist/esm/containerd/types/ContainerdContainerStats.js +1 -0
- package/dist/esm/containerd/types/ContainerdDevice.js +1 -0
- package/dist/esm/containerd/types/ContainerdExecResult.js +1 -0
- package/dist/esm/containerd/types/ContainerdImageConfig.js +1 -0
- package/dist/esm/containerd/types/ContainerdNetworkInfo.js +1 -0
- package/dist/esm/containerd/types/ContainerdProgressCallback.js +1 -0
- package/dist/esm/containerd/types/ContainerdPruneResult.js +1 -0
- package/dist/esm/containerd/types/ContainerdRestartPolicy.js +1 -0
- package/dist/esm/containerd/types/ContainerdTmpfs.js +1 -0
- package/dist/esm/containerd/types/ContainerdVolume.js +1 -0
- package/dist/esm/containerd/types/ContainerdVolumeInfo.js +1 -0
- package/dist/esm/exports/Containerd.js +68 -0
- package/dist/types/client/BuildKit.d.ts +176 -0
- package/dist/types/client/BuildKitMessages.d.ts +35 -0
- package/dist/types/client/ContainerStore.d.ts +558 -0
- package/dist/types/client/ContainerdClient.d.ts +244 -0
- package/dist/types/client/DockerIgnore.d.ts +44 -0
- package/dist/types/client/Fifo.d.ts +31 -0
- package/dist/types/client/ImageStore.d.ts +258 -0
- package/dist/types/client/Messages.d.ts +103 -0
- package/dist/types/client/Networks.d.ts +221 -0
- package/dist/types/client/Platforms.d.ts +53 -0
- package/dist/types/client/Reference.d.ts +33 -0
- package/dist/types/client/Registry.d.ts +145 -0
- package/dist/types/client/Rootfs.d.ts +83 -0
- package/dist/types/client/Seccomp.d.ts +36 -0
- package/dist/types/client/Spec.d.ts +151 -0
- package/dist/types/client/Volumes.d.ts +42 -0
- package/dist/types/containerd/Containerd.d.ts +442 -0
- package/dist/types/containerd/exceptions/ContainerdConnectionException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdContainerNameConflictException.d.ts +8 -0
- package/dist/types/containerd/exceptions/ContainerdContainerNotFoundException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdContainerStateException.d.ts +10 -0
- package/dist/types/containerd/exceptions/ContainerdImageBuildException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdImageExportException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdImageImportException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdImageNotFoundException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdImagePullException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdImagePushException.d.ts +8 -0
- package/dist/types/containerd/exceptions/ContainerdNetworkConflictException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdNetworkNotFoundException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdPathNotFoundException.d.ts +8 -0
- package/dist/types/containerd/exceptions/ContainerdPlatformException.d.ts +9 -0
- package/dist/types/containerd/exceptions/ContainerdVolumeInUseException.d.ts +8 -0
- package/dist/types/containerd/exceptions/ContainerdVolumeNotFoundException.d.ts +8 -0
- package/dist/types/containerd/lib/ContainerdContainer.d.ts +292 -0
- package/dist/types/containerd/lib/ContainerdContainerTTY.d.ts +116 -0
- package/dist/types/containerd/lib/ContainerdErrors.d.ts +6 -0
- package/dist/types/containerd/lib/ContainerdImage.d.ts +149 -0
- package/dist/types/containerd/options/ContainerdPruneOptions.d.ts +44 -0
- package/dist/types/containerd/options/ContainerdRegistryAuthOptions.d.ts +32 -0
- package/dist/types/containerd/options/container/ContainerCommitOptions.d.ts +57 -0
- package/dist/types/containerd/options/container/ContainerCreateOptions.d.ts +273 -0
- package/dist/types/containerd/options/container/ContainerExecOptions.d.ts +53 -0
- package/dist/types/containerd/options/container/ContainerExportDirectoryOptions.d.ts +32 -0
- package/dist/types/containerd/options/container/ContainerKillOptions.d.ts +30 -0
- package/dist/types/containerd/options/container/ContainerLogsOptions.d.ts +34 -0
- package/dist/types/containerd/options/container/ContainerRemoveOptions.d.ts +22 -0
- package/dist/types/containerd/options/container/ContainerResourceOptions.d.ts +63 -0
- package/dist/types/containerd/options/container/ContainerStopOptions.d.ts +30 -0
- package/dist/types/containerd/options/container/ContainerTTYConsoleSizeOptions.d.ts +26 -0
- package/dist/types/containerd/options/container/ContainerTTYOptions.d.ts +50 -0
- package/dist/types/containerd/options/image/ImageBuildOptions.d.ts +88 -0
- package/dist/types/containerd/options/image/ImageExportOptions.d.ts +25 -0
- package/dist/types/containerd/options/image/ImageImportOptions.d.ts +38 -0
- package/dist/types/containerd/options/image/ImagePullOptions.d.ts +53 -0
- package/dist/types/containerd/options/image/ImagePushOptions.d.ts +44 -0
- package/dist/types/containerd/options/network/NetworkCreateOptions.d.ts +82 -0
- package/dist/types/containerd/options/volume/VolumeCreateOptions.d.ts +26 -0
- package/dist/types/containerd/types/ContainerdBind.d.ts +28 -0
- package/dist/types/containerd/types/ContainerdBuildOutputCallback.d.ts +6 -0
- package/dist/types/containerd/types/ContainerdContainerNetwork.d.ts +40 -0
- package/dist/types/containerd/types/ContainerdContainerPort.d.ts +22 -0
- package/dist/types/containerd/types/ContainerdContainerState.d.ts +42 -0
- package/dist/types/containerd/types/ContainerdContainerStats.d.ts +107 -0
- package/dist/types/containerd/types/ContainerdDevice.d.ts +25 -0
- package/dist/types/containerd/types/ContainerdExecResult.d.ts +18 -0
- package/dist/types/containerd/types/ContainerdImageConfig.d.ts +46 -0
- package/dist/types/containerd/types/ContainerdNetworkInfo.d.ts +49 -0
- package/dist/types/containerd/types/ContainerdProgressCallback.d.ts +29 -0
- package/dist/types/containerd/types/ContainerdPruneResult.d.ts +21 -0
- package/dist/types/containerd/types/ContainerdRestartPolicy.d.ts +13 -0
- package/dist/types/containerd/types/ContainerdTmpfs.d.ts +20 -0
- package/dist/types/containerd/types/ContainerdVolume.d.ts +19 -0
- package/dist/types/containerd/types/ContainerdVolumeInfo.d.ts +26 -0
- package/dist/types/exports/Containerd.d.ts +69 -0
- package/package.json +51 -4
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NetworkStore = exports.HOOK_SCRIPT = exports.DEFAULT_NETWORK = void 0;
|
|
7
|
+
exports.parseSubnet = parseSubnet;
|
|
8
|
+
exports.parseIPv6Subnet = parseIPv6Subnet;
|
|
9
|
+
const node_crypto_1 = require("node:crypto");
|
|
10
|
+
const node_child_process_1 = require("node:child_process");
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
|
+
const promises_1 = require("node:fs/promises");
|
|
13
|
+
const node_net_1 = require("node:net");
|
|
14
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
/**
|
|
16
|
+
* The default network of nerdctl
|
|
17
|
+
*/
|
|
18
|
+
exports.DEFAULT_NETWORK = 'bridge';
|
|
19
|
+
const DEFAULT_SUBNET = '10.4.0.0/24';
|
|
20
|
+
const DEFAULT_BRIDGE = 'nerdctl0';
|
|
21
|
+
/**
|
|
22
|
+
* The directory of the leases of the addresses of the networks created (in /run: released at the boots, when the
|
|
23
|
+
* containers of the last one did not stop)
|
|
24
|
+
*/
|
|
25
|
+
const IPAM_DATA_DIR = '/run/lakutata/cni/ipam';
|
|
26
|
+
/**
|
|
27
|
+
* The script of the networks of the containers, run by runc as their hooks: add (createRuntime, the networks of CNI
|
|
28
|
+
* added to the namespace of the container, its /etc/hosts given its address), del (poststop, the networks deleted, their
|
|
29
|
+
* addresses released). The plugins of each network are chained as libcni chains them (the result of each one is the
|
|
30
|
+
* previous result of the next one); their configurations are the files written for the container
|
|
31
|
+
*/
|
|
32
|
+
exports.HOOK_SCRIPT = `#!/bin/sh
|
|
33
|
+
# The networks of a container (CNI), run by runc: add (createRuntime), del (poststop); the state of the container on the
|
|
34
|
+
# standard input
|
|
35
|
+
command="$1"
|
|
36
|
+
dir="$2"
|
|
37
|
+
state=$(cat)
|
|
38
|
+
. "$dir/network/env"
|
|
39
|
+
pid=$(printf '%s' "$state" | tr -d '\\n' | sed -n 's/.*"pid": *\\([0-9][0-9]*\\).*/\\1/p')
|
|
40
|
+
# The namespace of the network of the container, kept by a bind mount until its networks are deleted (the plugins delete
|
|
41
|
+
# their rules from the namespace, gone with the container otherwise)
|
|
42
|
+
netns="$dir/network/netns"
|
|
43
|
+
|
|
44
|
+
mounted() {
|
|
45
|
+
awk -v target="$netns" '$5 == target { found = 1 } END { exit !found }' /proc/self/mountinfo
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
plugin() {
|
|
49
|
+
old_ifs=$IFS
|
|
50
|
+
IFS=:
|
|
51
|
+
for directory in $CNI_PATH; do
|
|
52
|
+
if [ -x "$directory/$1" ]; then
|
|
53
|
+
IFS=$old_ifs
|
|
54
|
+
printf '%s' "$directory/$1"
|
|
55
|
+
return 0
|
|
56
|
+
fi
|
|
57
|
+
done
|
|
58
|
+
IFS=$old_ifs
|
|
59
|
+
return 1
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# The input of a plugin: its configuration, the previous result
|
|
63
|
+
input() {
|
|
64
|
+
if [ -n "$2" ]; then printf '%s,"prevResult":%s}' "$(cat "$1")" "$2"; else printf '%s}' "$(cat "$1")"; fi
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
add() {
|
|
68
|
+
net="$1"
|
|
69
|
+
export CNI_COMMAND=ADD CNI_CONTAINERID CNI_NETNS="$netns" CNI_IFNAME="$(cat "$net/ifname")" CNI_ARGS="$(cat "$net/args")" CNI_PATH
|
|
70
|
+
count=$(cat "$net/count")
|
|
71
|
+
previous=""
|
|
72
|
+
i=1
|
|
73
|
+
while [ "$i" -le "$count" ]; do
|
|
74
|
+
type=$(cat "$net/$i.type")
|
|
75
|
+
binary=$(plugin "$type") || { echo "the CNI plugin $type is not in $CNI_PATH" >&2; return 1; }
|
|
76
|
+
if ! previous=$(input "$net/$i.conf" "$previous" | "$binary"); then
|
|
77
|
+
echo "the CNI plugin $type of the network $(cat "$net/name") failed: $previous" >&2
|
|
78
|
+
return 1
|
|
79
|
+
fi
|
|
80
|
+
i=$((i + 1))
|
|
81
|
+
done
|
|
82
|
+
printf '%s' "$previous" > "$net/result.json"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
del() {
|
|
86
|
+
net="$1"
|
|
87
|
+
export CNI_COMMAND=DEL CNI_CONTAINERID CNI_NETNS="$netns" CNI_IFNAME="$(cat "$net/ifname")" CNI_ARGS="$(cat "$net/args")" CNI_PATH
|
|
88
|
+
count=$(cat "$net/count")
|
|
89
|
+
previous=$(cat "$net/result.json" 2>/dev/null)
|
|
90
|
+
i=$count
|
|
91
|
+
while [ "$i" -ge 1 ]; do
|
|
92
|
+
type=$(cat "$net/$i.type")
|
|
93
|
+
if binary=$(plugin "$type"); then
|
|
94
|
+
input "$net/$i.conf" "$previous" | "$binary" > /dev/null 2>&1 || echo "the CNI plugin $type of the network $(cat "$net/name") failed to delete" >&2
|
|
95
|
+
fi
|
|
96
|
+
i=$((i - 1))
|
|
97
|
+
done
|
|
98
|
+
rm -f "$net/result.json"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
networks=$(ls -d "$dir"/network/[0-9]* 2>/dev/null)
|
|
102
|
+
case "$command" in
|
|
103
|
+
add)
|
|
104
|
+
if ! mounted; then
|
|
105
|
+
if [ -z "$pid" ] || [ ! -e "/proc/$pid/ns/net" ]; then echo "the container has no process (its state: $state)" >&2; exit 1; fi
|
|
106
|
+
: > "$netns"
|
|
107
|
+
mount --bind "/proc/$pid/ns/net" "$netns" || exit 1
|
|
108
|
+
fi
|
|
109
|
+
for net in $networks; do
|
|
110
|
+
if ! add "$net"; then
|
|
111
|
+
for added in $networks; do del "$added"; done
|
|
112
|
+
umount "$netns" 2>/dev/null
|
|
113
|
+
rm -f "$netns"
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
done
|
|
117
|
+
first=$(printf '%s\\n' $networks | head -n 1)
|
|
118
|
+
address=$(sed -n 's/.*"address": *"\\([0-9a-fA-F.:]*\\)\\/.*/\\1/p' "$first/result.json" | head -n 1)
|
|
119
|
+
{ cat "$dir/hosts.base"; if [ -n "$address" ]; then printf '%s\\t%s\\n' "$address" "$(cat "$dir/hostname")"; fi; } > "$dir/hosts"
|
|
120
|
+
;;
|
|
121
|
+
del)
|
|
122
|
+
mounted || netns=""
|
|
123
|
+
for net in $(printf '%s\\n' $networks | sort -r); do del "$net"; done
|
|
124
|
+
if [ -n "$netns" ]; then umount "$netns" 2>/dev/null || umount -l "$netns" 2>/dev/null; fi
|
|
125
|
+
rm -f "$dir/network/netns"
|
|
126
|
+
;;
|
|
127
|
+
esac
|
|
128
|
+
exit 0
|
|
129
|
+
`;
|
|
130
|
+
/**
|
|
131
|
+
* The integer of an address of IPv4
|
|
132
|
+
* @param address
|
|
133
|
+
*/
|
|
134
|
+
function iPv4ToNumber(address) {
|
|
135
|
+
const parts = address.split('.').map(Number);
|
|
136
|
+
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255))
|
|
137
|
+
throw new Error(`The address ${address} is not an address of IPv4`);
|
|
138
|
+
return ((parts[0] << 24) >>> 0) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
|
|
139
|
+
}
|
|
140
|
+
function numberToIPv4(value) {
|
|
141
|
+
return [value >>> 24, (value >>> 16) & 255, (value >>> 8) & 255, value & 255].join('.');
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The first and the last addresses of a subnet (CIDR of IPv4)
|
|
145
|
+
* @param cidr
|
|
146
|
+
*/
|
|
147
|
+
function parseSubnet(cidr) {
|
|
148
|
+
const [address, prefixText] = cidr.split('/');
|
|
149
|
+
const prefix = Number(prefixText);
|
|
150
|
+
if (!Number.isInteger(prefix) || prefix < 8 || prefix > 30)
|
|
151
|
+
throw new Error(`The subnet ${cidr} is not a CIDR of IPv4 (/8 to /30)`);
|
|
152
|
+
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
|
|
153
|
+
const network = (iPv4ToNumber(address) & mask) >>> 0;
|
|
154
|
+
return { network: network, broadcast: (network | (~mask >>> 0)) >>> 0, prefix: prefix, cidr: `${numberToIPv4(network)}/${prefix}` };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The integer of an address of IPv6
|
|
158
|
+
* @param address
|
|
159
|
+
*/
|
|
160
|
+
function iPv6ToBigInt(address) {
|
|
161
|
+
if (!(0, node_net_1.isIPv6)(address))
|
|
162
|
+
throw new Error(`The address ${address} is not an address of IPv6`);
|
|
163
|
+
const [head, tail] = address.split('::');
|
|
164
|
+
//An address of IPv4 at its end (::ffff:1.2.3.4)
|
|
165
|
+
const ipv4 = (part) => part.includes('.') ? [(iPv4ToNumber(part) >>> 16).toString(16), (iPv4ToNumber(part) & 0xffff).toString(16)] : [part];
|
|
166
|
+
const headGroups = head ? head.split(':').flatMap(ipv4) : [];
|
|
167
|
+
const tailGroups = tail ? tail.split(':').flatMap(ipv4) : [];
|
|
168
|
+
const groups = tail === undefined ? headGroups : [...headGroups, ...Array(8 - headGroups.length - tailGroups.length).fill('0'), ...tailGroups];
|
|
169
|
+
return groups.reduce((value, group) => (value << 16n) | BigInt(parseInt(group || '0', 16)), 0n);
|
|
170
|
+
}
|
|
171
|
+
function bigIntToIPv6(value) {
|
|
172
|
+
const groups = [];
|
|
173
|
+
for (let index = 7; index >= 0; index--)
|
|
174
|
+
groups.push(((value >> BigInt(index * 16)) & 0xffffn).toString(16));
|
|
175
|
+
//The longest run of zeros compressed
|
|
176
|
+
let best = [-1, 0];
|
|
177
|
+
for (let start = 0; start < 8; start++) {
|
|
178
|
+
let length = 0;
|
|
179
|
+
while (start + length < 8 && groups[start + length] === '0')
|
|
180
|
+
length++;
|
|
181
|
+
if (length > best[1])
|
|
182
|
+
best = [start, length];
|
|
183
|
+
}
|
|
184
|
+
if (best[1] < 2)
|
|
185
|
+
return groups.join(':');
|
|
186
|
+
return `${groups.slice(0, best[0]).join(':')}::${groups.slice(best[0] + best[1]).join(':')}`;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A subnet of IPv6 (CIDR): its network, its prefix, its first address
|
|
190
|
+
* @param cidr
|
|
191
|
+
*/
|
|
192
|
+
function parseIPv6Subnet(cidr) {
|
|
193
|
+
const [address, prefixText] = cidr.split('/');
|
|
194
|
+
const prefix = Number(prefixText);
|
|
195
|
+
if (!Number.isInteger(prefix) || prefix < 8 || prefix > 126)
|
|
196
|
+
throw new Error(`The subnet ${cidr} is not a CIDR of IPv6 (/8 to /126)`);
|
|
197
|
+
const mask = ((1n << 128n) - 1n) ^ ((1n << BigInt(128 - prefix)) - 1n);
|
|
198
|
+
const network = iPv6ToBigInt(address) & mask;
|
|
199
|
+
return { cidr: `${bigIntToIPv6(network)}/${prefix}`, first: bigIntToIPv6(network + 1n), network: network, last: network | (((1n << 128n) - 1n) ^ mask) };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Whether two subnets overlap
|
|
203
|
+
* @param a
|
|
204
|
+
* @param b
|
|
205
|
+
*/
|
|
206
|
+
function overlap(a, b) {
|
|
207
|
+
try {
|
|
208
|
+
const [x, y] = [parseSubnet(a), parseSubnet(b)];
|
|
209
|
+
return x.network <= y.broadcast && y.network <= x.broadcast;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Remove a bridge of the host: the rules of the firewall plugin isolating it (iptables), its interface (ip of iproute2,
|
|
217
|
+
* or of busybox); what the system cannot remove is left
|
|
218
|
+
* @param bridge
|
|
219
|
+
*/
|
|
220
|
+
function removeBridge(bridge) {
|
|
221
|
+
for (const chain of ['CNI-ISOLATION-STAGE-1', 'CNI-ISOLATION-STAGE-2']) {
|
|
222
|
+
const rules = (0, node_child_process_1.spawnSync)('iptables', ['-w', '-S', chain], { encoding: 'utf8' });
|
|
223
|
+
if (rules.error || rules.status !== 0)
|
|
224
|
+
continue;
|
|
225
|
+
for (const rule of rules.stdout.split('\n')) {
|
|
226
|
+
//The rules naming the bridge: deleted as iptables writes them (their comments quoted)
|
|
227
|
+
if (!rule.startsWith('-A ') || !new RegExp(`(^| )-[io] ${bridge.replace(/\./g, '\\.')}( |$)`).test(rule))
|
|
228
|
+
continue;
|
|
229
|
+
(0, node_child_process_1.spawnSync)('/bin/sh', ['-c', `iptables -w -D ${rule.slice(3)}`], { stdio: 'ignore' });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if ((0, node_fs_1.existsSync)(`/sys/class/net/${bridge}`))
|
|
233
|
+
(0, node_child_process_1.spawnSync)('ip', ['link', 'delete', bridge], { stdio: 'ignore' });
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* The networks of CNI of the machine (the configuration lists of its directory), the ones of nerdctl created and
|
|
237
|
+
* removed, the configurations of the networks of the containers written for their hooks
|
|
238
|
+
*/
|
|
239
|
+
class NetworkStore {
|
|
240
|
+
#cniVersion;
|
|
241
|
+
constructor(confDir, cniPath) {
|
|
242
|
+
this.confDir = confDir;
|
|
243
|
+
this.cniPath = cniPath;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* The directories of the plugins which exist
|
|
247
|
+
*/
|
|
248
|
+
pluginDirectories() {
|
|
249
|
+
return this.cniPath.filter((directory) => (0, node_fs_1.existsSync)(directory));
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* The path of a plugin, undefined when it is not installed
|
|
253
|
+
* @param type
|
|
254
|
+
*/
|
|
255
|
+
plugin(type) {
|
|
256
|
+
for (const directory of this.pluginDirectories()) {
|
|
257
|
+
const file = node_path_1.default.join(directory, type);
|
|
258
|
+
try {
|
|
259
|
+
(0, node_fs_1.accessSync)(file, node_fs_1.constants.X_OK);
|
|
260
|
+
return file;
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
//Not there
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The version of CNI of the configurations written: the newest one of the plugins (1.0.0, or 0.4.0)
|
|
270
|
+
*/
|
|
271
|
+
cniVersion() {
|
|
272
|
+
if (this.#cniVersion)
|
|
273
|
+
return this.#cniVersion;
|
|
274
|
+
const bridge = this.plugin('bridge') ?? this.plugin('macvlan');
|
|
275
|
+
let versions = [];
|
|
276
|
+
if (bridge) {
|
|
277
|
+
try {
|
|
278
|
+
const result = (0, node_child_process_1.spawnSync)(bridge, [], { input: '', env: { ...process.env, CNI_COMMAND: 'VERSION' }, encoding: 'utf8', timeout: 10000 });
|
|
279
|
+
versions = JSON.parse(result.stdout).supportedVersions ?? [];
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
//An older plugin
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
this.#cniVersion = versions.includes('1.0.0') ? '1.0.0' : '0.4.0';
|
|
286
|
+
return this.#cniVersion;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A network of a configuration list
|
|
290
|
+
* @param file
|
|
291
|
+
* @param content
|
|
292
|
+
*/
|
|
293
|
+
parse(file, content) {
|
|
294
|
+
let list;
|
|
295
|
+
try {
|
|
296
|
+
list = JSON.parse(content);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
301
|
+
if (typeof list.name !== 'string')
|
|
302
|
+
return undefined;
|
|
303
|
+
const plugins = Array.isArray(list.plugins) ? list.plugins : [list];
|
|
304
|
+
const subnets = [];
|
|
305
|
+
const gateways = [];
|
|
306
|
+
for (const plugin of plugins) {
|
|
307
|
+
for (const range of plugin.ipam?.ranges ?? []) {
|
|
308
|
+
for (const item of range) {
|
|
309
|
+
if (item.subnet)
|
|
310
|
+
subnets.push(item.subnet);
|
|
311
|
+
if (item.gateway)
|
|
312
|
+
gateways.push(item.gateway);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (plugin.ipam?.subnet)
|
|
316
|
+
subnets.push(plugin.ipam.subnet);
|
|
317
|
+
if (plugin.ipam?.gateway)
|
|
318
|
+
gateways.push(plugin.ipam.gateway);
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
name: list.name,
|
|
322
|
+
id: typeof list.nerdctlID === 'string' ? list.nerdctlID : (0, node_crypto_1.createHash)('sha256').update(list.name).digest('hex'),
|
|
323
|
+
file: file,
|
|
324
|
+
labels: list.nerdctlLabels ?? {},
|
|
325
|
+
cniVersion: list.cniVersion ?? '0.4.0',
|
|
326
|
+
driver: plugins[0]?.type ?? '',
|
|
327
|
+
subnets: subnets,
|
|
328
|
+
gateways: gateways,
|
|
329
|
+
plugins: plugins,
|
|
330
|
+
managed: node_path_1.default.basename(file).startsWith('nerdctl-')
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The networks of CNI of the machine
|
|
335
|
+
*/
|
|
336
|
+
async list() {
|
|
337
|
+
let files;
|
|
338
|
+
try {
|
|
339
|
+
files = (await (0, promises_1.readdir)(this.confDir)).filter((file) => file.endsWith('.conflist') || file.endsWith('.conf')).sort();
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
const networks = [];
|
|
345
|
+
for (const file of files) {
|
|
346
|
+
const network = this.parse(node_path_1.default.join(this.confDir, file), await (0, promises_1.readFile)(node_path_1.default.join(this.confDir, file), 'utf8').catch(() => ''));
|
|
347
|
+
if (network && !networks.some((known) => known.name === network.name))
|
|
348
|
+
networks.push(network);
|
|
349
|
+
}
|
|
350
|
+
return networks;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* A network, by its name or its identifier (or a prefix of it); the default one of nerdctl created when it is asked
|
|
354
|
+
* @param nameOrId
|
|
355
|
+
*/
|
|
356
|
+
async get(nameOrId) {
|
|
357
|
+
const networks = await this.list();
|
|
358
|
+
const found = networks.find((network) => network.name === nameOrId)
|
|
359
|
+
?? networks.find((network) => network.id === nameOrId)
|
|
360
|
+
?? (nameOrId.length >= 3 ? networks.find((network) => network.id.startsWith(nameOrId)) : undefined);
|
|
361
|
+
if (found || nameOrId !== exports.DEFAULT_NETWORK)
|
|
362
|
+
return found;
|
|
363
|
+
return await this.createDefault();
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* The plugins added after the main one, as nerdctl adds them (the ones installed)
|
|
367
|
+
* @param driver
|
|
368
|
+
* @protected
|
|
369
|
+
*/
|
|
370
|
+
chainedPlugins(driver) {
|
|
371
|
+
const plugins = [{ type: 'portmap', capabilities: { portMappings: true } }];
|
|
372
|
+
if (driver === 'bridge' && this.plugin('firewall'))
|
|
373
|
+
plugins.push({ type: 'firewall', ingressPolicy: 'same-bridge' });
|
|
374
|
+
if (this.plugin('tuning'))
|
|
375
|
+
plugins.push({ type: 'tuning' });
|
|
376
|
+
return plugins;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Write a configuration list
|
|
380
|
+
* @param name
|
|
381
|
+
* @param id
|
|
382
|
+
* @param labels
|
|
383
|
+
* @param plugins
|
|
384
|
+
* @protected
|
|
385
|
+
*/
|
|
386
|
+
async write(name, id, labels, plugins) {
|
|
387
|
+
const file = node_path_1.default.join(this.confDir, `nerdctl-${name}.conflist`);
|
|
388
|
+
const content = JSON.stringify({ cniVersion: this.cniVersion(), name: name, nerdctlID: id, nerdctlLabels: labels, plugins: plugins }, null, 2);
|
|
389
|
+
await (0, promises_1.mkdir)(this.confDir, { recursive: true });
|
|
390
|
+
await (0, promises_1.writeFile)(file, content + '\n', { flag: 'wx' });
|
|
391
|
+
return this.parse(file, content);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Create the default network of nerdctl (bridge, nerdctl0, 10.4.0.0/24)
|
|
395
|
+
* @protected
|
|
396
|
+
*/
|
|
397
|
+
async createDefault() {
|
|
398
|
+
try {
|
|
399
|
+
return await this.write(exports.DEFAULT_NETWORK, (0, node_crypto_1.createHash)('sha256').update(exports.DEFAULT_NETWORK).digest('hex'), { 'nerdctl/default-network': 'true' }, [
|
|
400
|
+
{
|
|
401
|
+
type: 'bridge',
|
|
402
|
+
bridge: DEFAULT_BRIDGE,
|
|
403
|
+
isGateway: true,
|
|
404
|
+
ipMasq: true,
|
|
405
|
+
hairpinMode: true,
|
|
406
|
+
ipam: { ranges: [[{ gateway: '10.4.0.1', subnet: DEFAULT_SUBNET }]], routes: [{ dst: '0.0.0.0/0' }], type: 'host-local', dataDir: IPAM_DATA_DIR }
|
|
407
|
+
},
|
|
408
|
+
...this.chainedPlugins('bridge')
|
|
409
|
+
]);
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
//Created meanwhile
|
|
413
|
+
if (error.code === 'EEXIST')
|
|
414
|
+
return (await this.list()).find((network) => network.name === exports.DEFAULT_NETWORK);
|
|
415
|
+
throw error;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* A free subnet of 10.4.0.0/16 (the ones of nerdctl)
|
|
420
|
+
* @param used
|
|
421
|
+
* @protected
|
|
422
|
+
*/
|
|
423
|
+
freeSubnet(used) {
|
|
424
|
+
for (let third = 1; third < 256; third++) {
|
|
425
|
+
const subnet = `10.4.${third}.0/24`;
|
|
426
|
+
if (!used.some((other) => overlap(subnet, other)))
|
|
427
|
+
return subnet;
|
|
428
|
+
}
|
|
429
|
+
throw new Error('No subnet of 10.4.0.0/16 is free: give the subnet of the network');
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Create a network (bridge, macvlan, ipvlan), as nerdctl network create does
|
|
433
|
+
* @param options
|
|
434
|
+
*/
|
|
435
|
+
async create(options) {
|
|
436
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(options.name))
|
|
437
|
+
throw new Error(`The name of a network "${options.name}" is not valid ([a-zA-Z0-9][a-zA-Z0-9_.-]*)`);
|
|
438
|
+
if (['host', 'none', exports.DEFAULT_NETWORK].includes(options.name))
|
|
439
|
+
throw Object.assign(new Error(`The network ${options.name} is the one of the system`), { code: 'CONFLICT' });
|
|
440
|
+
const networks = await this.list();
|
|
441
|
+
if (networks.some((network) => network.name === options.name))
|
|
442
|
+
throw Object.assign(new Error(`The network ${options.name} exists`), { code: 'CONFLICT' });
|
|
443
|
+
const driver = options.driver ?? 'bridge';
|
|
444
|
+
if (!this.plugin(driver))
|
|
445
|
+
throw new Error(`The CNI plugin ${driver} is not installed (${this.cniPath.join(', ')})`);
|
|
446
|
+
const used = [DEFAULT_SUBNET, ...networks.flatMap((network) => network.subnets)];
|
|
447
|
+
const subnet = parseSubnet(options.subnet ?? this.freeSubnet(used));
|
|
448
|
+
const overlapping = used.find((other) => overlap(subnet.cidr, other));
|
|
449
|
+
if (options.subnet && overlapping)
|
|
450
|
+
throw Object.assign(new Error(`The subnet ${subnet.cidr} overlaps the one of another network (${overlapping})`), { code: 'CONFLICT' });
|
|
451
|
+
const gateway = options.gateway ?? numberToIPv4(subnet.network + 1);
|
|
452
|
+
const gatewayNumber = iPv4ToNumber(gateway);
|
|
453
|
+
if (gatewayNumber <= subnet.network || gatewayNumber >= subnet.broadcast)
|
|
454
|
+
throw new Error(`The gateway ${gateway} is not in the subnet ${subnet.cidr}`);
|
|
455
|
+
const range = { gateway: gateway, subnet: subnet.cidr };
|
|
456
|
+
if (options.ipRange) {
|
|
457
|
+
const ipRange = parseSubnet(options.ipRange);
|
|
458
|
+
if (ipRange.network < subnet.network || ipRange.broadcast > subnet.broadcast)
|
|
459
|
+
throw new Error(`The range ${options.ipRange} is not in the subnet ${subnet.cidr}`);
|
|
460
|
+
range.rangeStart = numberToIPv4(Math.max(ipRange.network + 1, subnet.network + 1));
|
|
461
|
+
range.rangeEnd = numberToIPv4(Math.min(ipRange.broadcast - 1, subnet.broadcast - 1));
|
|
462
|
+
}
|
|
463
|
+
const ipam = { ranges: [[range]], routes: options.internal ? [] : [{ dst: '0.0.0.0/0' }], type: 'host-local', dataDir: IPAM_DATA_DIR };
|
|
464
|
+
if (options.ipv6Subnet) {
|
|
465
|
+
const ipv6 = parseIPv6Subnet(options.ipv6Subnet);
|
|
466
|
+
const ipv6Gateway = options.ipv6Gateway ?? ipv6.first;
|
|
467
|
+
const gateway6 = iPv6ToBigInt(ipv6Gateway);
|
|
468
|
+
if (gateway6 <= ipv6.network || gateway6 > ipv6.last)
|
|
469
|
+
throw new Error(`The gateway ${ipv6Gateway} is not in the subnet ${ipv6.cidr}`);
|
|
470
|
+
const overlapping6 = networks.find((network) => network.subnets.some((other) => {
|
|
471
|
+
try {
|
|
472
|
+
const known = parseIPv6Subnet(other);
|
|
473
|
+
return known.network <= ipv6.last && ipv6.network <= known.last;
|
|
474
|
+
}
|
|
475
|
+
catch {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
}));
|
|
479
|
+
if (overlapping6)
|
|
480
|
+
throw Object.assign(new Error(`The subnet ${ipv6.cidr} overlaps the one of the network ${overlapping6.name}`), { code: 'CONFLICT' });
|
|
481
|
+
ipam.ranges.push([{ subnet: ipv6.cidr, gateway: ipv6Gateway }]);
|
|
482
|
+
if (!options.internal)
|
|
483
|
+
ipam.routes.push({ dst: '::/0' });
|
|
484
|
+
}
|
|
485
|
+
const id = (0, node_crypto_1.randomBytes)(32).toString('hex');
|
|
486
|
+
let main;
|
|
487
|
+
if (driver === 'bridge') {
|
|
488
|
+
main = { type: 'bridge', bridge: `br-${id.slice(0, 12)}`, isGateway: !options.internal, ipMasq: !options.internal, hairpinMode: true, ipam: ipam };
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
if (!options.parent)
|
|
492
|
+
throw new Error(`The ${driver} network ${options.name} needs the interface of the host (parent)`);
|
|
493
|
+
main = driver === 'macvlan' ? { type: 'macvlan', master: options.parent, mode: 'bridge', ipam: ipam } : { type: 'ipvlan', master: options.parent, mode: 'l2', ipam: ipam };
|
|
494
|
+
}
|
|
495
|
+
if (options.mtu)
|
|
496
|
+
main.mtu = options.mtu;
|
|
497
|
+
try {
|
|
498
|
+
return await this.write(options.name, id, options.labels ?? {}, [main, ...this.chainedPlugins(driver)]);
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
if (error.code === 'EEXIST')
|
|
502
|
+
throw Object.assign(new Error(`The network ${options.name} exists`), { code: 'CONFLICT' });
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Remove a network (one of nerdctl): its configuration, its bridge and the rules of its firewall, the leases of its
|
|
508
|
+
* addresses, as nerdctl network rm does
|
|
509
|
+
* @param network
|
|
510
|
+
*/
|
|
511
|
+
async remove(network) {
|
|
512
|
+
if (!network.managed)
|
|
513
|
+
throw new Error(`The network ${network.name} is not one of nerdctl (${network.file}): remove its configuration`);
|
|
514
|
+
if (network.labels['nerdctl/default-network'] === 'true')
|
|
515
|
+
throw Object.assign(new Error(`The network ${network.name} is the default one`), { code: 'CONFLICT' });
|
|
516
|
+
await (0, promises_1.rm)(network.file, { force: true });
|
|
517
|
+
const main = network.plugins[0] ?? {};
|
|
518
|
+
if (main.type === 'bridge' && typeof main.bridge === 'string' && /^[\w.-]+$/.test(main.bridge))
|
|
519
|
+
removeBridge(main.bridge);
|
|
520
|
+
if (main.ipam?.dataDir === IPAM_DATA_DIR)
|
|
521
|
+
await (0, promises_1.rm)(node_path_1.default.join(IPAM_DATA_DIR, network.name), { recursive: true, force: true });
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Write the configurations of the networks of a container for its hooks (the configurations of their plugins, their
|
|
525
|
+
* runtime configurations: the ports published on the first one)
|
|
526
|
+
* @param stateDir
|
|
527
|
+
* @param containerId
|
|
528
|
+
* @param networks
|
|
529
|
+
* @param ports
|
|
530
|
+
*/
|
|
531
|
+
async render(stateDir, containerId, networks, ports) {
|
|
532
|
+
const directory = node_path_1.default.join(stateDir, 'network');
|
|
533
|
+
await (0, promises_1.rm)(directory, { recursive: true, force: true });
|
|
534
|
+
await (0, promises_1.mkdir)(directory, { recursive: true });
|
|
535
|
+
const pluginPath = this.pluginDirectories().join(':');
|
|
536
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(directory, 'env'), [
|
|
537
|
+
`CNI_PATH='${pluginPath}'`,
|
|
538
|
+
`CNI_CONTAINERID='${containerId}'`,
|
|
539
|
+
`PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${pluginPath}'`,
|
|
540
|
+
'export CNI_PATH CNI_CONTAINERID PATH',
|
|
541
|
+
''
|
|
542
|
+
].join('\n'));
|
|
543
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(directory, 'hook.sh'), exports.HOOK_SCRIPT, { mode: 0o755 });
|
|
544
|
+
for (let index = 0; index < networks.length; index++) {
|
|
545
|
+
const { network, ip, ipv6 } = networks[index];
|
|
546
|
+
const net = node_path_1.default.join(directory, String(index).padStart(2, '0'));
|
|
547
|
+
await (0, promises_1.mkdir)(net);
|
|
548
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, 'name'), network.name);
|
|
549
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, 'ifname'), `eth${index}`);
|
|
550
|
+
const addresses = [ip, ipv6].filter((address) => !!address);
|
|
551
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, 'args'), ['IgnoreUnknown=1', ...addresses.length ? [`IP=${addresses.join(',')}`] : []].join(';'));
|
|
552
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, 'count'), String(network.plugins.length));
|
|
553
|
+
for (let position = 0; position < network.plugins.length; position++) {
|
|
554
|
+
const plugin = { ...network.plugins[position], name: network.name, cniVersion: network.cniVersion };
|
|
555
|
+
//The runtime configuration of the capabilities of the plugin (the ports on the first network)
|
|
556
|
+
if (plugin.capabilities?.portMappings && index === 0 && ports.length) {
|
|
557
|
+
plugin.runtimeConfig = { portMappings: ports.map((port) => ({ hostPort: port.hostPort, containerPort: port.containerPort, protocol: port.protocol, hostIP: port.hostIP ?? '' })) };
|
|
558
|
+
}
|
|
559
|
+
delete plugin.capabilities;
|
|
560
|
+
//Without its closing brace: the previous result is added by the hook
|
|
561
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, `${position + 1}.conf`), JSON.stringify(plugin).slice(0, -1));
|
|
562
|
+
await (0, promises_1.writeFile)(node_path_1.default.join(net, `${position + 1}.type`), String(plugin.type));
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Delete the networks of a container whose hook did not (its task killed with its shim): the hook run as runc runs
|
|
568
|
+
* it
|
|
569
|
+
* @param stateDir
|
|
570
|
+
*/
|
|
571
|
+
async teardown(stateDir) {
|
|
572
|
+
const hook = node_path_1.default.join(stateDir, 'network', 'hook.sh');
|
|
573
|
+
if (!(0, node_fs_1.existsSync)(hook))
|
|
574
|
+
return;
|
|
575
|
+
const results = (await (0, promises_1.readdir)(node_path_1.default.join(stateDir, 'network')).catch(() => []))
|
|
576
|
+
.filter((entry) => /^\d+$/.test(entry) && (0, node_fs_1.existsSync)(node_path_1.default.join(stateDir, 'network', entry, 'result.json')));
|
|
577
|
+
if (!results.length && !(0, node_fs_1.existsSync)(node_path_1.default.join(stateDir, 'network', 'netns')))
|
|
578
|
+
return;
|
|
579
|
+
await new Promise((resolve) => {
|
|
580
|
+
const child = (0, node_child_process_1.spawn)('/bin/sh', [hook, 'del', stateDir], { stdio: ['pipe', 'ignore', 'ignore'] });
|
|
581
|
+
child.on('error', () => resolve());
|
|
582
|
+
child.on('close', () => resolve());
|
|
583
|
+
child.stdin.end('{}');
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* The interfaces of a container on its networks (their results of CNI)
|
|
588
|
+
* @param stateDir
|
|
589
|
+
*/
|
|
590
|
+
async interfaces(stateDir) {
|
|
591
|
+
const directory = node_path_1.default.join(stateDir, 'network');
|
|
592
|
+
const entries = (await (0, promises_1.readdir)(directory).catch(() => [])).filter((entry) => /^\d+$/.test(entry)).sort();
|
|
593
|
+
const interfaces = [];
|
|
594
|
+
for (const entry of entries) {
|
|
595
|
+
const net = node_path_1.default.join(directory, entry);
|
|
596
|
+
const name = await (0, promises_1.readFile)(node_path_1.default.join(net, 'name'), 'utf8').catch(() => '');
|
|
597
|
+
const ifname = await (0, promises_1.readFile)(node_path_1.default.join(net, 'ifname'), 'utf8').catch(() => '');
|
|
598
|
+
const item = { network: name, interface: ifname };
|
|
599
|
+
let result;
|
|
600
|
+
try {
|
|
601
|
+
result = JSON.parse(await (0, promises_1.readFile)(node_path_1.default.join(net, 'result.json'), 'utf8'));
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
//Not added (the container is not running)
|
|
605
|
+
}
|
|
606
|
+
if (result) {
|
|
607
|
+
const index = (result.interfaces ?? []).findIndex((candidate) => candidate.name === ifname && !!candidate.sandbox);
|
|
608
|
+
if (index >= 0)
|
|
609
|
+
item.mac = result.interfaces[index].mac;
|
|
610
|
+
for (const ip of result.ips ?? []) {
|
|
611
|
+
if (ip.interface !== undefined && index >= 0 && ip.interface !== index)
|
|
612
|
+
continue;
|
|
613
|
+
const [address, prefix] = String(ip.address).split('/');
|
|
614
|
+
if (address.includes(':')) {
|
|
615
|
+
item.ipv6 ??= address;
|
|
616
|
+
item.ipv6Gateway ??= ip.gateway;
|
|
617
|
+
}
|
|
618
|
+
else if (!item.ip) {
|
|
619
|
+
item.ip = address;
|
|
620
|
+
item.prefixLength = Number(prefix);
|
|
621
|
+
item.gateway = ip.gateway;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
interfaces.push(item);
|
|
626
|
+
}
|
|
627
|
+
return interfaces;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
exports.NetworkStore = NetworkStore;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A platform of the images (OCI): its system, its architecture, its variant
|
|
3
|
+
*/
|
|
4
|
+
export type Platform = {
|
|
5
|
+
os: string;
|
|
6
|
+
architecture: string;
|
|
7
|
+
variant?: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The platforms of the ELF binaries an entry of binfmt_misc runs (by the machine of the ELF header of its magic): the
|
|
11
|
+
* emulators of QEMU, Rosetta, whatever their names
|
|
12
|
+
* @param entry the content of the entry
|
|
13
|
+
*/
|
|
14
|
+
export declare function binfmtPlatforms(entry: string): Platform[];
|
|
15
|
+
/**
|
|
16
|
+
* A platform written as OCI writes it (linux/arm64/v8)
|
|
17
|
+
* @param platform
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatPlatform(platform: Platform): string;
|
|
20
|
+
/**
|
|
21
|
+
* The variant of an architecture given without it: the one its images are matched to (arm64 is v8, arm v7)
|
|
22
|
+
* @param platform
|
|
23
|
+
*/
|
|
24
|
+
export declare function normalizePlatform(platform: Platform): Platform;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a platform: linux/arm64, linux/arm/v7, or an architecture (arm64), on Linux
|
|
27
|
+
* @param value
|
|
28
|
+
*/
|
|
29
|
+
export declare function parsePlatform(value: string): Platform;
|
|
30
|
+
/**
|
|
31
|
+
* The platform of the machine running Node.js
|
|
32
|
+
*/
|
|
33
|
+
export declare function hostPlatform(): Platform;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a platform of an image runs on a platform: the same system and architecture, a variant up to the one of the
|
|
36
|
+
* platform (an arm/v7 runs the images of arm/v6 and arm/v5)
|
|
37
|
+
* @param image
|
|
38
|
+
* @param platform
|
|
39
|
+
*/
|
|
40
|
+
export declare function matchPlatform(image: Platform, platform: Platform): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* How much a platform of an image suits a platform: the exact one first (lower is better), undefined when it does not
|
|
43
|
+
* run there
|
|
44
|
+
* @param image
|
|
45
|
+
* @param platform
|
|
46
|
+
*/
|
|
47
|
+
export declare function platformRank(image: Platform, platform: Platform): number | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The platforms the machine runs the containers of: its own one, and the ones of the emulators registered in
|
|
50
|
+
* binfmt_misc (enabled)
|
|
51
|
+
* @param binfmt the directory of binfmt_misc
|
|
52
|
+
*/
|
|
53
|
+
export declare function supportedPlatforms(binfmt?: string): Platform[];
|