@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.
Files changed (301) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +409 -2
  3. package/THIRD_PARTY_NOTICES.md +310 -0
  4. package/dist/cjs/client/BuildKit.d.ts +176 -0
  5. package/dist/cjs/client/BuildKit.js +536 -0
  6. package/dist/cjs/client/BuildKitMessages.d.ts +35 -0
  7. package/dist/cjs/client/BuildKitMessages.js +123 -0
  8. package/dist/cjs/client/ContainerStore.d.ts +558 -0
  9. package/dist/cjs/client/ContainerStore.js +1384 -0
  10. package/dist/cjs/client/ContainerdClient.d.ts +244 -0
  11. package/dist/cjs/client/ContainerdClient.js +455 -0
  12. package/dist/cjs/client/DockerIgnore.d.ts +44 -0
  13. package/dist/cjs/client/DockerIgnore.js +186 -0
  14. package/dist/cjs/client/Fifo.d.ts +31 -0
  15. package/dist/cjs/client/Fifo.js +66 -0
  16. package/dist/cjs/client/ImageStore.d.ts +258 -0
  17. package/dist/cjs/client/ImageStore.js +636 -0
  18. package/dist/cjs/client/Messages.d.ts +103 -0
  19. package/dist/cjs/client/Messages.js +397 -0
  20. package/dist/cjs/client/Networks.d.ts +221 -0
  21. package/dist/cjs/client/Networks.js +630 -0
  22. package/dist/cjs/client/Platforms.d.ts +53 -0
  23. package/dist/cjs/client/Platforms.js +169 -0
  24. package/dist/cjs/client/Reference.d.ts +33 -0
  25. package/dist/cjs/client/Reference.js +70 -0
  26. package/dist/cjs/client/Registry.d.ts +145 -0
  27. package/dist/cjs/client/Registry.js +272 -0
  28. package/dist/cjs/client/Rootfs.d.ts +83 -0
  29. package/dist/cjs/client/Rootfs.js +245 -0
  30. package/dist/cjs/client/Seccomp.d.ts +36 -0
  31. package/dist/cjs/client/Seccomp.js +156 -0
  32. package/dist/cjs/client/Spec.d.ts +151 -0
  33. package/dist/cjs/client/Spec.js +227 -0
  34. package/dist/cjs/client/Volumes.d.ts +42 -0
  35. package/dist/cjs/client/Volumes.js +80 -0
  36. package/dist/cjs/containerd/Containerd.d.ts +442 -0
  37. package/dist/cjs/containerd/Containerd.js +929 -0
  38. package/dist/cjs/containerd/exceptions/ContainerdConnectionException.d.ts +9 -0
  39. package/dist/cjs/containerd/exceptions/ContainerdConnectionException.js +16 -0
  40. package/dist/cjs/containerd/exceptions/ContainerdContainerNameConflictException.d.ts +8 -0
  41. package/dist/cjs/containerd/exceptions/ContainerdContainerNameConflictException.js +15 -0
  42. package/dist/cjs/containerd/exceptions/ContainerdContainerNotFoundException.d.ts +9 -0
  43. package/dist/cjs/containerd/exceptions/ContainerdContainerNotFoundException.js +16 -0
  44. package/dist/cjs/containerd/exceptions/ContainerdContainerStateException.d.ts +10 -0
  45. package/dist/cjs/containerd/exceptions/ContainerdContainerStateException.js +17 -0
  46. package/dist/cjs/containerd/exceptions/ContainerdImageBuildException.d.ts +9 -0
  47. package/dist/cjs/containerd/exceptions/ContainerdImageBuildException.js +16 -0
  48. package/dist/cjs/containerd/exceptions/ContainerdImageExportException.d.ts +9 -0
  49. package/dist/cjs/containerd/exceptions/ContainerdImageExportException.js +16 -0
  50. package/dist/cjs/containerd/exceptions/ContainerdImageImportException.d.ts +9 -0
  51. package/dist/cjs/containerd/exceptions/ContainerdImageImportException.js +16 -0
  52. package/dist/cjs/containerd/exceptions/ContainerdImageNotFoundException.d.ts +9 -0
  53. package/dist/cjs/containerd/exceptions/ContainerdImageNotFoundException.js +16 -0
  54. package/dist/cjs/containerd/exceptions/ContainerdImagePullException.d.ts +9 -0
  55. package/dist/cjs/containerd/exceptions/ContainerdImagePullException.js +16 -0
  56. package/dist/cjs/containerd/exceptions/ContainerdImagePushException.d.ts +8 -0
  57. package/dist/cjs/containerd/exceptions/ContainerdImagePushException.js +15 -0
  58. package/dist/cjs/containerd/exceptions/ContainerdNetworkConflictException.d.ts +9 -0
  59. package/dist/cjs/containerd/exceptions/ContainerdNetworkConflictException.js +16 -0
  60. package/dist/cjs/containerd/exceptions/ContainerdNetworkNotFoundException.d.ts +9 -0
  61. package/dist/cjs/containerd/exceptions/ContainerdNetworkNotFoundException.js +16 -0
  62. package/dist/cjs/containerd/exceptions/ContainerdPathNotFoundException.d.ts +8 -0
  63. package/dist/cjs/containerd/exceptions/ContainerdPathNotFoundException.js +15 -0
  64. package/dist/cjs/containerd/exceptions/ContainerdPlatformException.d.ts +9 -0
  65. package/dist/cjs/containerd/exceptions/ContainerdPlatformException.js +16 -0
  66. package/dist/cjs/containerd/exceptions/ContainerdVolumeInUseException.d.ts +8 -0
  67. package/dist/cjs/containerd/exceptions/ContainerdVolumeInUseException.js +15 -0
  68. package/dist/cjs/containerd/exceptions/ContainerdVolumeNotFoundException.d.ts +8 -0
  69. package/dist/cjs/containerd/exceptions/ContainerdVolumeNotFoundException.js +15 -0
  70. package/dist/cjs/containerd/lib/ContainerdContainer.d.ts +292 -0
  71. package/dist/cjs/containerd/lib/ContainerdContainer.js +536 -0
  72. package/dist/cjs/containerd/lib/ContainerdContainerTTY.d.ts +116 -0
  73. package/dist/cjs/containerd/lib/ContainerdContainerTTY.js +178 -0
  74. package/dist/cjs/containerd/lib/ContainerdErrors.d.ts +6 -0
  75. package/dist/cjs/containerd/lib/ContainerdErrors.js +37 -0
  76. package/dist/cjs/containerd/lib/ContainerdImage.d.ts +149 -0
  77. package/dist/cjs/containerd/lib/ContainerdImage.js +222 -0
  78. package/dist/cjs/containerd/options/ContainerdPruneOptions.d.ts +44 -0
  79. package/dist/cjs/containerd/options/ContainerdPruneOptions.js +51 -0
  80. package/dist/cjs/containerd/options/ContainerdRegistryAuthOptions.d.ts +32 -0
  81. package/dist/cjs/containerd/options/ContainerdRegistryAuthOptions.js +45 -0
  82. package/dist/cjs/containerd/options/container/ContainerCommitOptions.d.ts +57 -0
  83. package/dist/cjs/containerd/options/container/ContainerCommitOptions.js +66 -0
  84. package/dist/cjs/containerd/options/container/ContainerCreateOptions.d.ts +273 -0
  85. package/dist/cjs/containerd/options/container/ContainerCreateOptions.js +239 -0
  86. package/dist/cjs/containerd/options/container/ContainerExecOptions.d.ts +53 -0
  87. package/dist/cjs/containerd/options/container/ContainerExecOptions.js +63 -0
  88. package/dist/cjs/containerd/options/container/ContainerExportDirectoryOptions.d.ts +32 -0
  89. package/dist/cjs/containerd/options/container/ContainerExportDirectoryOptions.js +45 -0
  90. package/dist/cjs/containerd/options/container/ContainerKillOptions.d.ts +30 -0
  91. package/dist/cjs/containerd/options/container/ContainerKillOptions.js +41 -0
  92. package/dist/cjs/containerd/options/container/ContainerLogsOptions.d.ts +34 -0
  93. package/dist/cjs/containerd/options/container/ContainerLogsOptions.js +44 -0
  94. package/dist/cjs/containerd/options/container/ContainerRemoveOptions.d.ts +22 -0
  95. package/dist/cjs/containerd/options/container/ContainerRemoveOptions.js +34 -0
  96. package/dist/cjs/containerd/options/container/ContainerResourceOptions.d.ts +63 -0
  97. package/dist/cjs/containerd/options/container/ContainerResourceOptions.js +67 -0
  98. package/dist/cjs/containerd/options/container/ContainerStopOptions.d.ts +30 -0
  99. package/dist/cjs/containerd/options/container/ContainerStopOptions.js +41 -0
  100. package/dist/cjs/containerd/options/container/ContainerTTYConsoleSizeOptions.d.ts +26 -0
  101. package/dist/cjs/containerd/options/container/ContainerTTYConsoleSizeOptions.js +40 -0
  102. package/dist/cjs/containerd/options/container/ContainerTTYOptions.d.ts +50 -0
  103. package/dist/cjs/containerd/options/container/ContainerTTYOptions.js +63 -0
  104. package/dist/cjs/containerd/options/image/ImageBuildOptions.d.ts +88 -0
  105. package/dist/cjs/containerd/options/image/ImageBuildOptions.js +95 -0
  106. package/dist/cjs/containerd/options/image/ImageExportOptions.d.ts +25 -0
  107. package/dist/cjs/containerd/options/image/ImageExportOptions.js +39 -0
  108. package/dist/cjs/containerd/options/image/ImageImportOptions.d.ts +38 -0
  109. package/dist/cjs/containerd/options/image/ImageImportOptions.js +47 -0
  110. package/dist/cjs/containerd/options/image/ImagePullOptions.d.ts +53 -0
  111. package/dist/cjs/containerd/options/image/ImagePullOptions.js +66 -0
  112. package/dist/cjs/containerd/options/image/ImagePushOptions.d.ts +44 -0
  113. package/dist/cjs/containerd/options/image/ImagePushOptions.js +58 -0
  114. package/dist/cjs/containerd/options/network/NetworkCreateOptions.d.ts +82 -0
  115. package/dist/cjs/containerd/options/network/NetworkCreateOptions.js +83 -0
  116. package/dist/cjs/containerd/options/volume/VolumeCreateOptions.d.ts +26 -0
  117. package/dist/cjs/containerd/options/volume/VolumeCreateOptions.js +40 -0
  118. package/dist/cjs/containerd/types/ContainerdBind.d.ts +28 -0
  119. package/dist/cjs/containerd/types/ContainerdBind.js +2 -0
  120. package/dist/cjs/containerd/types/ContainerdBuildOutputCallback.d.ts +6 -0
  121. package/dist/cjs/containerd/types/ContainerdBuildOutputCallback.js +2 -0
  122. package/dist/cjs/containerd/types/ContainerdContainerNetwork.d.ts +40 -0
  123. package/dist/cjs/containerd/types/ContainerdContainerNetwork.js +2 -0
  124. package/dist/cjs/containerd/types/ContainerdContainerPort.d.ts +22 -0
  125. package/dist/cjs/containerd/types/ContainerdContainerPort.js +2 -0
  126. package/dist/cjs/containerd/types/ContainerdContainerState.d.ts +42 -0
  127. package/dist/cjs/containerd/types/ContainerdContainerState.js +2 -0
  128. package/dist/cjs/containerd/types/ContainerdContainerStats.d.ts +107 -0
  129. package/dist/cjs/containerd/types/ContainerdContainerStats.js +2 -0
  130. package/dist/cjs/containerd/types/ContainerdDevice.d.ts +25 -0
  131. package/dist/cjs/containerd/types/ContainerdDevice.js +2 -0
  132. package/dist/cjs/containerd/types/ContainerdExecResult.d.ts +18 -0
  133. package/dist/cjs/containerd/types/ContainerdExecResult.js +2 -0
  134. package/dist/cjs/containerd/types/ContainerdImageConfig.d.ts +46 -0
  135. package/dist/cjs/containerd/types/ContainerdImageConfig.js +2 -0
  136. package/dist/cjs/containerd/types/ContainerdNetworkInfo.d.ts +49 -0
  137. package/dist/cjs/containerd/types/ContainerdNetworkInfo.js +2 -0
  138. package/dist/cjs/containerd/types/ContainerdProgressCallback.d.ts +29 -0
  139. package/dist/cjs/containerd/types/ContainerdProgressCallback.js +2 -0
  140. package/dist/cjs/containerd/types/ContainerdPruneResult.d.ts +21 -0
  141. package/dist/cjs/containerd/types/ContainerdPruneResult.js +2 -0
  142. package/dist/cjs/containerd/types/ContainerdRestartPolicy.d.ts +13 -0
  143. package/dist/cjs/containerd/types/ContainerdRestartPolicy.js +2 -0
  144. package/dist/cjs/containerd/types/ContainerdTmpfs.d.ts +20 -0
  145. package/dist/cjs/containerd/types/ContainerdTmpfs.js +2 -0
  146. package/dist/cjs/containerd/types/ContainerdVolume.d.ts +19 -0
  147. package/dist/cjs/containerd/types/ContainerdVolume.js +2 -0
  148. package/dist/cjs/containerd/types/ContainerdVolumeInfo.d.ts +26 -0
  149. package/dist/cjs/containerd/types/ContainerdVolumeInfo.js +2 -0
  150. package/dist/cjs/exports/Containerd.d.ts +69 -0
  151. package/dist/cjs/exports/Containerd.js +87 -0
  152. package/dist/cjs/package.json +1 -0
  153. package/dist/esm/client/BuildKit.js +488 -0
  154. package/dist/esm/client/BuildKitMessages.js +120 -0
  155. package/dist/esm/client/ContainerStore.js +1339 -0
  156. package/dist/esm/client/ContainerdClient.js +416 -0
  157. package/dist/esm/client/DockerIgnore.js +179 -0
  158. package/dist/esm/client/Fifo.js +59 -0
  159. package/dist/esm/client/ImageStore.js +628 -0
  160. package/dist/esm/client/Messages.js +393 -0
  161. package/dist/esm/client/Networks.js +621 -0
  162. package/dist/esm/client/Platforms.js +156 -0
  163. package/dist/esm/client/Reference.js +66 -0
  164. package/dist/esm/client/Registry.js +263 -0
  165. package/dist/esm/client/Rootfs.js +234 -0
  166. package/dist/esm/client/Seccomp.js +152 -0
  167. package/dist/esm/client/Spec.js +220 -0
  168. package/dist/esm/client/Volumes.js +73 -0
  169. package/dist/esm/containerd/Containerd.js +923 -0
  170. package/dist/esm/containerd/exceptions/ContainerdConnectionException.js +12 -0
  171. package/dist/esm/containerd/exceptions/ContainerdContainerNameConflictException.js +11 -0
  172. package/dist/esm/containerd/exceptions/ContainerdContainerNotFoundException.js +12 -0
  173. package/dist/esm/containerd/exceptions/ContainerdContainerStateException.js +13 -0
  174. package/dist/esm/containerd/exceptions/ContainerdImageBuildException.js +12 -0
  175. package/dist/esm/containerd/exceptions/ContainerdImageExportException.js +12 -0
  176. package/dist/esm/containerd/exceptions/ContainerdImageImportException.js +12 -0
  177. package/dist/esm/containerd/exceptions/ContainerdImageNotFoundException.js +12 -0
  178. package/dist/esm/containerd/exceptions/ContainerdImagePullException.js +12 -0
  179. package/dist/esm/containerd/exceptions/ContainerdImagePushException.js +11 -0
  180. package/dist/esm/containerd/exceptions/ContainerdNetworkConflictException.js +12 -0
  181. package/dist/esm/containerd/exceptions/ContainerdNetworkNotFoundException.js +12 -0
  182. package/dist/esm/containerd/exceptions/ContainerdPathNotFoundException.js +11 -0
  183. package/dist/esm/containerd/exceptions/ContainerdPlatformException.js +12 -0
  184. package/dist/esm/containerd/exceptions/ContainerdVolumeInUseException.js +11 -0
  185. package/dist/esm/containerd/exceptions/ContainerdVolumeNotFoundException.js +11 -0
  186. package/dist/esm/containerd/lib/ContainerdContainer.js +533 -0
  187. package/dist/esm/containerd/lib/ContainerdContainerTTY.js +175 -0
  188. package/dist/esm/containerd/lib/ContainerdErrors.js +34 -0
  189. package/dist/esm/containerd/lib/ContainerdImage.js +219 -0
  190. package/dist/esm/containerd/options/ContainerdPruneOptions.js +47 -0
  191. package/dist/esm/containerd/options/ContainerdRegistryAuthOptions.js +41 -0
  192. package/dist/esm/containerd/options/container/ContainerCommitOptions.js +62 -0
  193. package/dist/esm/containerd/options/container/ContainerCreateOptions.js +235 -0
  194. package/dist/esm/containerd/options/container/ContainerExecOptions.js +59 -0
  195. package/dist/esm/containerd/options/container/ContainerExportDirectoryOptions.js +41 -0
  196. package/dist/esm/containerd/options/container/ContainerKillOptions.js +37 -0
  197. package/dist/esm/containerd/options/container/ContainerLogsOptions.js +40 -0
  198. package/dist/esm/containerd/options/container/ContainerRemoveOptions.js +30 -0
  199. package/dist/esm/containerd/options/container/ContainerResourceOptions.js +63 -0
  200. package/dist/esm/containerd/options/container/ContainerStopOptions.js +37 -0
  201. package/dist/esm/containerd/options/container/ContainerTTYConsoleSizeOptions.js +36 -0
  202. package/dist/esm/containerd/options/container/ContainerTTYOptions.js +59 -0
  203. package/dist/esm/containerd/options/image/ImageBuildOptions.js +91 -0
  204. package/dist/esm/containerd/options/image/ImageExportOptions.js +35 -0
  205. package/dist/esm/containerd/options/image/ImageImportOptions.js +43 -0
  206. package/dist/esm/containerd/options/image/ImagePullOptions.js +62 -0
  207. package/dist/esm/containerd/options/image/ImagePushOptions.js +54 -0
  208. package/dist/esm/containerd/options/network/NetworkCreateOptions.js +79 -0
  209. package/dist/esm/containerd/options/volume/VolumeCreateOptions.js +36 -0
  210. package/dist/esm/containerd/types/ContainerdBind.js +1 -0
  211. package/dist/esm/containerd/types/ContainerdBuildOutputCallback.js +1 -0
  212. package/dist/esm/containerd/types/ContainerdContainerNetwork.js +1 -0
  213. package/dist/esm/containerd/types/ContainerdContainerPort.js +1 -0
  214. package/dist/esm/containerd/types/ContainerdContainerState.js +1 -0
  215. package/dist/esm/containerd/types/ContainerdContainerStats.js +1 -0
  216. package/dist/esm/containerd/types/ContainerdDevice.js +1 -0
  217. package/dist/esm/containerd/types/ContainerdExecResult.js +1 -0
  218. package/dist/esm/containerd/types/ContainerdImageConfig.js +1 -0
  219. package/dist/esm/containerd/types/ContainerdNetworkInfo.js +1 -0
  220. package/dist/esm/containerd/types/ContainerdProgressCallback.js +1 -0
  221. package/dist/esm/containerd/types/ContainerdPruneResult.js +1 -0
  222. package/dist/esm/containerd/types/ContainerdRestartPolicy.js +1 -0
  223. package/dist/esm/containerd/types/ContainerdTmpfs.js +1 -0
  224. package/dist/esm/containerd/types/ContainerdVolume.js +1 -0
  225. package/dist/esm/containerd/types/ContainerdVolumeInfo.js +1 -0
  226. package/dist/esm/exports/Containerd.js +68 -0
  227. package/dist/types/client/BuildKit.d.ts +176 -0
  228. package/dist/types/client/BuildKitMessages.d.ts +35 -0
  229. package/dist/types/client/ContainerStore.d.ts +558 -0
  230. package/dist/types/client/ContainerdClient.d.ts +244 -0
  231. package/dist/types/client/DockerIgnore.d.ts +44 -0
  232. package/dist/types/client/Fifo.d.ts +31 -0
  233. package/dist/types/client/ImageStore.d.ts +258 -0
  234. package/dist/types/client/Messages.d.ts +103 -0
  235. package/dist/types/client/Networks.d.ts +221 -0
  236. package/dist/types/client/Platforms.d.ts +53 -0
  237. package/dist/types/client/Reference.d.ts +33 -0
  238. package/dist/types/client/Registry.d.ts +145 -0
  239. package/dist/types/client/Rootfs.d.ts +83 -0
  240. package/dist/types/client/Seccomp.d.ts +36 -0
  241. package/dist/types/client/Spec.d.ts +151 -0
  242. package/dist/types/client/Volumes.d.ts +42 -0
  243. package/dist/types/containerd/Containerd.d.ts +442 -0
  244. package/dist/types/containerd/exceptions/ContainerdConnectionException.d.ts +9 -0
  245. package/dist/types/containerd/exceptions/ContainerdContainerNameConflictException.d.ts +8 -0
  246. package/dist/types/containerd/exceptions/ContainerdContainerNotFoundException.d.ts +9 -0
  247. package/dist/types/containerd/exceptions/ContainerdContainerStateException.d.ts +10 -0
  248. package/dist/types/containerd/exceptions/ContainerdImageBuildException.d.ts +9 -0
  249. package/dist/types/containerd/exceptions/ContainerdImageExportException.d.ts +9 -0
  250. package/dist/types/containerd/exceptions/ContainerdImageImportException.d.ts +9 -0
  251. package/dist/types/containerd/exceptions/ContainerdImageNotFoundException.d.ts +9 -0
  252. package/dist/types/containerd/exceptions/ContainerdImagePullException.d.ts +9 -0
  253. package/dist/types/containerd/exceptions/ContainerdImagePushException.d.ts +8 -0
  254. package/dist/types/containerd/exceptions/ContainerdNetworkConflictException.d.ts +9 -0
  255. package/dist/types/containerd/exceptions/ContainerdNetworkNotFoundException.d.ts +9 -0
  256. package/dist/types/containerd/exceptions/ContainerdPathNotFoundException.d.ts +8 -0
  257. package/dist/types/containerd/exceptions/ContainerdPlatformException.d.ts +9 -0
  258. package/dist/types/containerd/exceptions/ContainerdVolumeInUseException.d.ts +8 -0
  259. package/dist/types/containerd/exceptions/ContainerdVolumeNotFoundException.d.ts +8 -0
  260. package/dist/types/containerd/lib/ContainerdContainer.d.ts +292 -0
  261. package/dist/types/containerd/lib/ContainerdContainerTTY.d.ts +116 -0
  262. package/dist/types/containerd/lib/ContainerdErrors.d.ts +6 -0
  263. package/dist/types/containerd/lib/ContainerdImage.d.ts +149 -0
  264. package/dist/types/containerd/options/ContainerdPruneOptions.d.ts +44 -0
  265. package/dist/types/containerd/options/ContainerdRegistryAuthOptions.d.ts +32 -0
  266. package/dist/types/containerd/options/container/ContainerCommitOptions.d.ts +57 -0
  267. package/dist/types/containerd/options/container/ContainerCreateOptions.d.ts +273 -0
  268. package/dist/types/containerd/options/container/ContainerExecOptions.d.ts +53 -0
  269. package/dist/types/containerd/options/container/ContainerExportDirectoryOptions.d.ts +32 -0
  270. package/dist/types/containerd/options/container/ContainerKillOptions.d.ts +30 -0
  271. package/dist/types/containerd/options/container/ContainerLogsOptions.d.ts +34 -0
  272. package/dist/types/containerd/options/container/ContainerRemoveOptions.d.ts +22 -0
  273. package/dist/types/containerd/options/container/ContainerResourceOptions.d.ts +63 -0
  274. package/dist/types/containerd/options/container/ContainerStopOptions.d.ts +30 -0
  275. package/dist/types/containerd/options/container/ContainerTTYConsoleSizeOptions.d.ts +26 -0
  276. package/dist/types/containerd/options/container/ContainerTTYOptions.d.ts +50 -0
  277. package/dist/types/containerd/options/image/ImageBuildOptions.d.ts +88 -0
  278. package/dist/types/containerd/options/image/ImageExportOptions.d.ts +25 -0
  279. package/dist/types/containerd/options/image/ImageImportOptions.d.ts +38 -0
  280. package/dist/types/containerd/options/image/ImagePullOptions.d.ts +53 -0
  281. package/dist/types/containerd/options/image/ImagePushOptions.d.ts +44 -0
  282. package/dist/types/containerd/options/network/NetworkCreateOptions.d.ts +82 -0
  283. package/dist/types/containerd/options/volume/VolumeCreateOptions.d.ts +26 -0
  284. package/dist/types/containerd/types/ContainerdBind.d.ts +28 -0
  285. package/dist/types/containerd/types/ContainerdBuildOutputCallback.d.ts +6 -0
  286. package/dist/types/containerd/types/ContainerdContainerNetwork.d.ts +40 -0
  287. package/dist/types/containerd/types/ContainerdContainerPort.d.ts +22 -0
  288. package/dist/types/containerd/types/ContainerdContainerState.d.ts +42 -0
  289. package/dist/types/containerd/types/ContainerdContainerStats.d.ts +107 -0
  290. package/dist/types/containerd/types/ContainerdDevice.d.ts +25 -0
  291. package/dist/types/containerd/types/ContainerdExecResult.d.ts +18 -0
  292. package/dist/types/containerd/types/ContainerdImageConfig.d.ts +46 -0
  293. package/dist/types/containerd/types/ContainerdNetworkInfo.d.ts +49 -0
  294. package/dist/types/containerd/types/ContainerdProgressCallback.d.ts +29 -0
  295. package/dist/types/containerd/types/ContainerdPruneResult.d.ts +21 -0
  296. package/dist/types/containerd/types/ContainerdRestartPolicy.d.ts +13 -0
  297. package/dist/types/containerd/types/ContainerdTmpfs.d.ts +20 -0
  298. package/dist/types/containerd/types/ContainerdVolume.d.ts +19 -0
  299. package/dist/types/containerd/types/ContainerdVolumeInfo.d.ts +26 -0
  300. package/dist/types/exports/Containerd.d.ts +69 -0
  301. package/package.json +51 -4
