@lakutata/containerd 0.0.0-stage → 3.0.0-beta.0
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,234 @@
|
|
|
1
|
+
import { lstat, readdir, readFile, readlink } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* The directories of the layers of the mounts of a snapshot, the top one first (overlay: its upper directory and its
|
|
5
|
+
* lower ones, bind: its source)
|
|
6
|
+
* @param mounts
|
|
7
|
+
*/
|
|
8
|
+
export function layerDirectories(mounts) {
|
|
9
|
+
const directories = [];
|
|
10
|
+
for (const mount of mounts) {
|
|
11
|
+
if (mount.type === 'bind' || mount.type === 'rbind') {
|
|
12
|
+
directories.push(mount.source);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (mount.type !== 'overlay')
|
|
16
|
+
continue;
|
|
17
|
+
for (const option of mount.options) {
|
|
18
|
+
if (option.startsWith('upperdir='))
|
|
19
|
+
directories.unshift(option.slice(9));
|
|
20
|
+
if (option.startsWith('lowerdir='))
|
|
21
|
+
directories.push(...option.slice(9).split(':'));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return directories;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Read a file of the root file system of a snapshot from the directories of its layers (the snapshotter of the host,
|
|
28
|
+
* readable by root): the top layer having it first, its deletions (the whiteouts of overlay) honoured, its symbolic
|
|
29
|
+
* links resolved in the root file system
|
|
30
|
+
* @param mounts
|
|
31
|
+
* @param file an absolute path in the root file system
|
|
32
|
+
* @param depth
|
|
33
|
+
*/
|
|
34
|
+
export async function readRootfsFile(mounts, file, depth = 0) {
|
|
35
|
+
if (depth > 8)
|
|
36
|
+
return undefined;
|
|
37
|
+
const relative = path.posix.normalize(file).replace(/^\/+/, '');
|
|
38
|
+
for (const directory of layerDirectories(mounts)) {
|
|
39
|
+
const target = path.join(directory, relative);
|
|
40
|
+
let stats;
|
|
41
|
+
try {
|
|
42
|
+
stats = await lstat(target);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
//Deleted by this layer
|
|
48
|
+
if (stats.isCharacterDevice() && stats.rdev === 0)
|
|
49
|
+
return undefined;
|
|
50
|
+
if (stats.isSymbolicLink()) {
|
|
51
|
+
const link = await readlink(target);
|
|
52
|
+
return await readRootfsFile(mounts, link.startsWith('/') ? link : path.posix.join(path.posix.dirname('/' + relative), link), depth + 1);
|
|
53
|
+
}
|
|
54
|
+
if (!stats.isFile())
|
|
55
|
+
return undefined;
|
|
56
|
+
return await readFile(target);
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The entries of a file of the database of the users or of the groups (name:x:id:…)
|
|
62
|
+
* @param content
|
|
63
|
+
*/
|
|
64
|
+
function readEntries(content) {
|
|
65
|
+
if (!content)
|
|
66
|
+
return [];
|
|
67
|
+
return content.toString('utf8').split('\n').filter((line) => !!line.trim() && !line.startsWith('#')).map((line) => line.split(':'));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the user of a process in a root file system (its /etc/passwd and /etc/group): user, user:group, uid, uid:gid
|
|
71
|
+
* @param mounts
|
|
72
|
+
* @param user empty for root
|
|
73
|
+
*/
|
|
74
|
+
export async function resolveUser(mounts, user) {
|
|
75
|
+
const [userPart, groupPart] = (user ?? '').split(':');
|
|
76
|
+
const passwd = readEntries(await readRootfsFile(mounts, '/etc/passwd'));
|
|
77
|
+
let uid = 0;
|
|
78
|
+
let gid = 0;
|
|
79
|
+
let home = '/';
|
|
80
|
+
let name = 'root';
|
|
81
|
+
if (userPart) {
|
|
82
|
+
const entry = passwd.find((fields) => fields[0] === userPart) ?? (/^\d+$/.test(userPart) ? passwd.find((fields) => fields[2] === userPart) : undefined);
|
|
83
|
+
if (entry) {
|
|
84
|
+
uid = Number(entry[2]);
|
|
85
|
+
gid = Number(entry[3]);
|
|
86
|
+
home = entry[5] || '/';
|
|
87
|
+
name = entry[0];
|
|
88
|
+
}
|
|
89
|
+
else if (/^\d+$/.test(userPart)) {
|
|
90
|
+
uid = Number(userPart);
|
|
91
|
+
gid = Number(userPart);
|
|
92
|
+
name = undefined;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
throw new Error(`The user "${userPart}" is not in the /etc/passwd of the image`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
const root = passwd.find((fields) => fields[2] === '0');
|
|
100
|
+
if (root)
|
|
101
|
+
home = root[5] || '/';
|
|
102
|
+
}
|
|
103
|
+
const groups = readEntries(await readRootfsFile(mounts, '/etc/group'));
|
|
104
|
+
if (groupPart) {
|
|
105
|
+
const entry = groups.find((fields) => fields[0] === groupPart);
|
|
106
|
+
if (entry)
|
|
107
|
+
gid = Number(entry[2]);
|
|
108
|
+
else if (/^\d+$/.test(groupPart))
|
|
109
|
+
gid = Number(groupPart);
|
|
110
|
+
else
|
|
111
|
+
throw new Error(`The group "${groupPart}" is not in the /etc/group of the image`);
|
|
112
|
+
}
|
|
113
|
+
//The groups the user is a member of (supplementary)
|
|
114
|
+
const additionalGids = name ? groups
|
|
115
|
+
.filter((fields) => (fields[3] ?? '').split(',').includes(name) && Number(fields[2]) !== gid)
|
|
116
|
+
.map((fields) => Number(fields[2])) : [];
|
|
117
|
+
return { uid: uid, gid: gid, additionalGids: [...new Set(additionalGids)], home: home };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The resolution of the symbolic links of a path in a file tree
|
|
121
|
+
* @param tree
|
|
122
|
+
* @param file
|
|
123
|
+
*/
|
|
124
|
+
async function resolveInTree(tree, file) {
|
|
125
|
+
const pending = path.posix.normalize(`/${file}`).split('/').filter(Boolean);
|
|
126
|
+
let current = '/';
|
|
127
|
+
let links = 0;
|
|
128
|
+
while (pending.length) {
|
|
129
|
+
const part = pending.shift();
|
|
130
|
+
if (part === '..') {
|
|
131
|
+
current = path.posix.dirname(current);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const candidate = path.posix.join(current, part);
|
|
135
|
+
const found = await tree.lstat(candidate);
|
|
136
|
+
if (found?.stats.isSymbolicLink()) {
|
|
137
|
+
if (++links > 40)
|
|
138
|
+
throw new Error(`The path ${file} has too many symbolic links`);
|
|
139
|
+
const target = await readlink(found.path);
|
|
140
|
+
if (target.startsWith('/'))
|
|
141
|
+
current = '/';
|
|
142
|
+
pending.unshift(...target.split('/').filter(Boolean));
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
current = candidate;
|
|
146
|
+
}
|
|
147
|
+
return current;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A file system of a directory of the host (/proc/<pid>/root: the one of a running container, its mounts with it)
|
|
151
|
+
*/
|
|
152
|
+
export class DirectoryTree {
|
|
153
|
+
constructor(root) {
|
|
154
|
+
this.root = root;
|
|
155
|
+
}
|
|
156
|
+
resolve(file) {
|
|
157
|
+
return resolveInTree(this, file);
|
|
158
|
+
}
|
|
159
|
+
async lstat(file) {
|
|
160
|
+
const real = path.join(this.root, path.posix.normalize(`/${file}`));
|
|
161
|
+
try {
|
|
162
|
+
return { stats: await lstat(real), path: real };
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async readdir(directory) {
|
|
169
|
+
return (await readdir(path.join(this.root, path.posix.normalize(`/${directory}`)))).sort();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Whether stats are the ones of a whiteout of overlay (a deletion of a layer)
|
|
174
|
+
* @param stats
|
|
175
|
+
*/
|
|
176
|
+
function isWhiteout(stats) {
|
|
177
|
+
return stats.isCharacterDevice() && stats.rdev === 0;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* A file system of the layers of a snapshot (the directories of overlay, the top one first): the deletions of the upper
|
|
181
|
+
* layers (their whiteouts) hide the entries of the lower ones
|
|
182
|
+
*/
|
|
183
|
+
export class LayersTree {
|
|
184
|
+
constructor(layers) {
|
|
185
|
+
this.layers = layers;
|
|
186
|
+
}
|
|
187
|
+
resolve(file) {
|
|
188
|
+
return resolveInTree(this, file);
|
|
189
|
+
}
|
|
190
|
+
async stat(file) {
|
|
191
|
+
try {
|
|
192
|
+
return await lstat(file);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async lstat(file) {
|
|
199
|
+
const parts = path.posix.normalize(`/${file}`).split('/').filter(Boolean);
|
|
200
|
+
for (const layer of this.layers) {
|
|
201
|
+
//An ancestor deleted (or replaced by a file) by this layer hides the path in the lower layers
|
|
202
|
+
for (let length = 1; length < parts.length; length++) {
|
|
203
|
+
const ancestor = await this.stat(path.join(layer, ...parts.slice(0, length)));
|
|
204
|
+
if (ancestor && (isWhiteout(ancestor) || !ancestor.isDirectory()))
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
const real = path.join(layer, ...parts);
|
|
208
|
+
const stats = await this.stat(real);
|
|
209
|
+
if (!stats)
|
|
210
|
+
continue;
|
|
211
|
+
return isWhiteout(stats) ? undefined : { stats: stats, path: real };
|
|
212
|
+
}
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
async readdir(directory) {
|
|
216
|
+
const parts = path.posix.normalize(`/${directory}`).split('/').filter(Boolean);
|
|
217
|
+
const names = new Map();
|
|
218
|
+
for (const layer of this.layers) {
|
|
219
|
+
const stats = await this.stat(path.join(layer, ...parts));
|
|
220
|
+
if (!stats)
|
|
221
|
+
continue;
|
|
222
|
+
//Deleted or replaced by this layer: the lower layers are hidden
|
|
223
|
+
if (!stats.isDirectory())
|
|
224
|
+
break;
|
|
225
|
+
for (const name of await readdir(path.join(layer, ...parts))) {
|
|
226
|
+
if (names.has(name))
|
|
227
|
+
continue;
|
|
228
|
+
const entry = await this.stat(path.join(layer, ...parts, name));
|
|
229
|
+
names.set(name, !!entry && !isWhiteout(entry));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return [...names].filter(([, present]) => present).map(([name]) => name).sort();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { release } from 'node:os';
|
|
3
|
+
const ALLOWED = [
|
|
4
|
+
'accept', 'accept4', 'access', 'adjtimex', 'alarm', 'bind', 'brk', 'cachestat', 'capget', 'capset', 'chdir', 'chmod',
|
|
5
|
+
'chown', 'chown32', 'clock_adjtime', 'clock_adjtime64', 'clock_getres', 'clock_getres_time64', 'clock_gettime',
|
|
6
|
+
'clock_gettime64', 'clock_nanosleep', 'clock_nanosleep_time64', 'close', 'close_range', 'connect', 'copy_file_range',
|
|
7
|
+
'creat', 'dup', 'dup2', 'dup3', 'epoll_create', 'epoll_create1', 'epoll_ctl', 'epoll_ctl_old', 'epoll_pwait',
|
|
8
|
+
'epoll_pwait2', 'epoll_wait', 'epoll_wait_old', 'eventfd', 'eventfd2', 'execve', 'execveat', 'exit', 'exit_group',
|
|
9
|
+
'faccessat', 'faccessat2', 'fadvise64', 'fadvise64_64', 'fallocate', 'fanotify_mark', 'fchdir', 'fchmod', 'fchmodat',
|
|
10
|
+
'fchmodat2', 'fchown', 'fchown32', 'fchownat', 'fcntl', 'fcntl64', 'fdatasync', 'fgetxattr', 'flistxattr', 'flock',
|
|
11
|
+
'fork', 'fremovexattr', 'fsetxattr', 'fstat', 'fstat64', 'fstatat64', 'fstatfs', 'fstatfs64', 'fsync', 'ftruncate',
|
|
12
|
+
'ftruncate64', 'futex', 'futex_requeue', 'futex_time64', 'futex_wait', 'futex_waitv', 'futex_wake', 'futimesat',
|
|
13
|
+
'getcpu', 'getcwd', 'getdents', 'getdents64', 'getegid', 'getegid32', 'geteuid', 'geteuid32', 'getgid', 'getgid32',
|
|
14
|
+
'getgroups', 'getgroups32', 'getitimer', 'getpeername', 'getpgid', 'getpgrp', 'getpid', 'getppid', 'getpriority',
|
|
15
|
+
'getrandom', 'getresgid', 'getresgid32', 'getresuid', 'getresuid32', 'getrlimit', 'get_robust_list', 'getrusage',
|
|
16
|
+
'getsid', 'getsockname', 'getsockopt', 'get_thread_area', 'gettid', 'gettimeofday', 'getuid', 'getuid32', 'getxattr',
|
|
17
|
+
'inotify_add_watch', 'inotify_init', 'inotify_init1', 'inotify_rm_watch', 'io_cancel', 'ioctl', 'io_destroy',
|
|
18
|
+
'io_getevents', 'io_pgetevents', 'io_pgetevents_time64', 'ioprio_get', 'ioprio_set', 'io_setup', 'io_submit',
|
|
19
|
+
'io_uring_enter', 'io_uring_register', 'io_uring_setup', 'ipc', 'kill', 'landlock_add_rule', 'landlock_create_ruleset',
|
|
20
|
+
'landlock_restrict_self', 'lchown', 'lchown32', 'lgetxattr', 'link', 'linkat', 'listen', 'listxattr', 'llistxattr',
|
|
21
|
+
'_llseek', 'lremovexattr', 'lseek', 'lsetxattr', 'lstat', 'lstat64', 'madvise', 'membarrier', 'memfd_create',
|
|
22
|
+
'memfd_secret', 'mincore', 'mkdir', 'mkdirat', 'mknod', 'mknodat', 'mlock', 'mlock2', 'mlockall', 'map_shadow_stack',
|
|
23
|
+
'mmap', 'mmap2', 'mprotect', 'mq_getsetattr', 'mq_notify', 'mq_open', 'mq_timedreceive', 'mq_timedreceive_time64',
|
|
24
|
+
'mq_timedsend', 'mq_timedsend_time64', 'mq_unlink', 'mremap', 'msgctl', 'msgget', 'msgrcv', 'msgsnd', 'msync',
|
|
25
|
+
'munlock', 'munlockall', 'munmap', 'name_to_handle_at', 'nanosleep', 'newfstatat', '_newselect', 'open', 'openat',
|
|
26
|
+
'openat2', 'pause', 'pidfd_open', 'pidfd_send_signal', 'pipe', 'pipe2', 'pkey_alloc', 'pkey_free', 'pkey_mprotect',
|
|
27
|
+
'poll', 'ppoll', 'ppoll_time64', 'prctl', 'pread64', 'preadv', 'preadv2', 'prlimit64', 'process_mrelease', 'pselect6',
|
|
28
|
+
'pselect6_time64', 'pwrite64', 'pwritev', 'pwritev2', 'read', 'readahead', 'readlink', 'readlinkat', 'readv', 'recv',
|
|
29
|
+
'recvfrom', 'recvmmsg', 'recvmmsg_time64', 'recvmsg', 'remap_file_pages', 'removexattr', 'rename', 'renameat',
|
|
30
|
+
'renameat2', 'restart_syscall', 'rmdir', 'rseq', 'rt_sigaction', 'rt_sigpending', 'rt_sigprocmask', 'rt_sigqueueinfo',
|
|
31
|
+
'rt_sigreturn', 'rt_sigsuspend', 'rt_sigtimedwait', 'rt_sigtimedwait_time64', 'rt_tgsigqueueinfo', 'sched_getaffinity',
|
|
32
|
+
'sched_getattr', 'sched_getparam', 'sched_get_priority_max', 'sched_get_priority_min', 'sched_getscheduler',
|
|
33
|
+
'sched_rr_get_interval', 'sched_rr_get_interval_time64', 'sched_setaffinity', 'sched_setattr', 'sched_setparam',
|
|
34
|
+
'sched_setscheduler', 'sched_yield', 'seccomp', 'select', 'semctl', 'semget', 'semop', 'semtimedop',
|
|
35
|
+
'semtimedop_time64', 'send', 'sendfile', 'sendfile64', 'sendmmsg', 'sendmsg', 'sendto', 'setfsgid', 'setfsgid32',
|
|
36
|
+
'setfsuid', 'setfsuid32', 'setgid', 'setgid32', 'setgroups', 'setgroups32', 'setitimer', 'setpgid', 'setpriority',
|
|
37
|
+
'setregid', 'setregid32', 'setresgid', 'setresgid32', 'setresuid', 'setresuid32', 'setreuid', 'setreuid32',
|
|
38
|
+
'setrlimit', 'set_robust_list', 'setsid', 'setsockopt', 'set_thread_area', 'set_tid_address', 'setuid', 'setuid32',
|
|
39
|
+
'setxattr', 'shmat', 'shmctl', 'shmdt', 'shmget', 'shutdown', 'sigaltstack', 'signalfd', 'signalfd4', 'sigprocmask',
|
|
40
|
+
'sigreturn', 'socketcall', 'socketpair', 'splice', 'stat', 'stat64', 'statfs', 'statfs64', 'statx', 'symlink',
|
|
41
|
+
'symlinkat', 'sync', 'sync_file_range', 'syncfs', 'sysinfo', 'tee', 'tgkill', 'time', 'timer_create', 'timer_delete',
|
|
42
|
+
'timer_getoverrun', 'timer_gettime', 'timer_gettime64', 'timer_settime', 'timer_settime64', 'timerfd_create',
|
|
43
|
+
'timerfd_gettime', 'timerfd_gettime64', 'timerfd_settime', 'timerfd_settime64', 'times', 'tkill', 'truncate',
|
|
44
|
+
'truncate64', 'ugetrlimit', 'umask', 'uname', 'unlink', 'unlinkat', 'utime', 'utimensat', 'utimensat_time64', 'utimes',
|
|
45
|
+
'vfork', 'vmsplice', 'wait4', 'waitid', 'waitpid', 'write', 'writev'
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* The architectures of the system calls filtered, by the architecture of the machine (the emulated containers run its
|
|
49
|
+
* system calls: their emulators are processes of the machine)
|
|
50
|
+
*/
|
|
51
|
+
const ARCHITECTURES = {
|
|
52
|
+
x64: ['SCMP_ARCH_X86_64', 'SCMP_ARCH_X86', 'SCMP_ARCH_X32'],
|
|
53
|
+
arm64: ['SCMP_ARCH_ARM', 'SCMP_ARCH_AARCH64'],
|
|
54
|
+
mips64: ['SCMP_ARCH_MIPS', 'SCMP_ARCH_MIPS64', 'SCMP_ARCH_MIPS64N32'],
|
|
55
|
+
mips64el: ['SCMP_ARCH_MIPSEL', 'SCMP_ARCH_MIPSEL64', 'SCMP_ARCH_MIPSEL64N32'],
|
|
56
|
+
s390x: ['SCMP_ARCH_S390', 'SCMP_ARCH_S390X'],
|
|
57
|
+
riscv64: ['SCMP_ARCH_RISCV64']
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The system calls of the architectures of the machine
|
|
61
|
+
*/
|
|
62
|
+
const ARCHITECTURE_SYSCALLS = {
|
|
63
|
+
ppc64: ['sync_file_range2', 'swapcontext'],
|
|
64
|
+
arm: ['arm_fadvise64_64', 'arm_sync_file_range', 'sync_file_range2', 'breakpoint', 'cacheflush', 'set_tls'],
|
|
65
|
+
arm64: ['arm_fadvise64_64', 'arm_sync_file_range', 'sync_file_range2', 'breakpoint', 'cacheflush', 'set_tls'],
|
|
66
|
+
x64: ['arch_prctl', 'modify_ldt'],
|
|
67
|
+
ia32: ['modify_ldt'],
|
|
68
|
+
s390x: ['s390_pci_mmio_read', 's390_pci_mmio_write', 's390_runtime_instr'],
|
|
69
|
+
riscv64: ['riscv_flush_icache']
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* The system calls allowed with the capabilities
|
|
73
|
+
*/
|
|
74
|
+
const CAPABILITY_SYSCALLS = {
|
|
75
|
+
CAP_DAC_READ_SEARCH: ['open_by_handle_at'],
|
|
76
|
+
CAP_SYS_ADMIN: [
|
|
77
|
+
'bpf', 'clone', 'clone3', 'fanotify_init', 'fsconfig', 'fsmount', 'fsopen', 'fspick', 'lookup_dcookie', 'mount',
|
|
78
|
+
'mount_setattr', 'move_mount', 'open_tree', 'perf_event_open', 'quotactl', 'quotactl_fd', 'setdomainname',
|
|
79
|
+
'sethostname', 'setns', 'syslog', 'umount', 'umount2', 'unshare'
|
|
80
|
+
],
|
|
81
|
+
CAP_SYS_BOOT: ['reboot'],
|
|
82
|
+
CAP_SYS_CHROOT: ['chroot'],
|
|
83
|
+
CAP_SYS_MODULE: ['delete_module', 'init_module', 'finit_module'],
|
|
84
|
+
CAP_SYS_PACCT: ['acct'],
|
|
85
|
+
CAP_SYS_PTRACE: ['kcmp', 'pidfd_getfd', 'process_madvise', 'process_vm_readv', 'process_vm_writev', 'ptrace'],
|
|
86
|
+
CAP_SYS_RAWIO: ['iopl', 'ioperm'],
|
|
87
|
+
CAP_SYS_TIME: ['settimeofday', 'stime', 'clock_settime', 'clock_settime64'],
|
|
88
|
+
CAP_SYS_TTY_CONFIG: ['vhangup'],
|
|
89
|
+
CAP_SYS_NICE: ['get_mempolicy', 'mbind', 'set_mempolicy', 'set_mempolicy_home_node'],
|
|
90
|
+
CAP_SYSLOG: ['syslog'],
|
|
91
|
+
CAP_BPF: ['bpf'],
|
|
92
|
+
CAP_PERFMON: ['perf_event_open']
|
|
93
|
+
};
|
|
94
|
+
const AF_VSOCK = 40;
|
|
95
|
+
const ENOSYS = 38;
|
|
96
|
+
/**
|
|
97
|
+
* The flags of clone creating namespaces (NEWNS, NEWUTS, NEWIPC, NEWUSER, NEWPID, NEWNET, NEWCGROUP)
|
|
98
|
+
*/
|
|
99
|
+
const CLONE_NAMESPACES = 0x00020000 | 0x04000000 | 0x08000000 | 0x10000000 | 0x20000000 | 0x40000000 | 0x02000000;
|
|
100
|
+
/**
|
|
101
|
+
* Whether a release of Linux (6.1.0-13-arm64) is at least a version
|
|
102
|
+
* @param kernel
|
|
103
|
+
* @param major
|
|
104
|
+
* @param minor
|
|
105
|
+
*/
|
|
106
|
+
function kernelAtLeast(kernel, major, minor) {
|
|
107
|
+
const match = kernel.match(/^(\d+)\.(\d+)/);
|
|
108
|
+
if (!match)
|
|
109
|
+
return false;
|
|
110
|
+
return Number(match[1]) > major || (Number(match[1]) === major && Number(match[2]) >= minor);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Whether the kernel filters the system calls (the Seccomp field of the status of the processes)
|
|
114
|
+
* @param status the status of a process
|
|
115
|
+
*/
|
|
116
|
+
export function seccompSupported(status) {
|
|
117
|
+
try {
|
|
118
|
+
return /^Seccomp:/m.test(status ?? readFileSync('/proc/self/status', 'utf8'));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The default profile of seccomp of a container, by its capabilities (its bounding set)
|
|
126
|
+
* @param capabilities
|
|
127
|
+
* @param arch the architecture of the machine, as Node.js names it
|
|
128
|
+
* @param kernel the release of its kernel
|
|
129
|
+
*/
|
|
130
|
+
export function defaultSeccompProfile(capabilities, arch = process.arch, kernel = release()) {
|
|
131
|
+
const allow = (names, args) => ({ names: names, action: 'SCMP_ACT_ALLOW', args: args ?? [] });
|
|
132
|
+
const syscalls = [
|
|
133
|
+
allow([...ALLOWED]),
|
|
134
|
+
allow(['socket'], [{ index: 0, value: AF_VSOCK, op: 'SCMP_CMP_NE' }]),
|
|
135
|
+
...[0x0, 0x0008, 0x20000, 0x20008, 0xffffffff].map((value) => allow(['personality'], [{ index: 0, value: value, op: 'SCMP_CMP_EQ' }]))
|
|
136
|
+
];
|
|
137
|
+
if (kernelAtLeast(kernel, 4, 8))
|
|
138
|
+
syscalls.push(allow(['process_vm_readv', 'process_vm_writev', 'ptrace']));
|
|
139
|
+
if (ARCHITECTURE_SYSCALLS[arch])
|
|
140
|
+
syscalls.push(allow([...ARCHITECTURE_SYSCALLS[arch]]));
|
|
141
|
+
for (const capability of capabilities) {
|
|
142
|
+
if (CAPABILITY_SYSCALLS[capability])
|
|
143
|
+
syscalls.push(allow([...CAPABILITY_SYSCALLS[capability]]));
|
|
144
|
+
}
|
|
145
|
+
if (!capabilities.includes('CAP_SYS_ADMIN')) {
|
|
146
|
+
//clone without the flags creating namespaces (its second argument on s390x)
|
|
147
|
+
syscalls.push(allow(['clone'], [{ index: arch === 's390x' ? 1 : 0, value: CLONE_NAMESPACES, valueTwo: 0, op: 'SCMP_CMP_MASKED_EQ' }]));
|
|
148
|
+
//clone3 refused with ENOSYS: the C libraries fall back to clone
|
|
149
|
+
syscalls.push({ names: ['clone3'], action: 'SCMP_ACT_ERRNO', errnoRet: ENOSYS });
|
|
150
|
+
}
|
|
151
|
+
return { defaultAction: 'SCMP_ACT_ERRNO', architectures: [...ARCHITECTURES[arch] ?? []], syscalls: syscalls };
|
|
152
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The capabilities of the containers by default (the ones of containerd, Docker and nerdctl)
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_CAPABILITIES = [
|
|
5
|
+
'CAP_CHOWN',
|
|
6
|
+
'CAP_DAC_OVERRIDE',
|
|
7
|
+
'CAP_FSETID',
|
|
8
|
+
'CAP_FOWNER',
|
|
9
|
+
'CAP_MKNOD',
|
|
10
|
+
'CAP_NET_RAW',
|
|
11
|
+
'CAP_SETGID',
|
|
12
|
+
'CAP_SETUID',
|
|
13
|
+
'CAP_SETFCAP',
|
|
14
|
+
'CAP_SETPCAP',
|
|
15
|
+
'CAP_NET_BIND_SERVICE',
|
|
16
|
+
'CAP_SYS_CHROOT',
|
|
17
|
+
'CAP_KILL',
|
|
18
|
+
'CAP_AUDIT_WRITE'
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* All the capabilities of Linux (the privileged containers)
|
|
22
|
+
*/
|
|
23
|
+
export const ALL_CAPABILITIES = [
|
|
24
|
+
'CAP_CHOWN', 'CAP_DAC_OVERRIDE', 'CAP_DAC_READ_SEARCH', 'CAP_FOWNER', 'CAP_FSETID', 'CAP_KILL', 'CAP_SETGID',
|
|
25
|
+
'CAP_SETUID', 'CAP_SETPCAP', 'CAP_LINUX_IMMUTABLE', 'CAP_NET_BIND_SERVICE', 'CAP_NET_BROADCAST', 'CAP_NET_ADMIN',
|
|
26
|
+
'CAP_NET_RAW', 'CAP_IPC_LOCK', 'CAP_IPC_OWNER', 'CAP_SYS_MODULE', 'CAP_SYS_RAWIO', 'CAP_SYS_CHROOT', 'CAP_SYS_PTRACE',
|
|
27
|
+
'CAP_SYS_PACCT', 'CAP_SYS_ADMIN', 'CAP_SYS_BOOT', 'CAP_SYS_NICE', 'CAP_SYS_RESOURCE', 'CAP_SYS_TIME',
|
|
28
|
+
'CAP_SYS_TTY_CONFIG', 'CAP_MKNOD', 'CAP_LEASE', 'CAP_AUDIT_WRITE', 'CAP_AUDIT_CONTROL', 'CAP_SETFCAP',
|
|
29
|
+
'CAP_MAC_OVERRIDE', 'CAP_MAC_ADMIN', 'CAP_SYSLOG', 'CAP_WAKE_ALARM', 'CAP_BLOCK_SUSPEND', 'CAP_AUDIT_READ',
|
|
30
|
+
'CAP_PERFMON', 'CAP_BPF', 'CAP_CHECKPOINT_RESTORE'
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* The paths masked in the containers (not privileged)
|
|
34
|
+
*/
|
|
35
|
+
const MASKED_PATHS = [
|
|
36
|
+
'/proc/acpi', '/proc/asound', '/proc/kcore', '/proc/keys', '/proc/latency_stats', '/proc/timer_list',
|
|
37
|
+
'/proc/timer_stats', '/proc/sched_debug', '/proc/scsi', '/sys/firmware', '/sys/devices/virtual/powercap'
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* The paths read only in the containers (not privileged)
|
|
41
|
+
*/
|
|
42
|
+
const READONLY_PATHS = ['/proc/bus', '/proc/fs', '/proc/irq', '/proc/sys', '/proc/sysrq-trigger'];
|
|
43
|
+
/**
|
|
44
|
+
* The devices of the containers allowed by default (the ones of runc: null, zero, full, tty, random, urandom, the
|
|
45
|
+
* pseudo terminals)
|
|
46
|
+
*/
|
|
47
|
+
const DEFAULT_DEVICE_RULES = [
|
|
48
|
+
{ allow: false, access: 'rwm' },
|
|
49
|
+
{ allow: true, type: 'c', major: 1, minor: 3, access: 'rwm' },
|
|
50
|
+
{ allow: true, type: 'c', major: 1, minor: 8, access: 'rwm' },
|
|
51
|
+
{ allow: true, type: 'c', major: 1, minor: 7, access: 'rwm' },
|
|
52
|
+
{ allow: true, type: 'c', major: 5, minor: 0, access: 'rwm' },
|
|
53
|
+
{ allow: true, type: 'c', major: 1, minor: 5, access: 'rwm' },
|
|
54
|
+
{ allow: true, type: 'c', major: 1, minor: 9, access: 'rwm' },
|
|
55
|
+
{ allow: true, type: 'c', major: 5, minor: 2, access: 'rwm' },
|
|
56
|
+
{ allow: true, type: 'c', major: 136, access: 'rwm' }
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* Parse a rule of the devices of a cgroup as Docker writes it: "c 188:* rwm", "b 8:16 r", "a *:* rwm"
|
|
60
|
+
* @param rule
|
|
61
|
+
*/
|
|
62
|
+
export function parseDeviceCgroupRule(rule) {
|
|
63
|
+
const match = rule.trim().match(/^([acb]) (\*|\d+):(\*|\d+) ([rwm]{1,3})$/);
|
|
64
|
+
if (!match || new Set(match[4]).size !== match[4].length)
|
|
65
|
+
throw new Error(`The rule of the devices "${rule}" is not valid ("c 188:* rwm": a type a, c or b, the major and the minor numbers or *, the access of r, w and m)`);
|
|
66
|
+
return {
|
|
67
|
+
type: match[1],
|
|
68
|
+
...match[2] === '*' ? {} : { major: Number(match[2]) },
|
|
69
|
+
...match[3] === '*' ? {} : { minor: Number(match[3]) },
|
|
70
|
+
access: match[4]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The capability of a name (NET_ADMIN, CAP_NET_ADMIN)
|
|
75
|
+
* @param name
|
|
76
|
+
*/
|
|
77
|
+
function normalizeCapability(name) {
|
|
78
|
+
const upper = name.trim().toUpperCase();
|
|
79
|
+
return upper.startsWith('CAP_') ? upper : `CAP_${upper}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The capabilities of a container: the ones by default (all for the privileged containers), the ones added, without
|
|
83
|
+
* the ones dropped (ALL drops all)
|
|
84
|
+
* @param options
|
|
85
|
+
*/
|
|
86
|
+
export function containerCapabilities(options) {
|
|
87
|
+
let capabilities = new Set(options.privileged ? ALL_CAPABILITIES : DEFAULT_CAPABILITIES);
|
|
88
|
+
const drop = (options.capDrop ?? []).map(normalizeCapability);
|
|
89
|
+
if (drop.includes('CAP_ALL'))
|
|
90
|
+
capabilities = new Set();
|
|
91
|
+
else
|
|
92
|
+
drop.forEach((capability) => capabilities.delete(capability));
|
|
93
|
+
const add = (options.capAdd ?? []).map(normalizeCapability);
|
|
94
|
+
if (add.includes('CAP_ALL'))
|
|
95
|
+
ALL_CAPABILITIES.forEach((capability) => capabilities.add(capability));
|
|
96
|
+
else
|
|
97
|
+
add.forEach((capability) => capabilities.add(capability));
|
|
98
|
+
return [...capabilities];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The specification of the runtime (OCI) of a container on Linux, as containerd and nerdctl generate it
|
|
102
|
+
* @param options
|
|
103
|
+
*/
|
|
104
|
+
export function generateSpec(options) {
|
|
105
|
+
const capabilities = containerCapabilities(options);
|
|
106
|
+
const namespaces = [{ type: 'mount' }, { type: 'uts' }];
|
|
107
|
+
if (!options.pidHost)
|
|
108
|
+
namespaces.push({ type: 'pid' });
|
|
109
|
+
if (!options.ipcHost)
|
|
110
|
+
namespaces.push({ type: 'ipc' });
|
|
111
|
+
if (options.cgroupNamespace)
|
|
112
|
+
namespaces.push({ type: 'cgroup' });
|
|
113
|
+
if (options.network.mode === 'none' || options.network.mode === 'cni')
|
|
114
|
+
namespaces.push({ type: 'network' });
|
|
115
|
+
if (options.network.mode === 'path')
|
|
116
|
+
namespaces.push({ type: 'network', path: options.network.path });
|
|
117
|
+
const mounts = [
|
|
118
|
+
{ destination: '/proc', type: 'proc', source: 'proc', options: ['nosuid', 'noexec', 'nodev'] },
|
|
119
|
+
{ destination: '/dev', type: 'tmpfs', source: 'tmpfs', options: ['nosuid', 'strictatime', 'mode=755', 'size=65536k'] },
|
|
120
|
+
{ destination: '/dev/pts', type: 'devpts', source: 'devpts', options: ['nosuid', 'noexec', 'newinstance', 'ptmxmode=0666', 'mode=0620', 'gid=5'] },
|
|
121
|
+
{ destination: '/dev/shm', type: 'tmpfs', source: 'shm', options: ['nosuid', 'noexec', 'nodev', 'mode=1777', `size=${options.shmSize ?? 64 * 1024 * 1024}`] },
|
|
122
|
+
{ destination: '/dev/mqueue', type: 'mqueue', source: 'mqueue', options: ['nosuid', 'noexec', 'nodev'] },
|
|
123
|
+
{ destination: '/sys', type: 'sysfs', source: 'sysfs', options: ['nosuid', 'noexec', 'nodev', options.privileged ? 'rw' : 'ro'] },
|
|
124
|
+
{ destination: '/sys/fs/cgroup', type: 'cgroup', source: 'cgroup', options: ['nosuid', 'noexec', 'nodev', 'relatime', options.privileged ? 'rw' : 'ro'] }
|
|
125
|
+
];
|
|
126
|
+
for (const mount of options.mounts ?? []) {
|
|
127
|
+
//A mount given replaces the one of its destination
|
|
128
|
+
const index = mounts.findIndex((existing) => existing.destination === mount.destination);
|
|
129
|
+
if (index >= 0)
|
|
130
|
+
mounts.splice(index, 1);
|
|
131
|
+
mounts.push({ type: mount.type ?? 'bind', source: mount.source, destination: mount.destination, options: mount.options ?? ['rbind', 'rprivate'] });
|
|
132
|
+
}
|
|
133
|
+
const devices = options.devices ?? [];
|
|
134
|
+
const resources = {
|
|
135
|
+
devices: options.privileged ? [{ allow: true, access: 'rwm' }] : [
|
|
136
|
+
...DEFAULT_DEVICE_RULES,
|
|
137
|
+
...devices.map((device) => ({ allow: true, type: device.type, major: device.major, minor: device.minor, access: device.permissions })),
|
|
138
|
+
...(options.deviceCgroupRules ?? []).map((rule) => ({ allow: true, ...rule }))
|
|
139
|
+
]
|
|
140
|
+
};
|
|
141
|
+
if (options.memory || options.oomKillDisable) {
|
|
142
|
+
resources.memory = {};
|
|
143
|
+
if (options.memory)
|
|
144
|
+
resources.memory.limit = options.memory;
|
|
145
|
+
if (options.memorySwap)
|
|
146
|
+
resources.memory.swap = options.memorySwap;
|
|
147
|
+
if (options.oomKillDisable)
|
|
148
|
+
resources.memory.disableOOMKiller = true;
|
|
149
|
+
}
|
|
150
|
+
if (options.cpuQuota || options.cpuShares || options.cpuset) {
|
|
151
|
+
resources.cpu = {};
|
|
152
|
+
if (options.cpuQuota) {
|
|
153
|
+
resources.cpu.quota = options.cpuQuota;
|
|
154
|
+
resources.cpu.period = options.cpuPeriod ?? 100000;
|
|
155
|
+
}
|
|
156
|
+
if (options.cpuShares)
|
|
157
|
+
resources.cpu.shares = options.cpuShares;
|
|
158
|
+
if (options.cpuset)
|
|
159
|
+
resources.cpu.cpus = options.cpuset;
|
|
160
|
+
}
|
|
161
|
+
if (options.pidsLimit)
|
|
162
|
+
resources.pids = { limit: options.pidsLimit };
|
|
163
|
+
return {
|
|
164
|
+
ociVersion: '1.0.2-dev',
|
|
165
|
+
process: {
|
|
166
|
+
terminal: !!options.terminal,
|
|
167
|
+
user: { uid: options.uid, gid: options.gid, ...options.additionalGids.length ? { additionalGids: options.additionalGids } : {} },
|
|
168
|
+
args: options.args,
|
|
169
|
+
env: options.env,
|
|
170
|
+
cwd: options.cwd || '/',
|
|
171
|
+
capabilities: { bounding: capabilities, effective: capabilities, permitted: capabilities },
|
|
172
|
+
rlimits: options.rlimits ?? [{ type: 'RLIMIT_NOFILE', hard: 1024, soft: 1024 }],
|
|
173
|
+
noNewPrivileges: !options.privileged
|
|
174
|
+
},
|
|
175
|
+
root: { path: 'rootfs', readonly: !!options.readonlyRootfs },
|
|
176
|
+
hostname: options.hostname,
|
|
177
|
+
mounts: mounts,
|
|
178
|
+
...options.hooks ? { hooks: options.hooks } : {},
|
|
179
|
+
annotations: options.annotations ?? {},
|
|
180
|
+
linux: {
|
|
181
|
+
resources: resources,
|
|
182
|
+
cgroupsPath: options.cgroupsPath,
|
|
183
|
+
namespaces: namespaces,
|
|
184
|
+
devices: devices.map((device) => ({
|
|
185
|
+
path: device.containerPath,
|
|
186
|
+
type: device.type,
|
|
187
|
+
major: device.major,
|
|
188
|
+
minor: device.minor,
|
|
189
|
+
fileMode: device.fileMode ?? 0o666,
|
|
190
|
+
uid: device.uid ?? 0,
|
|
191
|
+
gid: device.gid ?? 0
|
|
192
|
+
})),
|
|
193
|
+
...options.sysctls && Object.keys(options.sysctls).length ? { sysctl: options.sysctls } : {},
|
|
194
|
+
...options.seccomp ? { seccomp: options.seccomp } : {},
|
|
195
|
+
...options.privileged ? {} : { maskedPaths: [...MASKED_PATHS], readonlyPaths: [...READONLY_PATHS] }
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The specification of a process executed in a container (exec): the one of the container, its arguments, its
|
|
201
|
+
* environment, its directory, its user and its terminal changed
|
|
202
|
+
* @param spec the specification of the container
|
|
203
|
+
* @param options
|
|
204
|
+
*/
|
|
205
|
+
export function execProcessSpec(spec, options) {
|
|
206
|
+
const process = structuredClone(spec.process ?? {});
|
|
207
|
+
process.args = options.args;
|
|
208
|
+
process.terminal = !!options.terminal;
|
|
209
|
+
if (options.env?.length) {
|
|
210
|
+
const env = new Map((process.env ?? []).map((entry) => [entry.split('=')[0], entry]));
|
|
211
|
+
for (const entry of options.env)
|
|
212
|
+
env.set(entry.split('=')[0], entry);
|
|
213
|
+
process.env = [...env.values()];
|
|
214
|
+
}
|
|
215
|
+
if (options.cwd)
|
|
216
|
+
process.cwd = options.cwd;
|
|
217
|
+
if (options.uid !== undefined)
|
|
218
|
+
process.user = { uid: options.uid, gid: options.gid ?? 0, ...options.additionalGids?.length ? { additionalGids: options.additionalGids } : {} };
|
|
219
|
+
return process;
|
|
220
|
+
}
|