diff --git a/package.json b/package.json index fa57561..5eaa01a 100644 --- a/package.json +++ b/package.json @@ -34,17 +34,18 @@ "homepage": "https://gitlab.com/mojoio/docker#readme", "dependencies": { "@push.rocks/lik": "^6.0.15", - "@push.rocks/smartarchive": "^4.0.22", + "@push.rocks/smartarchive": "^4.0.36", "@push.rocks/smartbucket": "^3.0.10", - "@push.rocks/smartfile": "^11.0.16", + "@push.rocks/smartfile": "^11.0.20", "@push.rocks/smartjson": "^5.0.20", - "@push.rocks/smartlog": "^3.0.6", + "@push.rocks/smartlog": "^3.0.7", "@push.rocks/smartnetwork": "^3.0.0", "@push.rocks/smartpath": "^5.0.18", "@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartrequest": "^2.0.22", "@push.rocks/smartstream": "^3.0.44", "@push.rocks/smartstring": "^4.0.15", + "@push.rocks/smartunique": "^3.0.9", "@push.rocks/smartversion": "^3.0.5", "@tsclass/tsclass": "^4.0.54", "rxjs": "^7.5.7" @@ -54,7 +55,7 @@ "@git.zone/tsrun": "^1.2.12", "@git.zone/tstest": "^1.0.90", "@push.rocks/tapbundle": "^5.0.23", - "@types/node": "20.14.1" + "@types/node": "20.14.2" }, "files": [ "ts/**/*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5342266..2143fc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,20 +12,20 @@ importers: specifier: ^6.0.15 version: 6.0.15 '@push.rocks/smartarchive': - specifier: ^4.0.22 - version: 4.0.22 + specifier: ^4.0.36 + version: 4.0.36 '@push.rocks/smartbucket': specifier: ^3.0.10 version: 3.0.10 '@push.rocks/smartfile': - specifier: ^11.0.16 - version: 11.0.16 + specifier: ^11.0.20 + version: 11.0.20 '@push.rocks/smartjson': specifier: ^5.0.20 version: 5.0.20 '@push.rocks/smartlog': - specifier: ^3.0.6 - version: 3.0.6 + specifier: ^3.0.7 + version: 3.0.7 '@push.rocks/smartnetwork': specifier: ^3.0.0 version: 3.0.2 @@ -44,6 +44,9 @@ importers: '@push.rocks/smartstring': specifier: ^4.0.15 version: 4.0.15 + '@push.rocks/smartunique': + specifier: ^3.0.9 + version: 3.0.9 '@push.rocks/smartversion': specifier: ^3.0.5 version: 3.0.5 @@ -59,19 +62,22 @@ importers: version: 2.1.80 '@git.zone/tsrun': specifier: ^1.2.12 - version: 1.2.46(@types/node@20.14.1) + version: 1.2.46(@types/node@20.14.2) '@git.zone/tstest': specifier: ^1.0.90 - version: 1.0.90(@types/node@20.14.1) + version: 1.0.90(@types/node@20.14.2) '@push.rocks/tapbundle': specifier: ^5.0.23 version: 5.0.23 '@types/node': - specifier: 20.14.1 - version: 20.14.1 + specifier: 20.14.2 + version: 20.14.2 packages: + '@api.global/typedrequest-interfaces@2.0.2': + resolution: {integrity: sha512-D+mkr4IiUZ/eUgrdp5jXjBKOW/iuMcl0z2ZLQsLLypKX/psFGD3viZJ58FNRa+/1OSM38JS5wFyoWl8oPEFLrw==} + '@api.global/typedrequest-interfaces@3.0.19': resolution: {integrity: sha512-uuHUXJeOy/inWSDrwD0Cwax2rovpxYllDhM2RWh+6mVpQuNmZ3uw6IVg6dA2G1rOe24Ebs+Y9SzEogo+jYN7vw==} @@ -338,8 +344,8 @@ packages: '@push.rocks/lik@6.0.15': resolution: {integrity: sha512-rZxln6l4NAU931MTxnsjy1pue+S3AXtDCidHH/tbkqBtrWIzWuXduo6Nz3zYkndbD64Knyta7F60JRvcOe4XqA==} - '@push.rocks/smartarchive@4.0.22': - resolution: {integrity: sha512-8bj+J962edFUgdNh/951gkOD3gjQHgbwvMFxePWbJm5hXM9MOH7VgWA8XeNBUMnHrEHAlx/D5VYe1qulxF8lEA==} + '@push.rocks/smartarchive@4.0.36': + resolution: {integrity: sha512-zFd0xKK2TsE/mOxsxp4MrAmH9skFOJijMG0VuHjkYB5WRspvoaOssMypiILCXy/m7vEhqAVGmgrk8Ed0p4gDMQ==} '@push.rocks/smartbrowser@2.0.6': resolution: {integrity: sha512-Ne+KCVhV/DROc1rHRRw59K6h0+LpQAK9fdOUtgDZ7laLPmB/tmnbUh3IuRDNcIY1iVA9pydoobwjnTjVgio9eQ==} @@ -383,8 +389,8 @@ packages: '@push.rocks/smartfile@10.0.41': resolution: {integrity: sha512-xOOy0duI34M2qrJZggpk51EHGXmg9+mBL1Q55tNiQKXzfx89P3coY1EAZG8tvmep3qB712QEKe7T+u04t42Kjg==} - '@push.rocks/smartfile@11.0.16': - resolution: {integrity: sha512-tl0IJj1mWqNUkqZLjlFKR0OEixhX8cafws7WcxuhNZymkK9axo03O9DiFbUZb4XUbcfYaYNWGTqHUyppWpwRHQ==} + '@push.rocks/smartfile@11.0.20': + resolution: {integrity: sha512-gJERlNE2fNah9HLq6W3srcl1GZwlz2vFVZRmb50TQLabmWF4qyTlaMYAwY8ffgf8np4TsHAa4s+kL5F0zUfUUg==} '@push.rocks/smarthash@3.0.4': resolution: {integrity: sha512-HJ/fSx41jm0CvSaqMLa6b2nuNK5rHAqAeAq3dAB7Sq9BCPm2M0J5ZVDTzEAH8pS91XYniUiwuE0jwPERNn9hmw==} @@ -401,8 +407,11 @@ packages: '@push.rocks/smartlog-interfaces@3.0.0': resolution: {integrity: sha512-dfRqiSolGQwaF9gWmkixWOoXZxcWBjK3u6A1CpcfhCbVr2VSUMIrZ5t74/DgdfedsTrhDqoD0NGezsMXF2pFHQ==} - '@push.rocks/smartlog@3.0.6': - resolution: {integrity: sha512-HvZtgur6PY+n6skw5Jx+KWwHciCiWNm+WNLkqRreuLXJrWKknwYvy/Ea+f61RqJBHEkOYTYxRoddBuC+6HAoWw==} + '@push.rocks/smartlog-interfaces@3.0.2': + resolution: {integrity: sha512-8hGRTJehbsFSJxLhCQkA018mZtXVPxPTblbg9VaE/EqISRzUw+eosJ2EJV7M4Qu0eiTJZjnWnNLn8CkD77ziWw==} + + '@push.rocks/smartlog@3.0.7': + resolution: {integrity: sha512-WHOw0iHHjCEbYY4KGX40iFtLI11QJvvWIbC9yFn3Mt+nrdupMnry7Ztc5v/PqO8lu33Q6xDBMXiNQ9yNY0HVGw==} '@push.rocks/smartmanifest@2.0.2': resolution: {integrity: sha512-QGc5C9vunjfUbYsPGz5bynV/mVmPHkrQDkWp8ZO8VJtK1GZe+njgbrNyxn2SUHR0IhSAbSXl1j4JvBqYf5eTVg==} @@ -735,8 +744,8 @@ packages: '@types/minimatch@5.1.2': resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - '@types/node@20.14.1': - resolution: {integrity: sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==} + '@types/node@20.14.2': + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} '@types/parse5@6.0.3': resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} @@ -1708,8 +1717,8 @@ packages: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} - jackspeak@3.2.3: - resolution: {integrity: sha512-htOzIMPbpLid/Gq9/zaz9SfExABxqRe1sSCdxntlO/aMD6u0issZQiY25n2GKQUtJ02j7z5sfptlAOMpWWOmvw==} + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} engines: {node: '>=14'} js-base64@3.7.7: @@ -2707,6 +2716,8 @@ packages: snapshots: + '@api.global/typedrequest-interfaces@2.0.2': {} + '@api.global/typedrequest-interfaces@3.0.19': {} '@api.global/typedrequest@3.0.23': @@ -2730,9 +2741,9 @@ snapshots: '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartenv': 5.0.12 '@push.rocks/smartfeed': 1.0.11 - '@push.rocks/smartfile': 11.0.16 + '@push.rocks/smartfile': 11.0.20 '@push.rocks/smartjson': 5.0.20 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartlog-destination-devtools': 1.0.10 '@push.rocks/smartmanifest': 2.0.2 '@push.rocks/smartmime': 1.0.6 @@ -2872,8 +2883,8 @@ snapshots: '@push.rocks/early': 4.0.4 '@push.rocks/smartcli': 4.0.11 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.0.16 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartfile': 11.0.20 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartpath': 5.0.18 '@push.rocks/smartpromise': 4.0.3 typescript: 5.4.5 @@ -2883,8 +2894,8 @@ snapshots: '@push.rocks/early': 4.0.4 '@push.rocks/smartcli': 4.0.10 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.0.16 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartfile': 11.0.20 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartlog-destination-local': 9.0.2 '@push.rocks/smartpath': 5.0.18 '@push.rocks/smartpromise': 4.0.3 @@ -2896,27 +2907,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@git.zone/tsrun@1.2.46(@types/node@20.14.1)': + '@git.zone/tsrun@1.2.46(@types/node@20.14.2)': dependencies: '@push.rocks/smartfile': 10.0.41 '@push.rocks/smartshell': 3.0.5 - ts-node: 10.9.2(@types/node@20.14.1)(typescript@5.1.6) + ts-node: 10.9.2(@types/node@20.14.2)(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - '@types/node' - '@git.zone/tstest@1.0.90(@types/node@20.14.1)': + '@git.zone/tstest@1.0.90(@types/node@20.14.2)': dependencies: '@api.global/typedserver': 3.0.29 '@git.zone/tsbundle': 2.0.15 - '@git.zone/tsrun': 1.2.46(@types/node@20.14.1) + '@git.zone/tsrun': 1.2.46(@types/node@20.14.2) '@push.rocks/consolecolor': 2.0.2 '@push.rocks/smartbrowser': 2.0.6 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.0.16 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartfile': 11.0.20 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartshell': 3.0.5 '@push.rocks/tapbundle': 5.0.23 @@ -3043,10 +3054,10 @@ snapshots: '@types/symbol-tree': 3.2.5 symbol-tree: 3.2.4 - '@push.rocks/smartarchive@4.0.22': + '@push.rocks/smartarchive@4.0.36': dependencies: '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.0.16 + '@push.rocks/smartfile': 11.0.20 '@push.rocks/smartpath': 5.0.18 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrequest': 2.0.22 @@ -3105,7 +3116,7 @@ snapshots: '@push.rocks/smartcli@4.0.10': dependencies: '@push.rocks/lik': 6.0.15 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartparam': 1.1.10 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrx': 3.0.7 @@ -3114,7 +3125,7 @@ snapshots: '@push.rocks/smartcli@4.0.11': dependencies: '@push.rocks/lik': 6.0.15 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartobject': 1.0.12 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrx': 3.0.7 @@ -3168,7 +3179,7 @@ snapshots: glob: 10.3.12 js-yaml: 4.1.0 - '@push.rocks/smartfile@11.0.16': + '@push.rocks/smartfile@11.0.20': dependencies: '@push.rocks/lik': 6.0.15 '@push.rocks/smartdelay': 3.0.5 @@ -3215,10 +3226,15 @@ snapshots: dependencies: '@apiglobal/typedrequest-interfaces': 2.0.1 - '@push.rocks/smartlog@3.0.6': + '@push.rocks/smartlog-interfaces@3.0.2': + dependencies: + '@api.global/typedrequest-interfaces': 2.0.2 + '@tsclass/tsclass': 4.0.54 + + '@push.rocks/smartlog@3.0.7': dependencies: '@push.rocks/isounique': 1.0.5 - '@push.rocks/smartlog-interfaces': 3.0.0 + '@push.rocks/smartlog-interfaces': 3.0.2 '@push.rocks/smartmanifest@2.0.2': {} @@ -3267,7 +3283,7 @@ snapshots: dependencies: '@push.rocks/smartbuffer': 3.0.4 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.0.16 + '@push.rocks/smartfile': 11.0.20 '@push.rocks/smartnetwork': 3.0.2 '@push.rocks/smartpath': 5.0.18 '@push.rocks/smartpromise': 4.0.3 @@ -3339,7 +3355,7 @@ snapshots: '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartenv': 5.0.12 '@push.rocks/smartjson': 5.0.20 - '@push.rocks/smartlog': 3.0.6 + '@push.rocks/smartlog': 3.0.7 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrx': 3.0.7 '@push.rocks/smarttime': 4.0.6 @@ -3628,14 +3644,14 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/babel__code-frame@7.0.6': {} '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/buffer-json@2.0.3': {} @@ -3647,17 +3663,17 @@ snapshots: '@types/clean-css@4.2.11': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 source-map: 0.6.1 '@types/co-body@6.1.3': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/qs': 6.9.15 '@types/connect@3.4.38': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/content-disposition@0.5.8': {} @@ -3670,11 +3686,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 4.17.21 '@types/keygrip': 1.0.6 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/cors@2.8.17': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/debounce@1.2.4': {} @@ -3682,7 +3698,7 @@ snapshots: '@types/express-serve-static-core@4.19.0': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -3696,17 +3712,17 @@ snapshots: '@types/from2@2.3.5': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/glob@8.1.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/html-minifier@4.0.5': dependencies: @@ -3736,7 +3752,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/keygrip@1.0.6': {} @@ -3753,7 +3769,7 @@ snapshots: '@types/http-errors': 2.0.4 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/mime-types@2.1.4': {} @@ -3763,7 +3779,7 @@ snapshots: '@types/minimatch@5.1.2': {} - '@types/node@20.14.1': + '@types/node@20.14.2': dependencies: undici-types: 5.26.5 @@ -3784,12 +3800,12 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/send': 0.17.4 '@types/sinon-chai@3.2.12': @@ -3807,11 +3823,11 @@ snapshots: '@types/tar-stream@3.1.3': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/through2@2.0.41': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/trusted-types@2.0.7': {} @@ -3827,15 +3843,15 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/ws@8.5.10': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.14.1 + '@types/node': 20.14.2 optional: true '@web/browser-logs@0.4.0': @@ -4323,7 +4339,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 20.14.1 + '@types/node': 20.14.2 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -4582,7 +4598,7 @@ snapshots: glob@10.4.1: dependencies: foreground-child: 3.1.1 - jackspeak: 3.2.3 + jackspeak: 3.4.0 minimatch: 9.0.4 minipass: 7.1.2 path-scurry: 1.11.1 @@ -4828,7 +4844,7 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@3.2.3: + jackspeak@3.4.0: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -5646,14 +5662,14 @@ snapshots: tree-kill@1.2.2: {} - ts-node@10.9.2(@types/node@20.14.1)(typescript@5.1.6): + ts-node@10.9.2(@types/node@20.14.2)(typescript@5.1.6): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.14.1 + '@types/node': 20.14.2 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 diff --git a/test/test.nonci.node.ts b/test/test.nonci.node.ts index 91e9ae5..0c1d7fc 100644 --- a/test/test.nonci.node.ts +++ b/test/test.nonci.node.ts @@ -9,6 +9,7 @@ let testDockerHost: docker.DockerHost; tap.test('should create a new Dockersock instance', async () => { testDockerHost = new docker.DockerHost({}); + await testDockerHost.start(); return expect(testDockerHost).toBeInstanceOf(docker.DockerHost); }); @@ -118,7 +119,7 @@ tap.test('should create a service', async () => { await testSecret.remove(); }); -tap.test('should export images', async (toolsArg) => { +tap.skip.test('should export images', async (toolsArg) => { const done = toolsArg.defer(); const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, { creationObject: { @@ -135,7 +136,7 @@ tap.test('should export images', async (toolsArg) => { await done.promise; }); -tap.test('should import images', async (toolsArg) => { +tap.skip.test('should import images', async (toolsArg) => { const done = toolsArg.defer(); const fsReadStream = plugins.smartfile.fsStream.createReadStream( plugins.path.join(paths.nogitDir, 'testimage.tar') @@ -146,6 +147,10 @@ tap.test('should import images', async (toolsArg) => { imageUrl: 'code.foss.global/host.today/ht-docker-node:latest', } }) +}); + +tap.test('should expose a working DockerImageStore', async () => { + await testDockerHost.imageStore.storeImage('hello', plugins.smartfile.fsStream.createReadStream(plugins.path.join(paths.nogitDir, 'testimage.tar'))); }) export default tap.start(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index baeaaf3..27b9e79 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@apiclient.xyz/docker', - version: '1.1.4', + version: '1.2.0', description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.' } diff --git a/ts/classes.container.ts b/ts/classes.container.ts index 1b29e99..63dca45 100644 --- a/ts/classes.container.ts +++ b/ts/classes.container.ts @@ -2,7 +2,7 @@ import * as plugins from './plugins.js'; import * as interfaces from './interfaces/index.js'; import { DockerHost } from './classes.host.js'; -import { logger } from './logging.js'; +import { logger } from './logger.js'; export class DockerContainer { // STATIC diff --git a/ts/classes.host.ts b/ts/classes.host.ts index 449bad3..29cdeae 100644 --- a/ts/classes.host.ts +++ b/ts/classes.host.ts @@ -1,10 +1,12 @@ import * as plugins from './plugins.js'; +import * as paths from './paths.js'; import { DockerContainer } from './classes.container.js'; import { DockerNetwork } from './classes.network.js'; import { DockerService } from './classes.service.js'; -import { logger } from './logging.js'; +import { logger } from './logger.js'; import path from 'path'; -import type { DockerImageStore } from './classes.imagestore.js'; +import { DockerImageStore } from './classes.imagestore.js'; +import { DockerImage } from './classes.image.js'; export interface IAuthData { serveraddress: string; @@ -18,6 +20,8 @@ export interface IDockerHostConstructorOptions { } export class DockerHost { + public options: IDockerHostConstructorOptions; + /** * the path where the docker sock can be found */ @@ -30,6 +34,12 @@ export class DockerHost { * @param pathArg */ constructor(optionsArg: IDockerHostConstructorOptions) { + this.options = { + ...{ + imageStoreDir: plugins.path.join(paths.nogitDir, 'temp-docker-image-store'), + }, + ...optionsArg, + } let pathToUse: string; if (optionsArg.dockerSockPath) { pathToUse = optionsArg.dockerSockPath; @@ -48,6 +58,17 @@ export class DockerHost { } console.log(`using docker sock at ${pathToUse}`); this.socketPath = pathToUse; + this.imageStore = new DockerImageStore(this, { + bucketDir: null, + localDirPath: this.options.imageStoreDir, + }) + } + + public async start() { + await this.imageStore.start(); + } + public async stop() { + await this.imageStore.stop(); } /** @@ -81,6 +102,9 @@ export class DockerHost { }); } + // ============== + // NETWORKS + // ============== /** * gets all networks */ @@ -89,9 +113,23 @@ export class DockerHost { } /** - * + * create a network */ + public async createNetwork(optionsArg: Parameters[1]) { + return await DockerNetwork.createNetwork(this, optionsArg); + } + /** + * get a network by name + */ + public async getNetworkByName(networkNameArg: string) { + return await DockerNetwork.getNetworkByName(this, networkNameArg); + } + + + // ============== + // CONTAINERS + // ============== /** * gets all containers */ @@ -100,6 +138,10 @@ export class DockerHost { return containerArray; } + // ============== + // SERVICES + // ============== + /** * gets all services */ @@ -108,6 +150,24 @@ export class DockerHost { return serviceArray; } + // ============== + // IMAGES + // ============== + + /** + * get all images + */ + public async getImages() { + return await DockerImage.getImages(this); + } + + /** + * get an image by name + */ + public async getImageByName(imageNameArg: string) { + return await DockerImage.getImageByName(this, imageNameArg); + } + /** * */ diff --git a/ts/classes.image.ts b/ts/classes.image.ts index 9471fbd..c6007f0 100644 --- a/ts/classes.image.ts +++ b/ts/classes.image.ts @@ -1,8 +1,11 @@ import * as plugins from './plugins.js'; import * as interfaces from './interfaces/index.js'; import { DockerHost } from './classes.host.js'; -import { logger } from './logging.js'; +import { logger } from './logger.js'; +/** + * represents a docker image on the remote docker host + */ export class DockerImage { // STATIC public static async getImages(dockerHost: DockerHost) { @@ -14,7 +17,7 @@ export class DockerImage { return images; } - public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) { + public static async getImageByName(dockerHost: DockerHost, imageNameArg: string) { const images = await this.getImages(dockerHost); const result = images.find((image) => { if (image.RepoTags) { @@ -67,7 +70,7 @@ export class DockerImage { ); if (response.statusCode < 300) { logger.log('info', `Successfully pulled image ${imageUrlObject.imageUrl} from the registry`); - const image = await DockerImage.findImageByName(dockerHostArg, imageUrlObject.imageOriginTag); + const image = await DockerImage.getImageByName(dockerHostArg, imageUrlObject.imageOriginTag); return image; } else { logger.log('error', `Failed at the attempt of creating a new image`); diff --git a/ts/classes.imagestore.ts b/ts/classes.imagestore.ts index 1fcc6dc..72f57cd 100644 --- a/ts/classes.imagestore.ts +++ b/ts/classes.imagestore.ts @@ -1,5 +1,6 @@ import * as plugins from './plugins.js'; import * as paths from './paths.js'; +import { logger } from './logger.js'; import type { DockerHost } from './classes.host.js'; export interface IDockerImageStoreConstructorOptions { @@ -22,19 +23,78 @@ export class DockerImageStore { // Method to store tar stream public async storeImage(imageName: string, tarStream: plugins.smartstream.stream.Readable): Promise { - const imagePath = plugins.path.join(this.options.localDirPath, `${imageName}.tar`); + logger.log('info', `Storing image ${imageName}...`); + const uniqueProcessingId = plugins.smartunique.shortId(); + const initialTarDownloadPath = plugins.path.join(this.options.localDirPath, `${uniqueProcessingId}.tar`); + const extractionDir = plugins.path.join(this.options.localDirPath, uniqueProcessingId); // Create a write stream to store the tar file - const writeStream = plugins.smartfile.fsStream.createWriteStream(imagePath); + const writeStream = plugins.smartfile.fsStream.createWriteStream(initialTarDownloadPath); - return new Promise((resolve, reject) => { + // lets wait for the write stream to finish + await new Promise((resolve, reject) => { tarStream.pipe(writeStream); - writeStream.on('finish', resolve); writeStream.on('error', reject); }); + logger.log('info', `Image ${imageName} stored locally for processing. Extracting...`); + + // lets process the image + const tarArchive = await plugins.smartarchive.SmartArchive.fromArchiveFile(initialTarDownloadPath); + await tarArchive.exportToFs(extractionDir); + logger.log('info', `Image ${imageName} extracted.`); + await plugins.smartfile.fs.remove(initialTarDownloadPath); + logger.log('info', `deleted original tar to save space.`); + logger.log('info', `now repackaging for s3...`); + const smartfileIndexJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'index.json')); + const smartfileManifestJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'manifest.json')); + const smartfileOciLayoutJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'oci-layout')); + const smartfileRepositoriesJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'repositories')); + const indexJson = JSON.parse(smartfileIndexJson.contents.toString()); + const manifestJson = JSON.parse(smartfileManifestJson.contents.toString()); + const ociLayoutJson = JSON.parse(smartfileOciLayoutJson.contents.toString()); + const repositoriesJson = JSON.parse(smartfileRepositoriesJson.contents.toString()); + + indexJson.manifests[0].annotations['io.containerd.image.name'] = imageName; + manifestJson[0].RepoTags[0] = imageName; + const repoFirstKey = Object.keys(repositoriesJson)[0]; + const repoFirstValue = repositoriesJson[repoFirstKey]; + repositoriesJson[imageName] = repoFirstValue; + delete repositoriesJson[repoFirstKey]; + + smartfileIndexJson.contents = Buffer.from(JSON.stringify(indexJson, null, 2)); + smartfileManifestJson.contents = Buffer.from(JSON.stringify(manifestJson, null, 2)); + smartfileOciLayoutJson.contents = Buffer.from(JSON.stringify(ociLayoutJson, null, 2)); + smartfileRepositoriesJson.contents = Buffer.from(JSON.stringify(repositoriesJson, null, 2)); + await Promise.all([ + smartfileIndexJson.write(), + smartfileManifestJson.write(), + smartfileOciLayoutJson.write(), + smartfileRepositoriesJson.write(), + ]); + + logger.log('info', 'repackaging archive for s3...'); + const tartools = new plugins.smartarchive.TarTools(); + const newTarPack = await tartools.packDirectory(extractionDir); + const finalTarName = `${uniqueProcessingId}.processed.tar`; + const finalTarPath = plugins.path.join(this.options.localDirPath, finalTarName); + const finalWriteStream = plugins.smartfile.fsStream.createWriteStream(finalTarPath); + await new Promise((resolve, reject) => { + newTarPack.finalize(); + newTarPack.pipe(finalWriteStream); + finalWriteStream.on('finish', resolve); + finalWriteStream.on('error', reject); + }); + logger.log('ok', `Repackaged image ${imageName} for s3.`); + await plugins.smartfile.fs.remove(extractionDir); } + public async start() { + await plugins.smartfile.fs.ensureEmptyDir(this.options.localDirPath); + } + + public async stop() {} + // Method to retrieve tar stream public async getImage(imageName: string): Promise { const imagePath = plugins.path.join(this.options.localDirPath, `${imageName}.tar`); diff --git a/ts/classes.network.ts b/ts/classes.network.ts index 9f0d1c9..7c8d87c 100644 --- a/ts/classes.network.ts +++ b/ts/classes.network.ts @@ -3,7 +3,7 @@ import * as interfaces from './interfaces/index.js'; import { DockerHost } from './classes.host.js'; import { DockerService } from './classes.service.js'; -import { logger } from './logging.js'; +import { logger } from './logger.js'; export class DockerNetwork { public static async getNetworks(dockerHost: DockerHost): Promise { diff --git a/ts/classes.service.ts b/ts/classes.service.ts index bbaf0a1..2f5e3d7 100644 --- a/ts/classes.service.ts +++ b/ts/classes.service.ts @@ -4,7 +4,7 @@ import * as interfaces from './interfaces/index.js'; import { DockerHost } from './classes.host.js'; import { DockerImage } from './classes.image.js'; import { DockerSecret } from './classes.secret.js'; -import { logger } from './logging.js'; +import { logger } from './logger.js'; export class DockerService { // STATIC diff --git a/ts/logger.ts b/ts/logger.ts new file mode 100644 index 0000000..cf8676e --- /dev/null +++ b/ts/logger.ts @@ -0,0 +1,5 @@ +import * as plugins from './plugins.js'; +import { commitinfo } from './00_commitinfo_data.js'; + +export const logger = plugins.smartlog.Smartlog.createForCommitinfo(commitinfo); +logger.enableConsole(); \ No newline at end of file diff --git a/ts/logging.ts b/ts/logging.ts deleted file mode 100644 index 882d49c..0000000 --- a/ts/logging.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as plugins from './plugins.js'; - -export const logger = new plugins.smartlog.ConsoleLog(); diff --git a/ts/plugins.ts b/ts/plugins.ts index 3326a5f..123343f 100644 --- a/ts/plugins.ts +++ b/ts/plugins.ts @@ -5,6 +5,7 @@ export { path }; // @pushrocks scope import * as lik from '@push.rocks/lik'; +import * as smartarchive from '@push.rocks/smartarchive'; import * as smartbucket from '@push.rocks/smartbucket'; import * as smartfile from '@push.rocks/smartfile'; import * as smartjson from '@push.rocks/smartjson'; @@ -15,10 +16,12 @@ import * as smartpromise from '@push.rocks/smartpromise'; import * as smartrequest from '@push.rocks/smartrequest'; import * as smartstring from '@push.rocks/smartstring'; import * as smartstream from '@push.rocks/smartstream'; +import * as smartunique from '@push.rocks/smartunique'; import * as smartversion from '@push.rocks/smartversion'; export { lik, + smartarchive, smartbucket, smartfile, smartjson, @@ -29,6 +32,7 @@ export { smartrequest, smartstring, smartstream, + smartunique, smartversion, };