@@ -0,0 +1,1384 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ContainerStore = exports.ContainerLabels = void 0;
40
+ exports.resolvConf = resolvConf;
41
+ exports.seccompHint = seccompHint;
42
+ exports.signalNumber = signalNumber;
43
+ exports.isSwapLimitSupported = isSwapLimitSupported;
44
+ exports.swapLimit = swapLimit;
45
+ const node_crypto_1 = require("node:crypto");
46
+ const node_os_1 = require("node:os");
47
+ const promises_1 = require("node:fs/promises");
48
+ const node_fs_1 = require("node:fs");
49
+ const promises_2 = require("node:stream/promises");
50
+ const tar_stream_1 = require("tar-stream");
51
+ const node_path_1 = __importDefault(require("node:path"));
52
+ const node_stream_1 = require("node:stream");
53
+ const promises_3 = require("node:timers/promises");
54
+ const ContainerdClient_js_1 = require("./ContainerdClient.js");
55
+ const grpc_1 = require("@lakutata/grpc");
56
+ const M = __importStar(require("./Messages.js"));
57
+ const Platforms_js_1 = require("./Platforms.js");
58
+ const ImageStore_js_1 = require("./ImageStore.js");
59
+ const Fifo_js_1 = require("./Fifo.js");
60
+ const Volumes_js_1 = require("./Volumes.js");
61
+ const Networks_js_1 = require("./Networks.js");
62
+ const Rootfs_js_1 = require("./Rootfs.js");
63
+ const Spec_js_1 = require("./Spec.js");
64
+ const Seccomp_js_1 = require("./Seccomp.js");
65
+ /**
66
+ * The labels of the containers: the ones of nerdctl (nerdctl ps, nerdctl logs know them), the ones of the restart
67
+ * monitor of containerd
68
+ */
69
+ exports.ContainerLabels = {
70
+ NAME: 'nerdctl/name',
71
+ HOSTNAME: 'nerdctl/hostname',
72
+ PLATFORM: 'nerdctl/platform',
73
+ LOG_URI: 'nerdctl/log-uri',
74
+ STATE_DIR: 'nerdctl/state-dir',
75
+ NETWORKS: 'nerdctl/networks',
76
+ PORTS: 'nerdctl/ports',
77
+ MOUNTS: 'nerdctl/mounts',
78
+ STOP_SIGNAL: 'io.containerd.image.config.stop-signal',
79
+ RESTART_POLICY: 'containerd.io/restart.policy',
80
+ RESTART_STATUS: 'containerd.io/restart.status',
81
+ RESTART_LOG_URI: 'containerd.io/restart.loguri'
82
+ };
83
+ /**
84
+ * The resolv.conf of a container: the one of the host, without its local name servers on its own network (the ones of
85
+ * Google when it has no other one, as Docker does)
86
+ * @param content
87
+ * @param ownNetwork
88
+ */
89
+ function resolvConf(content, ownNetwork) {
90
+ if (!ownNetwork)
91
+ return content;
92
+ const lines = content.split('\n').filter((line) => !/^\s*nameserver\s+(127\.|::1\s*$)/.test(line));
93
+ while (lines.length && !lines[lines.length - 1].trim())
94
+ lines.pop();
95
+ if (!lines.some((line) => /^\s*nameserver\s+/.test(line)))
96
+ lines.push('nameserver 8.8.8.8', 'nameserver 8.8.4.4');
97
+ return lines.join('\n') + '\n';
98
+ }
99
+ /**
100
+ * An error of the runtime refusing the profile of seccomp of a container (a runc built without seccomp), with what to do
101
+ * @param error
102
+ */
103
+ function seccompHint(error) {
104
+ const message = error?.message ?? '';
105
+ if (!/seccomp/i.test(message) || !/not (supported|enabled)/i.test(message))
106
+ return error;
107
+ return Object.assign(error, { message: `${message} (the runtime of this machine does not filter the system calls with seccomp: create the container with the profile of seccomp unconfined)` });
108
+ }
109
+ /**
110
+ * The number of a signal (SIGTERM, TERM, 15)
111
+ * @param signal
112
+ */
113
+ function signalNumber(signal) {
114
+ if (typeof signal === 'number')
115
+ return signal;
116
+ if (/^\d+$/.test(signal))
117
+ return Number(signal);
118
+ const name = signal.toUpperCase().startsWith('SIG') ? signal.toUpperCase() : `SIG${signal.toUpperCase()}`;
119
+ const number = node_os_1.constants.signals[name];
120
+ if (number === undefined)
121
+ throw new Error(`The signal ${signal} is unknown`);
122
+ return number;
123
+ }
124
+ let swapLimitSupported;
125
+ /**
126
+ * Whether the kernel limits the swap of the cgroups (Docker discards the swap limits otherwise): the files of the swap
127
+ * limits, in the cgroups below the root on cgroup v2 (the root has none)
128
+ */
129
+ function isSwapLimitSupported() {
130
+ if (swapLimitSupported !== undefined)
131
+ return swapLimitSupported;
132
+ if ((0, node_fs_1.existsSync)('/sys/fs/cgroup/cgroup.controllers')) {
133
+ try {
134
+ swapLimitSupported = (0, node_fs_1.readdirSync)('/sys/fs/cgroup', { withFileTypes: true }).some((entry) => entry.isDirectory() && (0, node_fs_1.existsSync)(node_path_1.default.join('/sys/fs/cgroup', entry.name, 'memory.swap.max')));
135
+ }
136
+ catch {
137
+ swapLimitSupported = false;
138
+ }
139
+ }
140
+ else {
141
+ swapLimitSupported = (0, node_fs_1.existsSync)('/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes');
142
+ }
143
+ return swapLimitSupported;
144
+ }
145
+ /**
146
+ * The swap limit of a container (its memory and its swap together), as Docker and nerdctl give it: twice its memory
147
+ * limit by default, -1 unlimited; none without a memory limit, or when the kernel does not limit the swap
148
+ * @param memory
149
+ * @param memorySwap
150
+ */
151
+ function swapLimit(memory, memorySwap) {
152
+ if (!memory || !isSwapLimitSupported())
153
+ return undefined;
154
+ return memorySwap === -1 || (memorySwap && memorySwap > 0) ? memorySwap : memory * 2;
155
+ }
156
+ /**
157
+ * The CPUs of the machine online, as a cpuset writes them (0-3,6)
158
+ */
159
+ async function onlineCpuSet() {
160
+ return (await (0, promises_1.readFile)('/sys/devices/system/cpu/online', 'utf8').catch(() => '')).trim() || `0-${(0, node_os_1.availableParallelism)() - 1}`;
161
+ }
162
+ /**
163
+ * The counters of a metrics message as numbers: the 64-bit ones beyond 2^53 (an unlimited limit, 2^64 - 1) are decoded
164
+ * as bigints, the statistics are numbers
165
+ * @param value
166
+ */
167
+ function metricCounters(value) {
168
+ if (typeof value === 'bigint')
169
+ return Number(value);
170
+ if (Array.isArray(value))
171
+ return value.map(metricCounters);
172
+ if (value && typeof value === 'object' && !(value instanceof Uint8Array))
173
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, metricCounters(item)]));
174
+ return value;
175
+ }
176
+ /**
177
+ * The containers of containerd: created from the images (their specifications of OCI, their snapshots), their tasks
178
+ * started, stopped, executed in; their logs written by the shims of containerd (file://), kept by the restart monitor
179
+ * of containerd as their restart policies ask
180
+ */
181
+ class ContainerStore {
182
+ constructor(client, images, networks, options, volumes) {
183
+ this.client = client;
184
+ this.images = images;
185
+ this.networks = networks;
186
+ this.options = options;
187
+ this.volumes = volumes ?? new Volumes_js_1.VolumeStore(node_path_1.default.join(options.dataRoot, 'volumes', client.namespace));
188
+ }
189
+ /**
190
+ * The names of the volumes of a container
191
+ * @param container
192
+ */
193
+ static Volumes(container) {
194
+ try {
195
+ return JSON.parse(container.labels?.[exports.ContainerLabels.MOUNTS] ?? '[]')
196
+ .filter((mount) => mount.Type === 'volume' && !!mount.Name)
197
+ .map((mount) => mount.Name);
198
+ }
199
+ catch {
200
+ return [];
201
+ }
202
+ }
203
+ /**
204
+ * The networks of CNI of a container
205
+ * @param network
206
+ * @protected
207
+ */
208
+ async cniNetworks(network) {
209
+ if (!Array.isArray(network))
210
+ return [];
211
+ if (!network.length)
212
+ throw new Error('The networks of the container are empty');
213
+ const networks = [];
214
+ for (const item of network) {
215
+ if (item.name === 'host' || item.name === 'none')
216
+ throw new Error(`The network ${item.name} is not one of CNI: give it alone`);
217
+ const found = await this.networks.get(item.name);
218
+ if (!found)
219
+ throw Object.assign(new Error(`The network ${item.name} does not exist`), { code: 'NETWORK_NOT_FOUND' });
220
+ if (networks.some((known) => known.network.name === found.name))
221
+ throw new Error(`The network ${found.name} is given twice`);
222
+ networks.push({ network: found, ip: item.ip, ipv6: item.ipv6 });
223
+ }
224
+ return networks;
225
+ }
226
+ /**
227
+ * The profile of seccomp of a container, as nerdctl gives it: none for the privileged ones, unconfined ones and when
228
+ * the kernel does not filter the system calls; the default one by its capabilities; the one of a file
229
+ * @param options
230
+ * @protected
231
+ */
232
+ async seccomp(options) {
233
+ const profile = options.seccompProfile ?? 'default';
234
+ if (options.privileged || profile === 'unconfined')
235
+ return undefined;
236
+ if (profile !== 'default') {
237
+ try {
238
+ return JSON.parse(await (0, promises_1.readFile)(profile, 'utf8'));
239
+ }
240
+ catch (error) {
241
+ throw new Error(`The profile of seccomp ${profile} is not read: ${error.message}`, { cause: error });
242
+ }
243
+ }
244
+ if (!(0, Seccomp_js_1.seccompSupported)())
245
+ return undefined;
246
+ return (0, Seccomp_js_1.defaultSeccompProfile)((0, Spec_js_1.containerCapabilities)(options));
247
+ }
248
+ /**
249
+ * The interfaces of a container on its networks of CNI (their addresses while it runs)
250
+ * @param container
251
+ */
252
+ async interfaces(container) {
253
+ return await this.networks.interfaces(this.stateDir(container.id));
254
+ }
255
+ /**
256
+ * The directory of the state of a container
257
+ * @param id
258
+ */
259
+ stateDir(id) {
260
+ return node_path_1.default.join(this.options.dataRoot, 'containers', this.client.namespace, id);
261
+ }
262
+ /**
263
+ * The file of the logs of a container
264
+ * @param id
265
+ */
266
+ logFile(id) {
267
+ return node_path_1.default.join(this.stateDir(id), `${id}.log`);
268
+ }
269
+ /**
270
+ * The state written of a container
271
+ * @param id
272
+ */
273
+ async readState(id) {
274
+ try {
275
+ return JSON.parse(await (0, promises_1.readFile)(node_path_1.default.join(this.stateDir(id), 'state.json'), 'utf8'));
276
+ }
277
+ catch {
278
+ return {};
279
+ }
280
+ }
281
+ async writeState(id, state) {
282
+ await (0, promises_1.mkdir)(this.stateDir(id), { recursive: true });
283
+ await (0, promises_1.writeFile)(node_path_1.default.join(this.stateDir(id), 'state.json'), JSON.stringify({ ...await this.readState(id), ...state }));
284
+ }
285
+ /**
286
+ * The settings a container was created with by the component (its update creates it again with them)
287
+ * @param id
288
+ */
289
+ async readSettings(id) {
290
+ try {
291
+ return JSON.parse(await (0, promises_1.readFile)(node_path_1.default.join(this.stateDir(id), 'settings.json'), 'utf8'));
292
+ }
293
+ catch {
294
+ return undefined;
295
+ }
296
+ }
297
+ async writeSettings(id, settings) {
298
+ await (0, promises_1.mkdir)(this.stateDir(id), { recursive: true });
299
+ await (0, promises_1.writeFile)(node_path_1.default.join(this.stateDir(id), 'settings.json'), JSON.stringify(settings));
300
+ }
301
+ /**
302
+ * Name a container again (its label of nerdctl)
303
+ * @param container
304
+ * @param name
305
+ */
306
+ async rename(container, name) {
307
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(name))
308
+ throw new Error(`The name of a container "${name}" is not valid ([a-zA-Z0-9][a-zA-Z0-9_.-]*)`);
309
+ const used = await this.client.listContainers([`labels."${exports.ContainerLabels.NAME}"==${name}`]);
310
+ if (used.some((other) => other.id !== container.id))
311
+ throw Object.assign(new Error(`The name ${name} is used by another container`), { code: 'CONFLICT' });
312
+ await this.label(container, { [exports.ContainerLabels.NAME]: name });
313
+ }
314
+ /**
315
+ * Find a container: by its identifier, by its name, by a prefix of its identifier (only one)
316
+ * @param idOrName
317
+ */
318
+ async find(idOrName) {
319
+ const byId = await this.client.getContainer(idOrName);
320
+ if (byId)
321
+ return byId;
322
+ const byName = await this.client.listContainers([`labels."${exports.ContainerLabels.NAME}"==${idOrName}`]);
323
+ if (byName.length)
324
+ return byName[0];
325
+ if (!/^[0-9a-f]{3,}$/.test(idOrName))
326
+ return undefined;
327
+ const byPrefix = (await this.client.listContainers()).filter((container) => container.id.startsWith(idOrName));
328
+ if (byPrefix.length > 1)
329
+ throw new Error(`The prefix ${idOrName} names ${byPrefix.length} containers`);
330
+ return byPrefix[0];
331
+ }
332
+ /**
333
+ * The containers
334
+ * @param filters the filters of containerd (labels."app"==web)
335
+ */
336
+ async list(filters = []) {
337
+ return await this.client.listContainers(filters);
338
+ }
339
+ /**
340
+ * The devices of a host path (a device, or the ones of a directory)
341
+ * @param mapping
342
+ */
343
+ async devices(mapping) {
344
+ const stats = await (0, promises_1.stat)(mapping.hostPath, { bigint: true });
345
+ const containerPath = mapping.containerPath ?? mapping.hostPath;
346
+ if (stats.isDirectory()) {
347
+ const devices = [];
348
+ for (const entry of await (0, promises_1.readdir)(mapping.hostPath)) {
349
+ devices.push(...await this.devices({ hostPath: node_path_1.default.join(mapping.hostPath, entry), containerPath: node_path_1.default.posix.join(containerPath, entry), permissions: mapping.permissions }).catch(() => []));
350
+ }
351
+ return devices;
352
+ }
353
+ if (!stats.isCharacterDevice() && !stats.isBlockDevice())
354
+ throw new Error(`${mapping.hostPath} is not a device`);
355
+ return [ContainerStore.Device(mapping.hostPath, containerPath, stats, mapping.permissions ?? 'rwm')];
356
+ }
357
+ /**
358
+ * A device of the host, by the stats of its node (its major and minor numbers of its rdev, as glibc splits it)
359
+ * @param hostPath
360
+ * @param containerPath
361
+ * @param stats
362
+ * @param permissions
363
+ */
364
+ static Device(hostPath, containerPath, stats, permissions) {
365
+ const rdev = stats.rdev;
366
+ return {
367
+ path: hostPath,
368
+ containerPath: containerPath,
369
+ type: stats.isCharacterDevice() ? 'c' : 'b',
370
+ major: Number(((rdev >> 8n) & 0xfffn) | ((rdev >> 32n) & ~0xfffn)),
371
+ minor: Number((rdev & 0xffn) | ((rdev >> 12n) & ~0xffn)),
372
+ fileMode: Number(stats.mode & 511n),
373
+ uid: Number(stats.uid),
374
+ gid: Number(stats.gid),
375
+ permissions: permissions
376
+ };
377
+ }
378
+ /**
379
+ * The devices of the host given to a privileged container, as containerd's WithHostDevices gives them: the
380
+ * character and block devices of /dev and of its subdirectories, without the links, the console and the directories
381
+ * of the pseudo terminals, the shared memory, the descriptors and the queues
382
+ * @param directory
383
+ */
384
+ async hostDevices(directory = '/dev') {
385
+ const devices = [];
386
+ const entries = await (0, promises_1.readdir)(directory, { withFileTypes: true }).catch(() => []);
387
+ for (const entry of entries) {
388
+ const entryPath = node_path_1.default.join(directory, entry.name);
389
+ if (entry.isDirectory()) {
390
+ if (!['pts', 'shm', 'fd', 'mqueue', '.lxc', '.lxd-mounts', '.udev'].includes(entry.name))
391
+ devices.push(...await this.hostDevices(entryPath));
392
+ continue;
393
+ }
394
+ if (entry.name === 'console' || (!entry.isCharacterDevice() && !entry.isBlockDevice()))
395
+ continue;
396
+ //Removed meanwhile
397
+ const stats = await (0, promises_1.lstat)(entryPath, { bigint: true }).catch(() => undefined);
398
+ if (stats && (stats.isCharacterDevice() || stats.isBlockDevice()))
399
+ devices.push(ContainerStore.Device(entryPath, entryPath, stats, 'rwm'));
400
+ }
401
+ return devices;
402
+ }
403
+ /**
404
+ * The arguments of the process of a container: its entrypoint and its command, as Docker composes them
405
+ * @param resolved
406
+ * @param options
407
+ */
408
+ args(resolved, options) {
409
+ const config = resolved.config.config ?? {};
410
+ const entrypoint = options.entrypoint ?? config.Entrypoint ?? [];
411
+ //An entrypoint given resets the command of the image
412
+ const cmd = options.cmd ?? (options.entrypoint ? [] : config.Cmd ?? []);
413
+ const args = [...entrypoint.filter((part, index) => !(index === 0 && part === '' && entrypoint.length === 1)), ...cmd];
414
+ if (!args.length)
415
+ throw new Error(`The image ${resolved.name} has no command: give the command of the container`);
416
+ return args;
417
+ }
418
+ /**
419
+ * Create a container of an image: its snapshot (its root file system, the image unpacked), its specification, its
420
+ * state directory (its hosts, resolv.conf, hostname, logs)
421
+ * @param options
422
+ */
423
+ async create(options) {
424
+ const platform = options.platform ?? (0, Platforms_js_1.hostPlatform)();
425
+ const resolved = await this.images.resolve(options.image, platform);
426
+ const id = (0, node_crypto_1.randomBytes)(32).toString('hex');
427
+ const name = options.name ?? `${resolved.name.split('/').pop().split(/[:@]/)[0].replace(/[^a-zA-Z0-9_.-]/g, '')}-${id.slice(0, 5)}`;
428
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(name))
429
+ throw new Error(`The name of a container "${name}" is not valid ([a-zA-Z0-9][a-zA-Z0-9_.-]*)`);
430
+ if ((await this.client.listContainers([`labels."${exports.ContainerLabels.NAME}"==${name}`])).length)
431
+ throw Object.assign(new Error(`The name ${name} is used by another container`), { code: 'CONFLICT' });
432
+ const network = Array.isArray(options.network) ? 'cni' : options.network ?? 'host';
433
+ const cniNetworks = await this.cniNetworks(options.network);
434
+ const ports = options.ports ?? [];
435
+ if (ports.length && network !== 'cni')
436
+ throw new Error(`The ports of a container are published on its networks of CNI (${Networks_js_1.DEFAULT_NETWORK}), not on the network ${network}`);
437
+ const hostname = options.hostname ?? (network === 'host' ? (0, node_os_1.hostname)() : id.slice(0, 12));
438
+ const lease = await this.client.createLease();
439
+ const stateDir = this.stateDir(id);
440
+ try {
441
+ const chain = (0, ImageStore_js_1.chainIds)(resolved.config.rootfs?.diff_ids ?? []);
442
+ const parent = chain[chain.length - 1] ?? '';
443
+ if (parent && !(await this.client.statSnapshot(this.options.snapshotter, parent)))
444
+ await this.images.unpack(resolved.manifest, lease);
445
+ const mounts = await this.client.prepareSnapshot(this.options.snapshotter, id, parent, {}, lease);
446
+ const user = await (0, Rootfs_js_1.resolveUser)(mounts, options.user ?? resolved.config.config?.User);
447
+ //The environment: the one of the image, PATH, HOSTNAME, HOME, the one given
448
+ const env = new Map([['PATH', '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin']]);
449
+ for (const entry of resolved.config.config?.Env ?? [])
450
+ env.set(entry.split('=')[0], entry.slice(entry.indexOf('=') + 1));
451
+ env.set('HOSTNAME', hostname);
452
+ if (!env.has('HOME'))
453
+ env.set('HOME', user.home);
454
+ for (const [key, value] of Object.entries(options.env ?? {}))
455
+ env.set(key, value);
456
+ if (options.terminal && !env.has('TERM'))
457
+ env.set('TERM', 'xterm');
458
+ //The files of the network of the container
459
+ await (0, promises_1.mkdir)(stateDir, { recursive: true });
460
+ const hostHosts = network === 'host' ? await (0, promises_1.readFile)('/etc/hosts', 'utf8').catch(() => '') : '';
461
+ const hosts = [hostHosts.trimEnd() || '127.0.0.1\tlocalhost localhost.localdomain\n::1\tlocalhost localhost.localdomain ip6-localhost ip6-loopback'];
462
+ if (network === 'none')
463
+ hosts.push(`127.0.0.1\t${hostname}`);
464
+ for (const [host, address] of Object.entries(options.extraHosts ?? {}))
465
+ hosts.push(`${address}\t${host}`);
466
+ //The hosts of the networks of CNI: the address of the container added by its hook
467
+ await (0, promises_1.writeFile)(node_path_1.default.join(stateDir, 'hosts.base'), hosts.join('\n') + '\n');
468
+ await (0, promises_1.writeFile)(node_path_1.default.join(stateDir, 'hosts'), hosts.join('\n') + '\n');
469
+ await (0, promises_1.writeFile)(node_path_1.default.join(stateDir, 'resolv.conf'), options.dns?.length ? options.dns.map((server) => `nameserver ${server}`).join('\n') + '\n' : resolvConf(await (0, promises_1.readFile)('/etc/resolv.conf', 'utf8').catch(() => ''), network !== 'host'));
470
+ await (0, promises_1.writeFile)(node_path_1.default.join(stateDir, 'hostname'), hostname + '\n');
471
+ await (0, promises_1.writeFile)(this.logFile(id), '');
472
+ const specMounts = [
473
+ { source: node_path_1.default.join(stateDir, 'hosts'), destination: '/etc/hosts', options: ['bind', 'rprivate'] },
474
+ { source: node_path_1.default.join(stateDir, 'resolv.conf'), destination: '/etc/resolv.conf', options: ['bind', 'rprivate'] },
475
+ { source: node_path_1.default.join(stateDir, 'hostname'), destination: '/etc/hostname', options: ['bind', 'rprivate'] }
476
+ ];
477
+ for (const mount of options.mounts ?? []) {
478
+ if (mount.type === 'tmpfs') {
479
+ specMounts.push({ type: 'tmpfs', source: 'tmpfs', destination: mount.target, options: ['nosuid', 'nodev', 'noexec', ...mount.options ?? [], ...mount.readonly ? ['ro'] : []] });
480
+ }
481
+ else if (mount.type === 'volume') {
482
+ if (!mount.source)
483
+ throw new Error(`The volume mounted on ${mount.target} has no name`);
484
+ const volume = await this.volumes.create(mount.source);
485
+ specMounts.push({ type: 'bind', source: volume.mountpoint, destination: mount.target, options: ['rbind', 'rprivate', mount.readonly ? 'ro' : 'rw'] });
486
+ }
487
+ else {
488
+ if (!mount.source)
489
+ throw new Error(`The bind mount of ${mount.target} has no source`);
490
+ const source = node_path_1.default.resolve(mount.source);
491
+ await (0, promises_1.mkdir)(source, { recursive: true }).catch(() => undefined);
492
+ specMounts.push({ type: 'bind', source: source, destination: mount.target, options: ['rbind', ...mount.options?.length ? mount.options : ['rprivate'], mount.readonly ? 'ro' : 'rw'] });
493
+ }
494
+ }
495
+ const devices = [];
496
+ for (const device of options.devices ?? [])
497
+ devices.push(...await this.devices(device));
498
+ //The devices of the host in its /dev (its cgroup allows them all), the ones given kept
499
+ if (options.privileged)
500
+ devices.push(...(await this.hostDevices()).filter((device) => !devices.some((given) => given.containerPath === device.containerPath)));
501
+ let hooks;
502
+ if (network === 'cni') {
503
+ if (!this.networks.pluginDirectories().length)
504
+ throw new Error(`The plugins of CNI are not installed (${this.networks.cniPath.join(', ')}): install them (the package containernetworking-plugins, or the CNI plugins release in /opt/cni/bin), or give the container the network 'host'`);
505
+ await this.networks.render(stateDir, id, cniNetworks, ports);
506
+ const hook = node_path_1.default.join(stateDir, 'network', 'hook.sh');
507
+ hooks = {
508
+ createRuntime: [{ path: '/bin/sh', args: ['sh', hook, 'add', stateDir], timeout: 120 }],
509
+ poststop: [{ path: '/bin/sh', args: ['sh', hook, 'del', stateDir], timeout: 120 }]
510
+ };
511
+ }
512
+ const spec = (0, Spec_js_1.generateSpec)({
513
+ id: id,
514
+ namespace: this.client.namespace,
515
+ args: this.args(resolved, options),
516
+ env: [...env].map(([key, value]) => `${key}=${value}`),
517
+ cwd: options.workingDir ?? resolved.config.config?.WorkingDir ?? '/',
518
+ uid: user.uid,
519
+ gid: user.gid,
520
+ additionalGids: user.additionalGids,
521
+ hostname: hostname,
522
+ terminal: options.terminal,
523
+ privileged: options.privileged,
524
+ readonlyRootfs: options.readonlyRootfs,
525
+ capAdd: options.capAdd,
526
+ capDrop: options.capDrop,
527
+ seccomp: await this.seccomp(options),
528
+ mounts: specMounts,
529
+ devices: devices,
530
+ deviceCgroupRules: (options.deviceCgroupRules ?? []).map(Spec_js_1.parseDeviceCgroupRule),
531
+ network: { mode: network },
532
+ hooks: hooks,
533
+ pidHost: options.pidHost,
534
+ ipcHost: options.ipcHost,
535
+ cgroupNamespace: (options.cgroupns ?? 'private') === 'private' && (0, node_fs_1.existsSync)('/sys/fs/cgroup/cgroup.controllers'),
536
+ cgroupsPath: this.options.cgroupManager === 'systemd' ? `system.slice:lakutata:${id}` : `/${this.client.namespace}/${id}`,
537
+ memory: options.memory,
538
+ memorySwap: swapLimit(options.memory, options.memorySwap),
539
+ cpuQuota: options.cpus ? Math.round(options.cpus * 100000) : undefined,
540
+ cpuShares: options.cpuShares,
541
+ cpuset: options.cpuset,
542
+ pidsLimit: options.pidsLimit,
543
+ oomKillDisable: options.oomKillDisable,
544
+ sysctls: options.sysctls,
545
+ shmSize: options.shmSize
546
+ });
547
+ const logUri = `file://${this.logFile(id)}`;
548
+ const labels = {
549
+ ...resolved.config.config?.Labels ?? {},
550
+ ...options.labels ?? {},
551
+ [exports.ContainerLabels.NAME]: name,
552
+ [exports.ContainerLabels.HOSTNAME]: hostname,
553
+ [exports.ContainerLabels.PLATFORM]: (0, Platforms_js_1.formatPlatform)(resolved.platform),
554
+ [exports.ContainerLabels.LOG_URI]: logUri,
555
+ [exports.ContainerLabels.STATE_DIR]: stateDir,
556
+ [exports.ContainerLabels.NETWORKS]: JSON.stringify(network === 'cni' ? cniNetworks.map((item) => item.network.name) : [network]),
557
+ [exports.ContainerLabels.PORTS]: JSON.stringify(ports.map((port) => ({ HostPort: port.hostPort, ContainerPort: port.containerPort, Protocol: port.protocol, HostIP: port.hostIP || '0.0.0.0' }))),
558
+ [exports.ContainerLabels.MOUNTS]: JSON.stringify((options.mounts ?? []).map((mount) => mount.type === 'volume'
559
+ ? { Type: 'volume', Name: mount.source, Source: node_path_1.default.join(this.volumes.directory, mount.source, '_data'), Destination: mount.target, RW: !mount.readonly }
560
+ : { Type: mount.type ?? 'bind', Source: mount.source ?? '', Destination: mount.target, RW: !mount.readonly }))
561
+ };
562
+ const stopSignal = options.stopSignal ?? resolved.config.config?.StopSignal;
563
+ if (stopSignal)
564
+ labels[exports.ContainerLabels.STOP_SIGNAL] = stopSignal;
565
+ if (options.restart && options.restart !== 'no') {
566
+ labels[exports.ContainerLabels.RESTART_POLICY] = options.restart;
567
+ labels[exports.ContainerLabels.RESTART_LOG_URI] = logUri;
568
+ labels[exports.ContainerLabels.RESTART_STATUS] = 'stopped';
569
+ }
570
+ const runtime = { name: this.options.runtime };
571
+ if (this.options.cgroupManager === 'systemd')
572
+ runtime.options = { typeUrl: 'containerd.runc.v1.Options', value: (0, grpc_1.encode)(M.RuncOptions, { systemdCgroup: true }) };
573
+ return await this.client.createContainer({
574
+ id: id,
575
+ labels: labels,
576
+ image: resolved.name,
577
+ runtime: runtime,
578
+ spec: ContainerdClient_js_1.ContainerdClient.Json(ContainerdClient_js_1.SPEC_TYPE_URL, spec),
579
+ snapshotter: this.options.snapshotter,
580
+ snapshotKey: id
581
+ }, lease);
582
+ }
583
+ catch (error) {
584
+ await this.client.removeSnapshot(this.options.snapshotter, id).catch(() => undefined);
585
+ await (0, promises_1.rm)(stateDir, { recursive: true, force: true });
586
+ throw error;
587
+ }
588
+ finally {
589
+ await this.client.deleteLease(lease);
590
+ }
591
+ }
592
+ /**
593
+ * The state of a container: the one of its task, its last exit when it has none
594
+ * @param container
595
+ */
596
+ async state(container) {
597
+ const stored = await this.readState(container.id);
598
+ const task = await this.client.getTask(container.id);
599
+ const restarting = container.labels?.[exports.ContainerLabels.RESTART_STATUS] === 'running';
600
+ const state = {
601
+ status: 'created',
602
+ running: false,
603
+ paused: false,
604
+ pid: 0,
605
+ exitCode: stored.exitCode ?? 0,
606
+ startedAt: stored.startedAt ? new Date(stored.startedAt) : null,
607
+ finishedAt: stored.finishedAt ? new Date(stored.finishedAt) : null
608
+ };
609
+ if (!task) {
610
+ state.status = stored.startedAt ? 'exited' : 'created';
611
+ //Its restart monitor recreates its task
612
+ if (restarting && stored.startedAt)
613
+ state.status = 'restarting';
614
+ return state;
615
+ }
616
+ state.pid = task.pid ?? 0;
617
+ switch (task.status) {
618
+ case M.ProcessStatus.RUNNING:
619
+ state.status = 'running';
620
+ state.running = true;
621
+ break;
622
+ case M.ProcessStatus.PAUSED:
623
+ state.status = 'paused';
624
+ state.paused = true;
625
+ break;
626
+ case M.ProcessStatus.PAUSING:
627
+ state.status = 'pausing';
628
+ break;
629
+ case M.ProcessStatus.STOPPED:
630
+ state.status = restarting ? 'restarting' : 'exited';
631
+ state.exitCode = task.exitStatus ?? 0;
632
+ state.finishedAt = (0, ContainerdClient_js_1.timestampDate)(task.exitedAt) ?? state.finishedAt;
633
+ break;
634
+ case M.ProcessStatus.CREATED:
635
+ state.status = 'created';
636
+ break;
637
+ default:
638
+ state.status = 'unknown';
639
+ }
640
+ return state;
641
+ }
642
+ /**
643
+ * Rotate the logs of a container once they are larger than the size of the options: copied to the file .1, the
644
+ * file truncated (the shim writes to its end)
645
+ * @param id
646
+ */
647
+ async rotateLogs(id) {
648
+ if (!this.options.logMaxSize)
649
+ return;
650
+ const file = this.logFile(id);
651
+ const size = (await (0, promises_1.stat)(file).catch(() => undefined))?.size ?? 0;
652
+ if (size <= this.options.logMaxSize)
653
+ return;
654
+ await (0, promises_1.copyFile)(file, `${file}.1`);
655
+ await (0, promises_1.truncate)(file, 0);
656
+ }
657
+ /**
658
+ * Delete the task of a container (stopped), its exit kept
659
+ * @param id
660
+ */
661
+ async deleteTask(id) {
662
+ const deleted = await this.client.deleteTask(id).catch(async (error) => {
663
+ //A task still running (a stop of its restart monitor meanwhile): killed
664
+ if (!(0, ContainerdClient_js_1.isGRPCError)(error, grpc_1.GRPCStatus.FAILED_PRECONDITION))
665
+ throw error;
666
+ await this.client.kill(id, signalNumber('SIGKILL'), { all: true }).catch(() => undefined);
667
+ await this.client.wait(id).catch(() => undefined);
668
+ return await this.client.deleteTask(id);
669
+ });
670
+ if (deleted)
671
+ await this.writeState(id, { exitCode: deleted.exitStatus ?? 0, finishedAt: ((0, ContainerdClient_js_1.timestampDate)(deleted.exitedAt) ?? new Date()).toISOString() });
672
+ }
673
+ /**
674
+ * Set the labels of a container
675
+ * @param container
676
+ * @param labels
677
+ */
678
+ async label(container, labels) {
679
+ await this.client.updateContainer({ id: container.id, labels: labels }, Object.keys(labels).map((key) => `labels.${key}`));
680
+ }
681
+ /**
682
+ * Start a container: a new task of its snapshot (the one of its previous run deleted), its output written to its
683
+ * logs
684
+ * @param container
685
+ */
686
+ async start(container) {
687
+ const task = await this.client.getTask(container.id);
688
+ if (task?.status === M.ProcessStatus.RUNNING)
689
+ return task.pid;
690
+ if (task?.status === M.ProcessStatus.PAUSED)
691
+ throw Object.assign(new Error(`The container ${container.id} is paused: resume it`), { code: 'PAUSED' });
692
+ if (task)
693
+ await this.deleteTask(container.id);
694
+ await this.rotateLogs(container.id);
695
+ const logUri = container.labels?.[exports.ContainerLabels.LOG_URI] ?? `file://${this.logFile(container.id)}`;
696
+ await (0, promises_1.mkdir)(node_path_1.default.dirname(this.logFile(container.id)), { recursive: true });
697
+ const rootfs = await this.client.snapshotMounts(container.snapshotter || this.options.snapshotter, container.snapshotKey || container.id);
698
+ await this.client.createTask({ containerId: container.id, rootfs: rootfs, stdout: logUri, stderr: logUri }).catch((error) => {
699
+ throw seccompHint(error);
700
+ });
701
+ try {
702
+ const pid = await this.client.startTask(container.id).catch((error) => {
703
+ throw seccompHint(error);
704
+ });
705
+ await this.writeState(container.id, { startedAt: new Date().toISOString(), finishedAt: undefined, exitCode: undefined });
706
+ if (container.labels?.[exports.ContainerLabels.RESTART_POLICY])
707
+ await this.label(container, { [exports.ContainerLabels.RESTART_STATUS]: 'running' });
708
+ return pid;
709
+ }
710
+ catch (error) {
711
+ await this.client.deleteTask(container.id).catch(() => undefined);
712
+ throw error;
713
+ }
714
+ }
715
+ /**
716
+ * Wait for the task of a container to exit, at most a time
717
+ * @param id
718
+ * @param timeout milliseconds
719
+ */
720
+ async waitExit(id, timeout) {
721
+ const abort = new AbortController();
722
+ const timer = setTimeout(() => abort.abort(), timeout);
723
+ try {
724
+ await this.client.wait(id, '', abort.signal);
725
+ return true;
726
+ }
727
+ catch (error) {
728
+ if (abort.signal.aborted)
729
+ return false;
730
+ if ((0, ContainerdClient_js_1.isGRPCError)(error, grpc_1.GRPCStatus.NOT_FOUND))
731
+ return true;
732
+ throw error;
733
+ }
734
+ finally {
735
+ clearTimeout(timer);
736
+ }
737
+ }
738
+ /**
739
+ * Stop a container: its stop signal (SIGTERM, the one of its image) sent, then SIGKILL to all its processes after a
740
+ * time; its task deleted, its restart monitor told not to restart it
741
+ * @param container
742
+ * @param options
743
+ */
744
+ async stop(container, options = {}) {
745
+ if (container.labels?.[exports.ContainerLabels.RESTART_POLICY])
746
+ await this.label(container, { [exports.ContainerLabels.RESTART_STATUS]: 'stopped' });
747
+ const task = await this.client.getTask(container.id);
748
+ if (!task)
749
+ return;
750
+ if (task.status === M.ProcessStatus.PAUSED)
751
+ await this.client.resume(container.id);
752
+ if (task.status === M.ProcessStatus.RUNNING || task.status === M.ProcessStatus.PAUSED) {
753
+ const signal = signalNumber(options.signal ?? container.labels?.[exports.ContainerLabels.STOP_SIGNAL] ?? 'SIGTERM');
754
+ await this.client.kill(container.id, signal).catch((error) => {
755
+ if (!(0, ContainerdClient_js_1.isGRPCError)(error, grpc_1.GRPCStatus.NOT_FOUND))
756
+ throw error;
757
+ });
758
+ if (!(await this.waitExit(container.id, (options.timeout ?? 10) * 1000))) {
759
+ await this.client.kill(container.id, signalNumber('SIGKILL'), { all: true }).catch(() => undefined);
760
+ await this.waitExit(container.id, 10000);
761
+ }
762
+ }
763
+ await this.deleteTask(container.id);
764
+ }
765
+ /**
766
+ * Send a signal to a container (its main process, or all its processes)
767
+ * @param container
768
+ * @param signal
769
+ * @param all
770
+ */
771
+ async kill(container, signal = 'SIGKILL', all = false) {
772
+ if (signalNumber(signal) === signalNumber('SIGKILL') && container.labels?.[exports.ContainerLabels.RESTART_POLICY])
773
+ await this.label(container, { [exports.ContainerLabels.RESTART_STATUS]: 'stopped' });
774
+ await this.client.kill(container.id, signalNumber(signal), { all: all }).catch((error) => {
775
+ throw this.taskError(container, error);
776
+ });
777
+ }
778
+ async pause(container) {
779
+ await this.running(container);
780
+ await this.client.pause(container.id).catch((error) => {
781
+ throw this.taskError(container, error);
782
+ });
783
+ }
784
+ async resume(container) {
785
+ await this.running(container);
786
+ await this.client.resume(container.id).catch((error) => {
787
+ throw this.taskError(container, error);
788
+ });
789
+ }
790
+ /**
791
+ * Check that a container has a task which did not exit (the shim refuses to pause or resume a stopped one with an
792
+ * error of no code)
793
+ * @param container
794
+ * @protected
795
+ */
796
+ async running(container) {
797
+ const task = await this.client.getTask(container.id);
798
+ if (!task || task.status === M.ProcessStatus.STOPPED)
799
+ throw Object.assign(new Error(`The container ${ContainerStore.Name(container)} is not running`), { code: 'NOT_RUNNING' });
800
+ }
801
+ /**
802
+ * The processes of a running container (their identifiers on the host)
803
+ * @param container
804
+ */
805
+ async processes(container) {
806
+ return await this.client.listPids(container.id).catch((error) => {
807
+ throw this.taskError(container, error);
808
+ });
809
+ }
810
+ /**
811
+ * Wait for the main process of a container to exit: its exit code; the last one at once when it has no task (never
812
+ * started: 0, stopped: its task deleted, its exit kept by the store)
813
+ * @param container
814
+ * @param signal
815
+ */
816
+ async wait(container, signal) {
817
+ try {
818
+ return (await this.client.wait(container.id, '', signal)).exitStatus;
819
+ }
820
+ catch (error) {
821
+ if (!(0, ContainerdClient_js_1.isGRPCError)(error, grpc_1.GRPCStatus.NOT_FOUND))
822
+ throw error;
823
+ return (await this.readState(container.id)).exitCode ?? 0;
824
+ }
825
+ }
826
+ /**
827
+ * The error of an operation on the task of a container: the container is not running when it has no task (or its
828
+ * process exited)
829
+ * @param container
830
+ * @param error
831
+ * @protected
832
+ */
833
+ taskError(container, error) {
834
+ if (!(0, ContainerdClient_js_1.isGRPCError)(error, grpc_1.GRPCStatus.NOT_FOUND))
835
+ return error;
836
+ return Object.assign(new Error(`The container ${ContainerStore.Name(container)} is not running (${error.message})`, { cause: error }), { code: 'NOT_RUNNING' });
837
+ }
838
+ /**
839
+ * Remove a container: its task (a running one only when forced), its snapshot, its state directory
840
+ * @param container
841
+ * @param force
842
+ */
843
+ async remove(container, force = false) {
844
+ const task = await this.client.getTask(container.id);
845
+ if (task && task.status !== M.ProcessStatus.STOPPED && task.status !== M.ProcessStatus.CREATED) {
846
+ if (!force)
847
+ throw Object.assign(new Error(`The container ${ContainerStore.Name(container)} is running: stop it or remove it by force`), { code: 'RUNNING' });
848
+ if (container.labels?.[exports.ContainerLabels.RESTART_POLICY])
849
+ await this.label(container, { [exports.ContainerLabels.RESTART_STATUS]: 'stopped' });
850
+ if (task.status === M.ProcessStatus.PAUSED)
851
+ await this.client.resume(container.id).catch(() => undefined);
852
+ await this.client.kill(container.id, signalNumber('SIGKILL'), { all: true }).catch(() => undefined);
853
+ await this.waitExit(container.id, 10000);
854
+ }
855
+ if (task)
856
+ await this.client.deleteTask(container.id).catch(() => undefined);
857
+ //The networks its hook did not delete
858
+ await this.networks.teardown(this.stateDir(container.id));
859
+ await this.client.deleteContainer(container.id);
860
+ await this.client.removeSnapshot(container.snapshotter || this.options.snapshotter, container.snapshotKey || container.id);
861
+ await (0, promises_1.rm)(this.stateDir(container.id), { recursive: true, force: true });
862
+ }
863
+ /**
864
+ * Execute a command in a running container, its output captured: its standard output and its error apart (FIFOs,
865
+ * mkfifo of the system), or together in its standard output without mkfifo (the files of the shim)
866
+ * @param container
867
+ * @param options
868
+ */
869
+ async exec(container, options) {
870
+ const task = await this.client.getTask(container.id);
871
+ if (task?.status !== M.ProcessStatus.RUNNING)
872
+ throw Object.assign(new Error(`The container ${ContainerStore.Name(container)} is not running`), { code: 'NOT_RUNNING' });
873
+ const spec = ContainerdClient_js_1.ContainerdClient.FromJson(container.spec) ?? {};
874
+ let user;
875
+ if (options.user)
876
+ user = await (0, Rootfs_js_1.resolveUser)(await this.client.snapshotMounts(container.snapshotter || this.options.snapshotter, container.snapshotKey || container.id), options.user);
877
+ const process = (0, Spec_js_1.execProcessSpec)(spec, {
878
+ args: options.cmd,
879
+ env: Object.entries(options.env ?? {}).map(([key, value]) => `${key}=${value}`),
880
+ cwd: options.workingDir,
881
+ uid: user?.uid,
882
+ gid: user?.gid,
883
+ additionalGids: user?.additionalGids
884
+ });
885
+ const execId = `exec-${(0, node_crypto_1.randomBytes)(8).toString('hex')}`;
886
+ const directory = node_path_1.default.join(this.stateDir(container.id), 'exec');
887
+ await (0, promises_1.mkdir)(directory, { recursive: true });
888
+ const files = [];
889
+ const fifos = [];
890
+ const fifo = Fifo_js_1.ProcessFifo.Supported();
891
+ if (!fifo && options.stdin !== undefined)
892
+ throw new Error('The standard input of an execution needs mkfifo');
893
+ try {
894
+ let stdout, stderr, stdin;
895
+ let request;
896
+ if (fifo) {
897
+ stdout = Fifo_js_1.ProcessFifo.Create(node_path_1.default.join(directory, `${execId}-stdout`), 'read');
898
+ stderr = Fifo_js_1.ProcessFifo.Create(node_path_1.default.join(directory, `${execId}-stderr`), 'read');
899
+ fifos.push(stdout, stderr);
900
+ if (options.stdin !== undefined)
901
+ fifos.push(stdin = Fifo_js_1.ProcessFifo.Create(node_path_1.default.join(directory, `${execId}-stdin`), 'write'));
902
+ request = { stdout: stdout.path, stderr: stderr.path, stdin: stdin?.path ?? '' };
903
+ }
904
+ else {
905
+ const output = node_path_1.default.join(directory, `${execId}.log`);
906
+ files.push(output);
907
+ await (0, promises_1.writeFile)(output, '');
908
+ request = { stdout: `file://${output}`, stderr: `file://${output}` };
909
+ }
910
+ files.push(...fifos.map((item) => item.path));
911
+ await this.client.exec({ containerId: container.id, execId: execId, ...request, spec: ContainerdClient_js_1.ContainerdClient.Json(ContainerdClient_js_1.PROCESS_TYPE_URL, process) });
912
+ const waiting = this.client.wait(container.id, execId);
913
+ waiting.catch(() => undefined);
914
+ await this.client.startTask(container.id, execId);
915
+ const read = (item) => {
916
+ if (!item)
917
+ return Promise.resolve('');
918
+ const socket = item.open();
919
+ const chunks = [];
920
+ return new Promise((resolve) => {
921
+ socket.on('data', (chunk) => chunks.push(chunk));
922
+ socket.on('error', () => resolve(Buffer.concat(chunks).toString('utf8')));
923
+ socket.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
924
+ });
925
+ };
926
+ const outputs = Promise.all([read(stdout), read(stderr)]);
927
+ if (stdin) {
928
+ //Written and closed, then the writer of the shim closed (CloseIO): the end of the input once read
929
+ const writer = stdin.open();
930
+ await new Promise((resolve) => void writer.end(options.stdin ?? '', () => resolve()));
931
+ await this.client.closeIO(container.id, execId).catch(() => undefined);
932
+ }
933
+ const timer = options.timeout ? setTimeout(() => {
934
+ this.client.kill(container.id, signalNumber('SIGKILL'), { execId: execId }).catch(() => undefined);
935
+ }, options.timeout) : undefined;
936
+ try {
937
+ const { exitStatus } = await waiting;
938
+ if (!fifo)
939
+ return { exitCode: exitStatus, stdout: await (0, promises_1.readFile)(files[0], 'utf8'), stderr: '' };
940
+ const [out, err] = await outputs;
941
+ return { exitCode: exitStatus, stdout: out, stderr: err };
942
+ }
943
+ finally {
944
+ clearTimeout(timer);
945
+ }
946
+ }
947
+ finally {
948
+ fifos.forEach((item) => item.close());
949
+ await this.client.deleteProcess(container.id, execId).catch(() => undefined);
950
+ for (const file of files)
951
+ await (0, promises_1.rm)(file, { force: true });
952
+ }
953
+ }
954
+ /**
955
+ * The logs of a container: its last lines, followed while it runs (until the signal aborts)
956
+ * @param container
957
+ * @param options
958
+ */
959
+ logs(container, options = {}) {
960
+ const file = this.logFile(container.id);
961
+ const store = this;
962
+ return node_stream_1.Readable.from((async function* () {
963
+ let content = Buffer.concat([await (0, promises_1.readFile)(`${file}.1`).catch(() => Buffer.alloc(0)), await (0, promises_1.readFile)(file).catch(() => Buffer.alloc(0))]);
964
+ let offset = (await (0, promises_1.stat)(file).catch(() => undefined))?.size ?? 0;
965
+ if (options.tail !== undefined && options.tail >= 0) {
966
+ let end = content.length;
967
+ if (content[end - 1] === 0x0a)
968
+ end--;
969
+ let start = end;
970
+ for (let lines = 0; start > 0; start--) {
971
+ if (content[start - 1] === 0x0a && ++lines >= options.tail)
972
+ break;
973
+ }
974
+ content = options.tail === 0 ? Buffer.alloc(0) : content.subarray(start);
975
+ }
976
+ if (content.length)
977
+ yield content;
978
+ if (!options.follow)
979
+ return;
980
+ let idle = 0;
981
+ while (!options.signal?.aborted) {
982
+ const size = (await (0, promises_1.stat)(file).catch(() => undefined))?.size ?? 0;
983
+ //Rotated: read from its start
984
+ if (size < offset)
985
+ offset = 0;
986
+ if (size > offset) {
987
+ const handle = await (0, promises_1.open)(file, 'r');
988
+ try {
989
+ const buffer = Buffer.alloc(size - offset);
990
+ await handle.read(buffer, 0, buffer.length, offset);
991
+ offset = size;
992
+ yield buffer;
993
+ }
994
+ finally {
995
+ await handle.close();
996
+ }
997
+ continue;
998
+ }
999
+ //Every second, whether it still runs
1000
+ if (++idle % 4 === 0) {
1001
+ const task = await store.client.getTask(container.id);
1002
+ //Stopped, and not restarted by its restart monitor
1003
+ if ((!task || task.status === M.ProcessStatus.STOPPED) && (await store.client.getContainer(container.id))?.labels?.[exports.ContainerLabels.RESTART_STATUS] !== 'running')
1004
+ break;
1005
+ }
1006
+ await (0, promises_3.setTimeout)(250, undefined, { signal: options.signal }).catch(() => undefined);
1007
+ }
1008
+ })());
1009
+ }
1010
+ /**
1011
+ * A sample of the resources a running container uses
1012
+ * @param container
1013
+ * @protected
1014
+ */
1015
+ async sample(container) {
1016
+ const task = await this.client.getTask(container.id);
1017
+ if (task?.status !== M.ProcessStatus.RUNNING && task?.status !== M.ProcessStatus.PAUSED)
1018
+ throw Object.assign(new Error(`The container ${ContainerStore.Name(container)} is not running`), { code: 'NOT_RUNNING' });
1019
+ const metric = await this.client.metrics(container.id);
1020
+ const type = String(metric?.data?.typeUrl ?? '');
1021
+ const data = metric?.data?.value ?? new Uint8Array();
1022
+ const unlimited = (value) => !value || value >= 2 ** 62 ? (0, node_os_1.totalmem)() : value;
1023
+ const onlineCpus = (0, node_os_1.availableParallelism)();
1024
+ const stats = {
1025
+ read: (0, ContainerdClient_js_1.timestampDate)(metric?.timestamp) ?? new Date(),
1026
+ pids: { current: 0, limit: 0 },
1027
+ cpu: { usage: 0, user: 0, system: 0, throttledPeriods: 0, throttledTime: 0, onlineCpus: onlineCpus },
1028
+ memory: { usage: 0, workingSet: 0, limit: (0, node_os_1.totalmem)(), cache: 0, swap: 0, oomKills: 0 },
1029
+ blkio: { readBytes: 0, writeBytes: 0, readOps: 0, writeOps: 0 },
1030
+ networks: {}
1031
+ };
1032
+ if (type.endsWith('cgroups.v2.Metrics')) {
1033
+ const metrics = metricCounters((0, grpc_1.decode)(M.CgroupV2Metrics, data));
1034
+ stats.pids = { current: metrics.pids?.current ?? 0, limit: metrics.pids?.limit ?? 0 };
1035
+ stats.cpu = {
1036
+ usage: (metrics.cpu?.usageUsec ?? 0) * 1000,
1037
+ user: (metrics.cpu?.userUsec ?? 0) * 1000,
1038
+ system: (metrics.cpu?.systemUsec ?? 0) * 1000,
1039
+ throttledPeriods: metrics.cpu?.nrThrottled ?? 0,
1040
+ throttledTime: (metrics.cpu?.throttledUsec ?? 0) * 1000,
1041
+ onlineCpus: onlineCpus
1042
+ };
1043
+ const usage = metrics.memory?.usage ?? 0;
1044
+ stats.memory = {
1045
+ usage: usage,
1046
+ workingSet: Math.max(0, usage - (metrics.memory?.inactiveFile ?? 0)),
1047
+ limit: unlimited(metrics.memory?.usageLimit ?? 0),
1048
+ cache: metrics.memory?.file ?? 0,
1049
+ swap: metrics.memory?.swapUsage ?? 0,
1050
+ oomKills: metrics.memoryEvents?.oomKill ?? 0
1051
+ };
1052
+ for (const entry of metrics.io?.usage ?? []) {
1053
+ stats.blkio.readBytes += entry.rbytes ?? 0;
1054
+ stats.blkio.writeBytes += entry.wbytes ?? 0;
1055
+ stats.blkio.readOps += entry.rios ?? 0;
1056
+ stats.blkio.writeOps += entry.wios ?? 0;
1057
+ }
1058
+ }
1059
+ else if (type.endsWith('cgroups.v1.Metrics')) {
1060
+ const metrics = metricCounters((0, grpc_1.decode)(M.CgroupV1Metrics, data));
1061
+ stats.pids = { current: metrics.pids?.current ?? 0, limit: metrics.pids?.limit ?? 0 };
1062
+ stats.cpu = {
1063
+ usage: metrics.cpu?.usage?.total ?? 0,
1064
+ user: metrics.cpu?.usage?.user ?? 0,
1065
+ system: metrics.cpu?.usage?.kernel ?? 0,
1066
+ throttledPeriods: metrics.cpu?.throttling?.throttledPeriods ?? 0,
1067
+ throttledTime: metrics.cpu?.throttling?.throttledTime ?? 0,
1068
+ onlineCpus: metrics.cpu?.usage?.perCpu?.length || onlineCpus
1069
+ };
1070
+ const usage = metrics.memory?.usage?.usage ?? 0;
1071
+ stats.memory = {
1072
+ usage: usage,
1073
+ workingSet: Math.max(0, usage - (metrics.memory?.totalInactiveFile ?? 0)),
1074
+ limit: unlimited(metrics.memory?.usage?.limit ?? 0),
1075
+ cache: metrics.memory?.cache ?? 0,
1076
+ swap: Math.max(0, (metrics.memory?.swap?.usage ?? 0) - usage),
1077
+ oomKills: metrics.memoryOomControl?.oomKill ?? 0
1078
+ };
1079
+ for (const entry of metrics.blkio?.ioServiceBytesRecursive ?? []) {
1080
+ if (/^read$/i.test(entry.op))
1081
+ stats.blkio.readBytes += entry.value ?? 0;
1082
+ if (/^write$/i.test(entry.op))
1083
+ stats.blkio.writeBytes += entry.value ?? 0;
1084
+ }
1085
+ for (const entry of metrics.blkio?.ioServicedRecursive ?? []) {
1086
+ if (/^read$/i.test(entry.op))
1087
+ stats.blkio.readOps += entry.value ?? 0;
1088
+ if (/^write$/i.test(entry.op))
1089
+ stats.blkio.writeOps += entry.value ?? 0;
1090
+ }
1091
+ }
1092
+ //The interfaces of its namespace of network (without its loopback)
1093
+ try {
1094
+ for (const line of (await (0, promises_1.readFile)(`/proc/${task.pid}/net/dev`, 'utf8')).split('\n').slice(2)) {
1095
+ const [name, counters] = line.split(':');
1096
+ if (!counters || name.trim() === 'lo')
1097
+ continue;
1098
+ const values = counters.trim().split(/\s+/).map(Number);
1099
+ stats.networks[name.trim()] = {
1100
+ rxBytes: values[0], rxPackets: values[1], rxErrors: values[2], rxDropped: values[3],
1101
+ txBytes: values[8], txPackets: values[9], txErrors: values[10], txDropped: values[11]
1102
+ };
1103
+ }
1104
+ }
1105
+ catch {
1106
+ //Its process is gone
1107
+ }
1108
+ return stats;
1109
+ }
1110
+ /**
1111
+ * The resources a running container uses: two samples, its use of the CPUs between them
1112
+ * @param container
1113
+ * @param interval milliseconds between the samples
1114
+ */
1115
+ async stats(container, interval = 1000) {
1116
+ const first = await this.sample(container);
1117
+ if (interval <= 0)
1118
+ return { ...first, cpu: { ...first.cpu, percent: 0 } };
1119
+ await (0, promises_3.setTimeout)(interval);
1120
+ const second = await this.sample(container);
1121
+ const elapsed = (second.read.getTime() - first.read.getTime()) * 1e6 || interval * 1e6;
1122
+ return { ...second, cpu: { ...second.cpu, percent: Math.max(0, (second.cpu.usage - first.cpu.usage) / elapsed * 100) } };
1123
+ }
1124
+ /**
1125
+ * Open a terminal in a running container: a process executed with its pseudo terminal, its input and its output by
1126
+ * FIFOs (mkfifo of the system)
1127
+ * @param container
1128
+ * @param options
1129
+ */
1130
+ async terminal(container, options) {
1131
+ const task = await this.client.getTask(container.id);
1132
+ if (task?.status !== M.ProcessStatus.RUNNING)
1133
+ throw Object.assign(new Error(`The container ${ContainerStore.Name(container)} is not running`), { code: 'NOT_RUNNING' });
1134
+ if (!Fifo_js_1.ProcessFifo.Supported())
1135
+ throw new Error('The terminals of the containers need mkfifo');
1136
+ const spec = ContainerdClient_js_1.ContainerdClient.FromJson(container.spec) ?? {};
1137
+ let user;
1138
+ if (options.user)
1139
+ user = await (0, Rootfs_js_1.resolveUser)(await this.client.snapshotMounts(container.snapshotter || this.options.snapshotter, container.snapshotKey || container.id), options.user);
1140
+ const env = { TERM: 'xterm', ...options.env ?? {} };
1141
+ const process = (0, Spec_js_1.execProcessSpec)(spec, {
1142
+ args: options.cmd,
1143
+ env: Object.entries(env).map(([key, value]) => `${key}=${value}`),
1144
+ cwd: options.workingDir,
1145
+ uid: user?.uid,
1146
+ gid: user?.gid,
1147
+ additionalGids: user?.additionalGids,
1148
+ terminal: true
1149
+ });
1150
+ if (options.cols && options.rows)
1151
+ process.consoleSize = { height: options.rows, width: options.cols };
1152
+ const execId = `tty-${(0, node_crypto_1.randomBytes)(8).toString('hex')}`;
1153
+ const directory = node_path_1.default.join(this.stateDir(container.id), 'exec');
1154
+ await (0, promises_1.mkdir)(directory, { recursive: true });
1155
+ const stdin = Fifo_js_1.ProcessFifo.Create(node_path_1.default.join(directory, `${execId}-stdin`), 'write');
1156
+ const stdout = Fifo_js_1.ProcessFifo.Create(node_path_1.default.join(directory, `${execId}-stdout`), 'read');
1157
+ let cleaned = false;
1158
+ const cleanup = async () => {
1159
+ if (cleaned)
1160
+ return;
1161
+ cleaned = true;
1162
+ stdin.close();
1163
+ stdout.close();
1164
+ await this.client.deleteProcess(container.id, execId).catch(() => undefined);
1165
+ await (0, promises_1.rm)(stdin.path, { force: true });
1166
+ await (0, promises_1.rm)(stdout.path, { force: true });
1167
+ };
1168
+ try {
1169
+ await this.client.exec({ containerId: container.id, execId: execId, stdin: stdin.path, stdout: stdout.path, terminal: true, spec: ContainerdClient_js_1.ContainerdClient.Json(ContainerdClient_js_1.PROCESS_TYPE_URL, process) });
1170
+ const waiting = this.client.wait(container.id, execId);
1171
+ await this.client.startTask(container.id, execId);
1172
+ const input = stdin.open();
1173
+ const output = stdout.open();
1174
+ input.on('error', () => undefined);
1175
+ const exited = (async () => {
1176
+ try {
1177
+ return (await waiting).exitStatus;
1178
+ }
1179
+ finally {
1180
+ //Its output read before the FIFOs are closed
1181
+ if (!output.readableEnded)
1182
+ await new Promise((resolve) => {
1183
+ const timer = setTimeout(resolve, 1000);
1184
+ output.once('end', () => {
1185
+ clearTimeout(timer);
1186
+ resolve();
1187
+ });
1188
+ });
1189
+ await cleanup();
1190
+ }
1191
+ })();
1192
+ exited.catch(() => undefined);
1193
+ return {
1194
+ execId: execId,
1195
+ input: input,
1196
+ output: output,
1197
+ resize: async (cols, rows) => this.client.resizePty(container.id, execId, cols, rows),
1198
+ exited: exited,
1199
+ close: async () => {
1200
+ if (cleaned)
1201
+ return;
1202
+ await this.client.kill(container.id, signalNumber('SIGKILL'), { execId: execId }).catch(() => undefined);
1203
+ await exited.catch(() => undefined);
1204
+ }
1205
+ };
1206
+ }
1207
+ catch (error) {
1208
+ await cleanup();
1209
+ throw error;
1210
+ }
1211
+ }
1212
+ /**
1213
+ * Update the resources of a container (its specification, the cgroup of its running task) and its restart policy,
1214
+ * without restarting it (docker update)
1215
+ * @param container
1216
+ * @param update
1217
+ */
1218
+ async updateResources(container, update) {
1219
+ const spec = ContainerdClient_js_1.ContainerdClient.FromJson(container.spec) ?? {};
1220
+ const resources = spec.linux.resources ??= {};
1221
+ //The limits removed: absent from the specification, given to the task as the values of no limit (the update of
1222
+ //runc leaves a 0 or an empty value as it is)
1223
+ const removed = {};
1224
+ if (update.memory !== undefined || update.memorySwap !== undefined || update.oomKillDisable !== undefined) {
1225
+ resources.memory ??= {};
1226
+ if (update.memory === 0) {
1227
+ //No swap limit without a memory limit
1228
+ delete resources.memory.limit;
1229
+ delete resources.memory.swap;
1230
+ removed.memory = removed.swap = true;
1231
+ }
1232
+ else if (update.memory !== undefined) {
1233
+ //A swap limit of twice the memory (the default one) follows the memory
1234
+ if (update.memorySwap === undefined && resources.memory.limit > 0 && resources.memory.swap === resources.memory.limit * 2)
1235
+ resources.memory.swap = update.memory * 2;
1236
+ resources.memory.limit = update.memory;
1237
+ }
1238
+ if (update.memorySwap !== undefined) {
1239
+ if (update.memorySwap > 0 && !(resources.memory.limit > 0))
1240
+ throw Object.assign(new Error('The swap limit of a container (memorySwap) needs its memory limit (memoryLimit)'), { code: 'INVALID_VALUE' });
1241
+ //0: no swap limit; discarded when the kernel does not limit the swap
1242
+ if (!removed.swap && isSwapLimitSupported())
1243
+ resources.memory.swap = update.memorySwap || -1;
1244
+ }
1245
+ if (update.oomKillDisable !== undefined)
1246
+ resources.memory.disableOOMKiller = update.oomKillDisable;
1247
+ if (resources.memory.swap > 0 && resources.memory.swap < resources.memory.limit)
1248
+ throw Object.assign(new Error('The swap limit of a container (memorySwap, its memory and its swap) is less than its memory limit (memoryLimit)'), { code: 'INVALID_VALUE' });
1249
+ }
1250
+ if (update.cpus !== undefined || update.cpuShares !== undefined || update.cpuset !== undefined) {
1251
+ resources.cpu ??= {};
1252
+ if (update.cpus !== undefined) {
1253
+ resources.cpu.quota = update.cpus ? Math.round(update.cpus * 100000) : -1;
1254
+ resources.cpu.period = 100000;
1255
+ }
1256
+ if (update.cpuShares === 0) {
1257
+ delete resources.cpu.shares;
1258
+ removed.shares = true;
1259
+ }
1260
+ else if (update.cpuShares !== undefined) {
1261
+ resources.cpu.shares = update.cpuShares;
1262
+ }
1263
+ if (update.cpuset === '') {
1264
+ delete resources.cpu.cpus;
1265
+ removed.cpus = true;
1266
+ }
1267
+ else if (update.cpuset !== undefined) {
1268
+ resources.cpu.cpus = update.cpuset;
1269
+ }
1270
+ }
1271
+ if (update.pidsLimit !== undefined)
1272
+ resources.pids = { limit: update.pidsLimit || -1 };
1273
+ const labels = {};
1274
+ if (update.restart !== undefined) {
1275
+ const restart = update.restart === 'no' ? '' : update.restart;
1276
+ labels[exports.ContainerLabels.RESTART_POLICY] = restart;
1277
+ labels[exports.ContainerLabels.RESTART_LOG_URI] = restart ? container.labels?.[exports.ContainerLabels.LOG_URI] ?? `file://${this.logFile(container.id)}` : '';
1278
+ const task = await this.client.getTask(container.id);
1279
+ labels[exports.ContainerLabels.RESTART_STATUS] = restart && task?.status === M.ProcessStatus.RUNNING ? 'running' : restart ? 'stopped' : '';
1280
+ }
1281
+ //The labels emptied are deleted
1282
+ await this.client.updateContainer({ id: container.id, spec: ContainerdClient_js_1.ContainerdClient.Json(ContainerdClient_js_1.SPEC_TYPE_URL, spec), labels: Object.fromEntries(Object.entries(labels).filter(([, value]) => !!value)) }, ['spec', ...Object.keys(labels).map((key) => `labels.${key}`)]);
1283
+ const task = await this.client.getTask(container.id);
1284
+ if (!task || task.status === M.ProcessStatus.STOPPED)
1285
+ return;
1286
+ const taskResources = structuredClone(resources);
1287
+ if (removed.memory)
1288
+ taskResources.memory.limit = -1;
1289
+ if (removed.swap)
1290
+ taskResources.memory.swap = -1;
1291
+ //The default weight of the kernel
1292
+ if (removed.shares)
1293
+ taskResources.cpu.shares = 1024;
1294
+ if (removed.cpus)
1295
+ taskResources.cpu.cpus = await onlineCpuSet();
1296
+ await this.client.updateTask(container.id, taskResources);
1297
+ }
1298
+ /**
1299
+ * Commit a container: the changes of its file system as a layer on its image, a new image (its container paused
1300
+ * meanwhile when it runs, by default)
1301
+ * @param container
1302
+ * @param options
1303
+ */
1304
+ async commit(container, options) {
1305
+ const task = await this.client.getTask(container.id);
1306
+ const pause = (options.pause ?? true) && task?.status === M.ProcessStatus.RUNNING;
1307
+ if (pause)
1308
+ await this.client.pause(container.id);
1309
+ try {
1310
+ return await this.images.commit({
1311
+ image: container.image,
1312
+ platform: container.labels?.[exports.ContainerLabels.PLATFORM] ? (0, Platforms_js_1.parsePlatform)(container.labels[exports.ContainerLabels.PLATFORM]) : (0, Platforms_js_1.hostPlatform)(),
1313
+ snapshotKey: container.snapshotKey || container.id,
1314
+ name: options.name,
1315
+ changes: options.changes,
1316
+ comment: options.comment,
1317
+ author: options.author
1318
+ });
1319
+ }
1320
+ finally {
1321
+ if (pause)
1322
+ await this.client.resume(container.id).catch(() => undefined);
1323
+ }
1324
+ }
1325
+ /**
1326
+ * Archive a path of the file system of a container (tar): the one of its running process (its mounts with it), or
1327
+ * the one of its snapshot when it is not running; its symbolic links resolved in it
1328
+ * @param container
1329
+ * @param file an absolute path in the container
1330
+ * @param destination
1331
+ */
1332
+ async archive(container, file, destination) {
1333
+ const task = await this.client.getTask(container.id);
1334
+ const running = !!task && task.status !== M.ProcessStatus.STOPPED && !!task.pid;
1335
+ const tree = running
1336
+ ? new Rootfs_js_1.DirectoryTree(`/proc/${task.pid}/root`)
1337
+ : new Rootfs_js_1.LayersTree((0, Rootfs_js_1.layerDirectories)(await this.client.snapshotMounts(container.snapshotter || this.options.snapshotter, container.snapshotKey || container.id)));
1338
+ const resolved = await tree.resolve(file);
1339
+ const root = await tree.lstat(resolved);
1340
+ if (!root)
1341
+ throw Object.assign(new Error(`The path ${file} does not exist in the container ${ContainerStore.Name(container)}`), { code: 'PATH_NOT_FOUND' });
1342
+ const archive = (0, tar_stream_1.pack)();
1343
+ const output = (0, promises_2.pipeline)(archive, destination);
1344
+ const entry = (header) => new Promise((resolve, reject) => void archive.entry(header, (error) => error ? reject(error) : resolve()));
1345
+ const add = async (name, inner, stats, real) => {
1346
+ const header = { name: name, mode: stats.mode & 0o7777, mtime: stats.mtime, uid: stats.uid, gid: stats.gid };
1347
+ if (stats.isDirectory()) {
1348
+ await entry({ ...header, type: 'directory' });
1349
+ for (const child of await tree.readdir(inner)) {
1350
+ const childInner = node_path_1.default.posix.join(inner, child);
1351
+ const found = await tree.lstat(childInner);
1352
+ if (found)
1353
+ await add(`${name}/${child}`, childInner, found.stats, found.path);
1354
+ }
1355
+ }
1356
+ else if (stats.isSymbolicLink()) {
1357
+ await entry({ ...header, type: 'symlink', linkname: await (0, promises_1.readlink)(real) });
1358
+ }
1359
+ else if (stats.isFile()) {
1360
+ await new Promise((resolve, reject) => {
1361
+ const writer = archive.entry({ ...header, type: 'file', size: stats.size }, (error) => error ? reject(error) : resolve());
1362
+ (0, promises_2.pipeline)((0, node_fs_1.createReadStream)(real), writer).catch(reject);
1363
+ });
1364
+ }
1365
+ //The devices, the sockets and the pipes are not archived
1366
+ };
1367
+ try {
1368
+ await add(node_path_1.default.posix.basename(resolved) || '.', resolved, root.stats, root.path);
1369
+ archive.finalize();
1370
+ }
1371
+ catch (error) {
1372
+ archive.destroy(error);
1373
+ }
1374
+ await output;
1375
+ }
1376
+ /**
1377
+ * The name of a container
1378
+ * @param container
1379
+ */
1380
+ static Name(container) {
1381
+ return container.labels?.[exports.ContainerLabels.NAME] ?? container.id;
1382
+ }
1383
+ }
1384
+ exports.ContainerStore = ContainerStore;