Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
52af76b7ed | |||
414d7dd727 | |||
4b1c908b89 | |||
6e313261e7 | |||
42df15a523 | |||
7ef2ebcf5b | |||
87f26b7b63 | |||
ffdc61fb42 |
@@ -6,8 +6,8 @@ on:
|
|||||||
- '**'
|
- '**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
|
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Install pnpm and npmci
|
- name: Install pnpm and npmci
|
||||||
run: |
|
run: |
|
||||||
pnpm install -g pnpm
|
pnpm install -g pnpm
|
||||||
pnpm install -g @shipzone/npmci
|
pnpm install -g @ship.zone/npmci
|
||||||
|
|
||||||
- name: Run npm prepare
|
- name: Run npm prepare
|
||||||
run: npmci npm prepare
|
run: npmci npm prepare
|
||||||
|
@@ -6,8 +6,8 @@ on:
|
|||||||
- '*'
|
- '*'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
|
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
pnpm install -g pnpm
|
pnpm install -g pnpm
|
||||||
pnpm install -g @shipzone/npmci
|
pnpm install -g @ship.zone/npmci
|
||||||
npmci npm prepare
|
npmci npm prepare
|
||||||
|
|
||||||
- name: Audit production dependencies
|
- name: Audit production dependencies
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
pnpm install -g pnpm
|
pnpm install -g pnpm
|
||||||
pnpm install -g @shipzone/npmci
|
pnpm install -g @ship.zone/npmci
|
||||||
npmci npm prepare
|
npmci npm prepare
|
||||||
|
|
||||||
- name: Test stable
|
- name: Test stable
|
||||||
@@ -82,7 +82,7 @@ jobs:
|
|||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
pnpm install -g pnpm
|
pnpm install -g pnpm
|
||||||
pnpm install -g @shipzone/npmci
|
pnpm install -g @ship.zone/npmci
|
||||||
npmci npm prepare
|
npmci npm prepare
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
@@ -104,7 +104,7 @@ jobs:
|
|||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
pnpm install -g pnpm
|
pnpm install -g pnpm
|
||||||
pnpm install -g @shipzone/npmci
|
pnpm install -g @ship.zone/npmci
|
||||||
npmci npm prepare
|
npmci npm prepare
|
||||||
|
|
||||||
- name: Code quality
|
- name: Code quality
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@@ -3,7 +3,6 @@
|
|||||||
# artifacts
|
# artifacts
|
||||||
coverage/
|
coverage/
|
||||||
public/
|
public/
|
||||||
pages/
|
|
||||||
|
|
||||||
# installs
|
# installs
|
||||||
node_modules/
|
node_modules/
|
||||||
@@ -17,4 +16,8 @@ node_modules/
|
|||||||
dist/
|
dist/
|
||||||
dist_*/
|
dist_*/
|
||||||
|
|
||||||
# custom
|
# AI
|
||||||
|
.claude/
|
||||||
|
.serena/
|
||||||
|
|
||||||
|
#------# custom
|
Binary file not shown.
65
changelog.md
65
changelog.md
@@ -1,6 +1,36 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-08-19 - 1.3.5 - fix(core)
|
||||||
|
Stabilize CI/workflows and runtime: update CI images/metadata, improve streaming requests and image handling, and fix tests & package metadata
|
||||||
|
|
||||||
|
- Update CI workflows and images: switch workflow IMAGE to code.foss.global/host.today/ht-docker-node:npmci, fix NPMCI_COMPUTED_REPOURL placeholders, and replace @shipzone/npmci with @ship.zone/npmci in workflows
|
||||||
|
- Update npmextra.json gitzone metadata (githost -> code.foss.global, gitscope -> apiclient.xyz, npmPackagename -> @apiclient.xyz/docker) and npmdocker.baseImage -> host.today/ht-docker-node:npmci
|
||||||
|
- Adjust package.json repository/bugs/homepage to code.foss.global, add pnpm overrides entry and normalize package metadata
|
||||||
|
- Improve DockerHost streaming and request handling: reduce requestStreaming timeout to 30s, enable autoDrain for streaming requests, improve response parsing for streaming vs JSON endpoints to avoid hangs
|
||||||
|
- Enhance DockerImage and DockerImageStore stream handling and tar processing: more robust import/export parsing, safer stream-to-file writes, repackaging steps, and error handling
|
||||||
|
- Unskip and update tests: re-enable DockerImageStore integration test, change stored image name to 'hello2', add formatting fixes and ensure cleanup stops the test DockerHost
|
||||||
|
- Miscellaneous code and docs cleanup: numerous formatting fixes and trailing-comma normalization across README and TS sources, update commitinfo and logger newline fixes, and add local tool ignores (.claude/.serena) to .gitignore
|
||||||
|
|
||||||
|
## 2025-08-19 - 1.3.4 - fix(test)
|
||||||
|
|
||||||
|
Increase test timeout, enable DockerImageStore test, update test image name, bump smartrequest patch, and add local claude settings
|
||||||
|
|
||||||
|
- Increase tstest timeout from 120s to 600s in package.json to accommodate longer-running integration tests.
|
||||||
|
- Unskip the DockerImageStore integration test and change stored image name from 'hello' to 'hello2' in test/test.nonci.node.ts.
|
||||||
|
- Bump dependency @push.rocks/smartrequest from ^4.3.0 to ^4.3.1.
|
||||||
|
- Add .claude/settings.local.json to allow local agent permissions for running tests and related tooling.
|
||||||
|
|
||||||
|
## 2025-08-19 - 1.3.3 - fix(classes.host)
|
||||||
|
|
||||||
|
Adjust requestStreaming timeout and autoDrain; stabilize tests
|
||||||
|
|
||||||
|
- Reduced requestStreaming timeout from 10 minutes to 30 seconds to avoid long-running hanging requests.
|
||||||
|
- Enabled autoDrain for streaming requests to ensure response streams are properly drained and reduce resource issues.
|
||||||
|
- Marked the DockerImageStore S3 integration test as skipped to avoid CI dependence on external S3 and added a cleanup test to stop the test DockerHost.
|
||||||
|
- Added local tool settings file (.claude/settings.local.json) with local permissions (development-only).
|
||||||
|
|
||||||
## 2025-08-18 - 1.3.2 - fix(package.json)
|
## 2025-08-18 - 1.3.2 - fix(package.json)
|
||||||
|
|
||||||
Fix test script timeout typo, update dependency versions, and add typings & project configs
|
Fix test script timeout typo, update dependency versions, and add typings & project configs
|
||||||
|
|
||||||
- Fix test script: correct 'tineout' -> 'timeout' for npm test command and set timeout to 120s
|
- Fix test script: correct 'tineout' -> 'timeout' for npm test command and set timeout to 120s
|
||||||
@@ -10,6 +40,7 @@ Fix test script timeout typo, update dependency versions, and add typings & proj
|
|||||||
- Include generated cache/metadata files (typescript document symbols cache) — not source changes but tooling/cache artifacts
|
- Include generated cache/metadata files (typescript document symbols cache) — not source changes but tooling/cache artifacts
|
||||||
|
|
||||||
## 2025-08-18 - 1.3.1 - fix(test)
|
## 2025-08-18 - 1.3.1 - fix(test)
|
||||||
|
|
||||||
Update test setup and devDependencies; adjust test import and add package metadata
|
Update test setup and devDependencies; adjust test import and add package metadata
|
||||||
|
|
||||||
- Update test script to run with additional flags: --verbose, --logfile and --tineout 120
|
- Update test script to run with additional flags: --verbose, --logfile and --tineout 120
|
||||||
@@ -19,26 +50,29 @@ Update test setup and devDependencies; adjust test import and add package metada
|
|||||||
- Add packageManager field for pnpm@10.14.0 with integrity hash
|
- Add packageManager field for pnpm@10.14.0 with integrity hash
|
||||||
|
|
||||||
## 2024-12-23 - 1.3.0 - feat(core)
|
## 2024-12-23 - 1.3.0 - feat(core)
|
||||||
|
|
||||||
Initial release of Docker client with TypeScript support
|
Initial release of Docker client with TypeScript support
|
||||||
|
|
||||||
- Provides easy communication with Docker's remote API from Node.js
|
- Provides easy communication with Docker's remote API from Node.js
|
||||||
- Includes implementations for managing Docker services, networks, secrets, containers, and images
|
- Includes implementations for managing Docker services, networks, secrets, containers, and images
|
||||||
|
|
||||||
## 2024-12-23 - 1.2.8 - fix(core)
|
## 2024-12-23 - 1.2.8 - fix(core)
|
||||||
|
|
||||||
Improved the image creation process from tar stream in DockerImage class.
|
Improved the image creation process from tar stream in DockerImage class.
|
||||||
|
|
||||||
- Enhanced `DockerImage.createFromTarStream` method to handle streamed response and parse imported image details.
|
- Enhanced `DockerImage.createFromTarStream` method to handle streamed response and parse imported image details.
|
||||||
- Fixed the dependency version for `@push.rocks/smartarchive` in package.json.
|
- Fixed the dependency version for `@push.rocks/smartarchive` in package.json.
|
||||||
|
|
||||||
## 2024-10-13 - 1.2.7 - fix(core)
|
## 2024-10-13 - 1.2.7 - fix(core)
|
||||||
|
|
||||||
Prepare patch release with minor fixes and improvements
|
Prepare patch release with minor fixes and improvements
|
||||||
|
|
||||||
|
|
||||||
## 2024-10-13 - 1.2.6 - fix(core)
|
## 2024-10-13 - 1.2.6 - fix(core)
|
||||||
|
|
||||||
Minor refactoring and code quality improvements.
|
Minor refactoring and code quality improvements.
|
||||||
|
|
||||||
|
|
||||||
## 2024-10-13 - 1.2.5 - fix(dependencies)
|
## 2024-10-13 - 1.2.5 - fix(dependencies)
|
||||||
|
|
||||||
Update dependencies for stability improvements
|
Update dependencies for stability improvements
|
||||||
|
|
||||||
- Updated @push.rocks/smartstream to version ^3.0.46
|
- Updated @push.rocks/smartstream to version ^3.0.46
|
||||||
@@ -46,129 +80,152 @@ Update dependencies for stability improvements
|
|||||||
- Updated @types/node to version 22.7.5
|
- Updated @types/node to version 22.7.5
|
||||||
|
|
||||||
## 2024-10-13 - 1.2.4 - fix(core)
|
## 2024-10-13 - 1.2.4 - fix(core)
|
||||||
|
|
||||||
Refactored DockerImageStore constructor to remove DockerHost dependency
|
Refactored DockerImageStore constructor to remove DockerHost dependency
|
||||||
|
|
||||||
- Adjusted DockerImageStore constructor to remove dependency on DockerHost
|
- Adjusted DockerImageStore constructor to remove dependency on DockerHost
|
||||||
- Updated ts/classes.host.ts to align with DockerImageStore's new constructor signature
|
- Updated ts/classes.host.ts to align with DockerImageStore's new constructor signature
|
||||||
|
|
||||||
## 2024-08-21 - 1.2.3 - fix(dependencies)
|
## 2024-08-21 - 1.2.3 - fix(dependencies)
|
||||||
|
|
||||||
Update dependencies to the latest versions and fix image export test
|
Update dependencies to the latest versions and fix image export test
|
||||||
|
|
||||||
- Updated several dependencies to their latest versions in package.json.
|
- Updated several dependencies to their latest versions in package.json.
|
||||||
- Enabled the previously skipped 'should export images' test.
|
- Enabled the previously skipped 'should export images' test.
|
||||||
|
|
||||||
## 2024-06-10 - 1.2.1-1.2.2 - Core/General
|
## 2024-06-10 - 1.2.1-1.2.2 - Core/General
|
||||||
|
|
||||||
General updates and fixes.
|
General updates and fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2024-06-10 - 1.2.0 - Core
|
## 2024-06-10 - 1.2.0 - Core
|
||||||
|
|
||||||
Core updates and bug fixes.
|
Core updates and bug fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2024-06-08 - 1.2.0 - General/Core
|
## 2024-06-08 - 1.2.0 - General/Core
|
||||||
|
|
||||||
Major release with core enhancements.
|
Major release with core enhancements.
|
||||||
|
|
||||||
- Processing images with extraction, retagging, repackaging, and long-term storage
|
- Processing images with extraction, retagging, repackaging, and long-term storage
|
||||||
|
|
||||||
## 2024-06-06 - 1.1.4 - General/Imagestore
|
## 2024-06-06 - 1.1.4 - General/Imagestore
|
||||||
|
|
||||||
Significant feature addition.
|
Significant feature addition.
|
||||||
|
|
||||||
- Add feature to process images with extraction, retagging, repackaging, and long-term storage
|
- Add feature to process images with extraction, retagging, repackaging, and long-term storage
|
||||||
|
|
||||||
## 2024-05-08 - 1.0.112 - Images
|
## 2024-05-08 - 1.0.112 - Images
|
||||||
|
|
||||||
Add new functionality for image handling.
|
Add new functionality for image handling.
|
||||||
|
|
||||||
- Can now import and export images
|
- Can now import and export images
|
||||||
- Start work on local 100% JS OCI image registry
|
- Start work on local 100% JS OCI image registry
|
||||||
|
|
||||||
## 2024-06-05 - 1.1.0-1.1.3 - Core
|
## 2024-06-05 - 1.1.0-1.1.3 - Core
|
||||||
|
|
||||||
Regular updates and fixes.
|
Regular updates and fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2024-02-02 - 1.0.105-1.0.110 - Core
|
## 2024-02-02 - 1.0.105-1.0.110 - Core
|
||||||
|
|
||||||
Routine core updates and fixes.
|
Routine core updates and fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2022-10-17 - 1.0.103-1.0.104 - Core
|
## 2022-10-17 - 1.0.103-1.0.104 - Core
|
||||||
|
|
||||||
Routine core updates.
|
Routine core updates.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2020-10-01 - 1.0.99-1.0.102 - Core
|
## 2020-10-01 - 1.0.99-1.0.102 - Core
|
||||||
|
|
||||||
Routine core updates.
|
Routine core updates.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-09-22 - 1.0.73-1.0.78 - Core
|
## 2019-09-22 - 1.0.73-1.0.78 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-09-13 - 1.0.60-1.0.72 - Core
|
## 2019-09-13 - 1.0.60-1.0.72 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-08-16 - 1.0.43-1.0.59 - Core
|
## 2019-08-16 - 1.0.43-1.0.59 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-08-15 - 1.0.37-1.0.42 - Core
|
## 2019-08-15 - 1.0.37-1.0.42 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-08-14 - 1.0.31-1.0.36 - Core
|
## 2019-08-14 - 1.0.31-1.0.36 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2019-01-10 - 1.0.27-1.0.30 - Core
|
## 2019-01-10 - 1.0.27-1.0.30 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core update
|
- Fix core update
|
||||||
|
|
||||||
## 2018-07-16 - 1.0.23-1.0.24 - Core
|
## 2018-07-16 - 1.0.23-1.0.24 - Core
|
||||||
|
|
||||||
Routine updates and core fixes.
|
Routine updates and core fixes.
|
||||||
|
|
||||||
- Fix core shift to new style
|
- Fix core shift to new style
|
||||||
|
|
||||||
## 2017-07-16 - 1.0.20-1.0.22 - General
|
## 2017-07-16 - 1.0.20-1.0.22 - General
|
||||||
|
|
||||||
Routine updates and fixes.
|
Routine updates and fixes.
|
||||||
|
|
||||||
- Update node_modules within npmdocker
|
- Update node_modules within npmdocker
|
||||||
|
|
||||||
## 2017-04-02 - 1.0.18-1.0.19 - General
|
## 2017-04-02 - 1.0.18-1.0.19 - General
|
||||||
|
|
||||||
Routine updates and fixes.
|
Routine updates and fixes.
|
||||||
|
|
||||||
- Work with npmdocker and npmts 7.x.x
|
- Work with npmdocker and npmts 7.x.x
|
||||||
- CI updates
|
- CI updates
|
||||||
|
|
||||||
## 2016-07-31 - 1.0.17 - General
|
## 2016-07-31 - 1.0.17 - General
|
||||||
|
|
||||||
Enhancements and fixes.
|
Enhancements and fixes.
|
||||||
|
|
||||||
- Now waiting for response to be stored before ending streaming request
|
- Now waiting for response to be stored before ending streaming request
|
||||||
- Cosmetic fix
|
- Cosmetic fix
|
||||||
|
|
||||||
## 2016-07-29 - 1.0.14-1.0.16 - General
|
## 2016-07-29 - 1.0.14-1.0.16 - General
|
||||||
|
|
||||||
Multiple updates and features added.
|
Multiple updates and features added.
|
||||||
|
|
||||||
- Fix request for change observable and add npmdocker
|
- Fix request for change observable and add npmdocker
|
||||||
- Add request typings
|
- Add request typings
|
||||||
|
|
||||||
## 2016-07-28 - 1.0.13 - Core
|
## 2016-07-28 - 1.0.13 - Core
|
||||||
|
|
||||||
Fixes and preparations.
|
Fixes and preparations.
|
||||||
|
|
||||||
- Fixed request for newer docker
|
- Fixed request for newer docker
|
||||||
- Prepare for npmdocker
|
- Prepare for npmdocker
|
||||||
|
|
||||||
|
|
||||||
## 2016-06-16 - 1.0.0-1.0.2 - General
|
## 2016-06-16 - 1.0.0-1.0.2 - General
|
||||||
|
|
||||||
Initial sequence of releases, significant feature additions and CI setups.
|
Initial sequence of releases, significant feature additions and CI setups.
|
||||||
|
|
||||||
- Implement container start and stop
|
- Implement container start and stop
|
||||||
@@ -176,7 +233,7 @@ Initial sequence of releases, significant feature additions and CI setups.
|
|||||||
- Add tests with in docker environment
|
- Add tests with in docker environment
|
||||||
|
|
||||||
## 2016-04-12 - unknown - Initial Commit
|
## 2016-04-12 - unknown - Initial Commit
|
||||||
|
|
||||||
Initial project setup.
|
Initial project setup.
|
||||||
|
|
||||||
- Initial commit
|
- Initial commit
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"npmdocker": {
|
"npmdocker": {
|
||||||
"baseImage": "hosttoday/ht-docker-node:npmci",
|
"baseImage": "host.today/ht-docker-node:npmci",
|
||||||
"command": "(ls -a && rm -r node_modules && yarn global add npmts && yarn install && npmts)",
|
"command": "(ls -a && rm -r node_modules && yarn global add npmts && yarn install && npmts)",
|
||||||
"dockerSock": true
|
"dockerSock": true
|
||||||
},
|
},
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
"gitzone": {
|
"gitzone": {
|
||||||
"projectType": "npm",
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "code.foss.global",
|
||||||
"gitscope": "mojoio",
|
"gitscope": "apiclient.xyz",
|
||||||
"gitrepo": "docker",
|
"gitrepo": "docker",
|
||||||
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
||||||
"npmPackagename": "@mojoio/docker",
|
"npmPackagename": "@apiclient.xyz/docker",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Docker",
|
"Docker",
|
||||||
|
23
package.json
23
package.json
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "@apiclient.xyz/docker",
|
"name": "@apiclient.xyz/docker",
|
||||||
"version": "1.3.2",
|
"version": "1.3.5",
|
||||||
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
"description": "Provides easy communication with Docker remote API from Node.js, with TypeScript support.",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(tstest test/ --verbose --logfile --timeout 120)",
|
"test": "(tstest test/ --verbose --logfile --timeout 600)",
|
||||||
"build": "(tsbuild --web --allowimplicitany)",
|
"build": "(tsbuild --web --allowimplicitany)",
|
||||||
"buildDocs": "tsdoc"
|
"buildDocs": "tsdoc"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://gitlab.com/mojoio/docker.git"
|
"url": "https://code.foss.global/apiclient.xyz/docker.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Docker",
|
"Docker",
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitlab.com/mojoio/docker/issues"
|
"url": "https://code.foss.global/apiclient.xyz/docker/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/mojoio/docker#readme",
|
"homepage": "https://code.foss.global/apiclient.xyz/docker#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/lik": "^6.2.2",
|
"@push.rocks/lik": "^6.2.2",
|
||||||
"@push.rocks/smartarchive": "^4.2.2",
|
"@push.rocks/smartarchive": "^4.2.2",
|
||||||
@@ -39,15 +39,15 @@
|
|||||||
"@push.rocks/smartfile": "^11.2.7",
|
"@push.rocks/smartfile": "^11.2.7",
|
||||||
"@push.rocks/smartjson": "^5.0.20",
|
"@push.rocks/smartjson": "^5.0.20",
|
||||||
"@push.rocks/smartlog": "^3.1.8",
|
"@push.rocks/smartlog": "^3.1.8",
|
||||||
"@push.rocks/smartnetwork": "^3.0.0",
|
"@push.rocks/smartnetwork": "^4.1.2",
|
||||||
"@push.rocks/smartpath": "^5.0.18",
|
"@push.rocks/smartpath": "^6.0.0",
|
||||||
"@push.rocks/smartpromise": "^4.2.3",
|
"@push.rocks/smartpromise": "^4.2.3",
|
||||||
"@push.rocks/smartrequest": "^2.0.22",
|
"@push.rocks/smartrequest": "^4.3.1",
|
||||||
"@push.rocks/smartstream": "^3.2.5",
|
"@push.rocks/smartstream": "^3.2.5",
|
||||||
"@push.rocks/smartstring": "^4.0.15",
|
"@push.rocks/smartstring": "^4.0.15",
|
||||||
"@push.rocks/smartunique": "^3.0.9",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"@push.rocks/smartversion": "^3.0.5",
|
"@push.rocks/smartversion": "^3.0.5",
|
||||||
"@tsclass/tsclass": "^4.1.2",
|
"@tsclass/tsclass": "^9.2.0",
|
||||||
"rxjs": "^7.8.2"
|
"rxjs": "^7.8.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -72,5 +72,8 @@
|
|||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 1 chrome versions"
|
"last 1 chrome versions"
|
||||||
],
|
],
|
||||||
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748"
|
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
172
pnpm-lock.yaml
generated
172
pnpm-lock.yaml
generated
@@ -27,17 +27,17 @@ importers:
|
|||||||
specifier: ^3.1.8
|
specifier: ^3.1.8
|
||||||
version: 3.1.8
|
version: 3.1.8
|
||||||
'@push.rocks/smartnetwork':
|
'@push.rocks/smartnetwork':
|
||||||
specifier: ^3.0.0
|
specifier: ^4.1.2
|
||||||
version: 3.0.2
|
version: 4.1.2
|
||||||
'@push.rocks/smartpath':
|
'@push.rocks/smartpath':
|
||||||
specifier: ^5.0.18
|
specifier: ^6.0.0
|
||||||
version: 5.0.18
|
version: 6.0.0
|
||||||
'@push.rocks/smartpromise':
|
'@push.rocks/smartpromise':
|
||||||
specifier: ^4.2.3
|
specifier: ^4.2.3
|
||||||
version: 4.2.3
|
version: 4.2.3
|
||||||
'@push.rocks/smartrequest':
|
'@push.rocks/smartrequest':
|
||||||
specifier: ^2.0.22
|
specifier: ^4.3.1
|
||||||
version: 2.0.22
|
version: 4.3.1
|
||||||
'@push.rocks/smartstream':
|
'@push.rocks/smartstream':
|
||||||
specifier: ^3.2.5
|
specifier: ^3.2.5
|
||||||
version: 3.2.5
|
version: 3.2.5
|
||||||
@@ -51,8 +51,8 @@ importers:
|
|||||||
specifier: ^3.0.5
|
specifier: ^3.0.5
|
||||||
version: 3.0.5
|
version: 3.0.5
|
||||||
'@tsclass/tsclass':
|
'@tsclass/tsclass':
|
||||||
specifier: ^4.1.2
|
specifier: ^9.2.0
|
||||||
version: 4.1.2
|
version: 9.2.0
|
||||||
rxjs:
|
rxjs:
|
||||||
specifier: ^7.8.2
|
specifier: ^7.8.2
|
||||||
version: 7.8.2
|
version: 7.8.2
|
||||||
@@ -679,9 +679,6 @@ packages:
|
|||||||
'@push.rocks/smartmongo@2.0.12':
|
'@push.rocks/smartmongo@2.0.12':
|
||||||
resolution: {integrity: sha512-NglYiO14BikxnlvW6JF18FtopBtaWQEGAtPxHmmSCbyhU8Mi0aEFO7VgCasE9Kguba/wcR597qhcDEdcpBg1eQ==}
|
resolution: {integrity: sha512-NglYiO14BikxnlvW6JF18FtopBtaWQEGAtPxHmmSCbyhU8Mi0aEFO7VgCasE9Kguba/wcR597qhcDEdcpBg1eQ==}
|
||||||
|
|
||||||
'@push.rocks/smartnetwork@3.0.2':
|
|
||||||
resolution: {integrity: sha512-s6CNGzQ1n/d/6cOKXbxeW6/tO//dr1woLqI01g7XhqTriw0nsm2G2kWaZh2J0VOguGNWBgQVCIpR0LjdRNWb3g==}
|
|
||||||
|
|
||||||
'@push.rocks/smartnetwork@4.1.2':
|
'@push.rocks/smartnetwork@4.1.2':
|
||||||
resolution: {integrity: sha512-TjucG72ooHgzAUpNu2LAv4iFoettmZq2aEWhhzIa7AKcOvt4yxsk3Vl73guhKRohTfhdRauPcH5OHISLUHJbYA==}
|
resolution: {integrity: sha512-TjucG72ooHgzAUpNu2LAv4iFoettmZq2aEWhhzIa7AKcOvt4yxsk3Vl73guhKRohTfhdRauPcH5OHISLUHJbYA==}
|
||||||
|
|
||||||
@@ -697,8 +694,8 @@ packages:
|
|||||||
'@push.rocks/smartopen@2.0.0':
|
'@push.rocks/smartopen@2.0.0':
|
||||||
resolution: {integrity: sha512-eVT0GhtQ2drb95j/kktYst/Toh1zCwCqjTJFYtaYFUnnBnBUajPtBZDFnPQo01DN8JxoeCTo8jggq+PCvzcfww==}
|
resolution: {integrity: sha512-eVT0GhtQ2drb95j/kktYst/Toh1zCwCqjTJFYtaYFUnnBnBUajPtBZDFnPQo01DN8JxoeCTo8jggq+PCvzcfww==}
|
||||||
|
|
||||||
'@push.rocks/smartpath@5.0.18':
|
'@push.rocks/smartpath@5.1.0':
|
||||||
resolution: {integrity: sha512-kIyRTlOoeEth5b4Qp8KPUxNOGNdvhb2aD0hbHfF3oGTQ0xnDdgB1l03/4bIoapHG48OrTgh4uQ5tUorykgdOzw==}
|
resolution: {integrity: sha512-pJ4UGATHV/C6Dw5DU0D3MJaPMASlKAgeS+Hl9dkhD2ceYArn86Ky3Z/g7LNj40Oz6cUe77/AP1chztmJZISrpw==}
|
||||||
|
|
||||||
'@push.rocks/smartpath@6.0.0':
|
'@push.rocks/smartpath@6.0.0':
|
||||||
resolution: {integrity: sha512-r94u1MbBaIOSy+517PZp2P7SuZPSe9LkwJ8l3dXQKHeIOri/zDxk/RQPiFM+j4N9301ztkRyhvRj7xgUDroOsg==}
|
resolution: {integrity: sha512-r94u1MbBaIOSy+517PZp2P7SuZPSe9LkwJ8l3dXQKHeIOri/zDxk/RQPiFM+j4N9301ztkRyhvRj7xgUDroOsg==}
|
||||||
@@ -715,11 +712,11 @@ packages:
|
|||||||
'@push.rocks/smartpuppeteer@2.0.5':
|
'@push.rocks/smartpuppeteer@2.0.5':
|
||||||
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
|
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
|
||||||
|
|
||||||
'@push.rocks/smartrequest@2.0.22':
|
'@push.rocks/smartrequest@2.1.0':
|
||||||
resolution: {integrity: sha512-EfgmdEsLtDJ8aNOLOh59ca1NMsiiFz54aoHRigQFQ0cuoUs6phxejIY2FdMoPFn68ubTpkztdL2P4L1/cRYyHg==}
|
resolution: {integrity: sha512-3eHLTRInHA+u+W98TqJwgTES7rRimBAsJC4JxVNQC3UUezmblAhM5/TIQsEBQTsbjAY8SeQKy6NHzW6iTiaD8w==}
|
||||||
|
|
||||||
'@push.rocks/smartrequest@4.2.2':
|
'@push.rocks/smartrequest@4.3.1':
|
||||||
resolution: {integrity: sha512-OMtSyxvuOw04nRR/97yAF3XLe42QDyuwStQMo2bXrVvXgcriNyn0JFavl0IL5hY6Gb+dyCWgOAUwX7cVZ4DzZg==}
|
resolution: {integrity: sha512-H5FQSfFEbSJCHpE2A+SasQQcxM5FlxhHIUEzhUsSLjtlCTEu9T7Xb1WzVLFYvdWfyP5VIrg+XM4AMOols8cG+Q==}
|
||||||
|
|
||||||
'@push.rocks/smartrouter@1.3.3':
|
'@push.rocks/smartrouter@1.3.3':
|
||||||
resolution: {integrity: sha512-1+xZEnWlhzqLWAaJ1zFNhQ0zgbfCWQl1DBT72LygLxTs+P0K8AwJKgqo/IX6CT55kGCFnPAZIYSbVJlGsgrB0w==}
|
resolution: {integrity: sha512-1+xZEnWlhzqLWAaJ1zFNhQ0zgbfCWQl1DBT72LygLxTs+P0K8AwJKgqo/IX6CT55kGCFnPAZIYSbVJlGsgrB0w==}
|
||||||
@@ -757,9 +754,6 @@ packages:
|
|||||||
'@push.rocks/smartunique@3.0.9':
|
'@push.rocks/smartunique@3.0.9':
|
||||||
resolution: {integrity: sha512-q6DYQgT7/dqdWi9HusvtWCjdsFzLFXY9LTtaZV6IYNJt6teZOonoygxTdNt9XLn6niBSbLYrHSKvJNTRH/uK+g==}
|
resolution: {integrity: sha512-q6DYQgT7/dqdWi9HusvtWCjdsFzLFXY9LTtaZV6IYNJt6teZOonoygxTdNt9XLn6niBSbLYrHSKvJNTRH/uK+g==}
|
||||||
|
|
||||||
'@push.rocks/smarturl@3.0.7':
|
|
||||||
resolution: {integrity: sha512-nx4EWjQD9JeO7QVbOsxd1PFeDQYoSQOOOYCZ+r7QWXHLJG52iYzgvJDCQyX6p705HDkYMJWozW2ZzhR22qLKbw==}
|
|
||||||
|
|
||||||
'@push.rocks/smarturl@3.1.0':
|
'@push.rocks/smarturl@3.1.0':
|
||||||
resolution: {integrity: sha512-ij73Q4GERojdPSHxAvYKvspimcpAJC6GGQCWsC4b+1sAiOSByjfmkUHK8yiEEOPRU9AeGuyaIVqK6ZzKLEZ3vA==}
|
resolution: {integrity: sha512-ij73Q4GERojdPSHxAvYKvspimcpAJC6GGQCWsC4b+1sAiOSByjfmkUHK8yiEEOPRU9AeGuyaIVqK6ZzKLEZ3vA==}
|
||||||
|
|
||||||
@@ -823,10 +817,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-PLvBNVeuY9BERNLq3PFDkhnHHc0RpilEGHd4aUI5XRFlZF++LETdLxPbxw+DHbvHlkUf/nep09f7rrL9Tqub1Q==}
|
resolution: {integrity: sha512-PLvBNVeuY9BERNLq3PFDkhnHHc0RpilEGHd4aUI5XRFlZF++LETdLxPbxw+DHbvHlkUf/nep09f7rrL9Tqub1Q==}
|
||||||
deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartmatch
|
deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartmatch
|
||||||
|
|
||||||
'@pushrocks/smartping@1.0.8':
|
|
||||||
resolution: {integrity: sha512-VM2gfS1sTuycj/jHyDa0lDntkPe7/JT0b2kGsy265RkichAJZkoEp3fboRJH/WAdzM8T4Du64JYgZkc8v2HHQg==}
|
|
||||||
deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartping
|
|
||||||
|
|
||||||
'@pushrocks/smartpromise@3.1.10':
|
'@pushrocks/smartpromise@3.1.10':
|
||||||
resolution: {integrity: sha512-VeTurbZ1+ZMxBDJk1Y1LV8SN9xLI+oDXKVeCFw41FAGEKOUEqordqFpi6t+7Vhe/TXUZzCVpZ5bXxAxrGf8yTQ==}
|
resolution: {integrity: sha512-VeTurbZ1+ZMxBDJk1Y1LV8SN9xLI+oDXKVeCFw41FAGEKOUEqordqFpi6t+7Vhe/TXUZzCVpZ5bXxAxrGf8yTQ==}
|
||||||
deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartpromise
|
deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartpromise
|
||||||
@@ -1227,8 +1217,8 @@ packages:
|
|||||||
'@tsclass/tsclass@3.0.48':
|
'@tsclass/tsclass@3.0.48':
|
||||||
resolution: {integrity: sha512-hC65UvDlp9qvsl6OcIZXz0JNiWZ0gyzsTzbXpg215sGxopgbkOLCr6E0s4qCTnweYm95gt2AdY95uP7M7kExaQ==}
|
resolution: {integrity: sha512-hC65UvDlp9qvsl6OcIZXz0JNiWZ0gyzsTzbXpg215sGxopgbkOLCr6E0s4qCTnweYm95gt2AdY95uP7M7kExaQ==}
|
||||||
|
|
||||||
'@tsclass/tsclass@4.1.2':
|
'@tsclass/tsclass@4.4.4':
|
||||||
resolution: {integrity: sha512-uMg1IcTU1cP0McXYGwGffoU3asNQHle7bTN0tn6kVXzfNzSwQf4o8v+YQ4VRnUzo4ov6VKcPXqg5OLb2vz977g==}
|
resolution: {integrity: sha512-YZOAF+u+r4u5rCev2uUd1KBTBdfyFdtDmcv4wuN+864lMccbdfRICR3SlJwCfYS1lbeV3QNLYGD30wjRXgvCJA==}
|
||||||
|
|
||||||
'@tsclass/tsclass@9.2.0':
|
'@tsclass/tsclass@9.2.0':
|
||||||
resolution: {integrity: sha512-A6ULEkQfYgOnCKQVQRt26O7PRzFo4PE2EoD25RAtnuFuVrNwGynYC20Vee2c8KAOyI7nQ/LaREki9KAX4AHOHQ==}
|
resolution: {integrity: sha512-A6ULEkQfYgOnCKQVQRt26O7PRzFo4PE2EoD25RAtnuFuVrNwGynYC20Vee2c8KAOyI7nQ/LaREki9KAX4AHOHQ==}
|
||||||
@@ -1254,9 +1244,6 @@ packages:
|
|||||||
'@types/debug@4.1.12':
|
'@types/debug@4.1.12':
|
||||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||||
|
|
||||||
'@types/default-gateway@3.0.1':
|
|
||||||
resolution: {integrity: sha512-tpu0hp+AOIzwdAHyZPzLE5pCf9uT0pb+xZ76T4S7MrY2YTVq918Q7Q2VQ3KCVQqYxM7nxuCK/SL3X97jBEIeKQ==}
|
|
||||||
|
|
||||||
'@types/default-gateway@7.2.2':
|
'@types/default-gateway@7.2.2':
|
||||||
resolution: {integrity: sha512-35C93fYQlnLKLASkMPoxRvok4fENwB3By9clRLd2I/08n/XRl0pCdf7EB17K5oMMwZu8NBYA8i66jH5r/LYBKA==}
|
resolution: {integrity: sha512-35C93fYQlnLKLASkMPoxRvok4fENwB3By9clRLd2I/08n/XRl0pCdf7EB17K5oMMwZu8NBYA8i66jH5r/LYBKA==}
|
||||||
|
|
||||||
@@ -1403,10 +1390,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
||||||
engines: {node: '>= 8.0.0'}
|
engines: {node: '>= 8.0.0'}
|
||||||
|
|
||||||
aggregate-error@4.0.1:
|
|
||||||
resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
ansi-256-colors@1.1.0:
|
ansi-256-colors@1.1.0:
|
||||||
resolution: {integrity: sha1-kQ3lDvzHwJ49gvL4er1rcAwYgYo=}
|
resolution: {integrity: sha1-kQ3lDvzHwJ49gvL4er1rcAwYgYo=}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1609,10 +1592,6 @@ packages:
|
|||||||
resolution: {integrity: sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=}
|
resolution: {integrity: sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
clean-stack@4.2.0:
|
|
||||||
resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
cliui@8.0.1:
|
cliui@8.0.1:
|
||||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -2063,10 +2042,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
|
resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
|
||||||
engines: {node: '>= 14.17'}
|
engines: {node: '>= 14.17'}
|
||||||
|
|
||||||
form-data@4.0.0:
|
|
||||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
|
||||||
engines: {node: '>= 6'}
|
|
||||||
|
|
||||||
form-data@4.0.4:
|
form-data@4.0.4:
|
||||||
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
|
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -2270,10 +2245,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
|
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
indent-string@5.0.0:
|
|
||||||
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
inflight@1.0.6:
|
inflight@1.0.6:
|
||||||
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
|
resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
|
||||||
|
|
||||||
@@ -2314,10 +2285,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
|
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-ip@4.0.0:
|
|
||||||
resolution: {integrity: sha512-4B4XA2HEIm/PY+OSpeMBXr8pGWBYbXuHgjMAqrwbLO3CPTCAd9ArEJzBUKGZtk9viY6+aSfadGnWyjY3ydYZkw==}
|
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
|
||||||
|
|
||||||
is-ip@5.0.1:
|
is-ip@5.0.1:
|
||||||
resolution: {integrity: sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==}
|
resolution: {integrity: sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
@@ -3023,10 +2990,6 @@ packages:
|
|||||||
proxy-from-env@1.1.0:
|
proxy-from-env@1.1.0:
|
||||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
|
||||||
public-ip@6.0.2:
|
|
||||||
resolution: {integrity: sha512-+6bkjnf0yQ4+tZV0zJv1017DiIF7y6R4yg17Mrhhkc25L7dtQtXWHgSCrz9BbLL4OeTFbPK4EALXqJUrwCIWXw==}
|
|
||||||
engines: {node: '>=14.16'}
|
|
||||||
|
|
||||||
public-ip@7.0.1:
|
public-ip@7.0.1:
|
||||||
resolution: {integrity: sha512-DdNcqcIbI0wEeCBcqX+bmZpUCvrDMJHXE553zgyG1MZ8S1a/iCCxmK9iTjjql+SpHSv4cZkmRv5/zGYW93AlCw==}
|
resolution: {integrity: sha512-DdNcqcIbI0wEeCBcqX+bmZpUCvrDMJHXE553zgyG1MZ8S1a/iCCxmK9iTjjql+SpHSv4cZkmRv5/zGYW93AlCw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -3369,12 +3332,6 @@ packages:
|
|||||||
symbol-tree@3.2.4:
|
symbol-tree@3.2.4:
|
||||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||||
|
|
||||||
systeminformation@5.22.8:
|
|
||||||
resolution: {integrity: sha512-F1iWQ+PSfOzvLMGh2UXASaWLDq5o+1h1db13Kddl6ojcQ47rsJhpMtRrmBXfTA5QJgutC4KV67YRmXLuroIxrA==}
|
|
||||||
engines: {node: '>=8.0.0'}
|
|
||||||
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
systeminformation@5.27.7:
|
systeminformation@5.27.7:
|
||||||
resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==}
|
resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
@@ -3460,10 +3417,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
|
|
||||||
type-fest@4.25.0:
|
|
||||||
resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==}
|
|
||||||
engines: {node: '>=16'}
|
|
||||||
|
|
||||||
type-fest@4.41.0:
|
type-fest@4.41.0:
|
||||||
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
@@ -3713,7 +3666,7 @@ snapshots:
|
|||||||
'@push.rocks/smartopen': 2.0.0
|
'@push.rocks/smartopen': 2.0.0
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
'@push.rocks/smartsitemap': 2.0.3
|
'@push.rocks/smartsitemap': 2.0.3
|
||||||
'@push.rocks/smartstream': 3.2.5
|
'@push.rocks/smartstream': 3.2.5
|
||||||
@@ -4410,7 +4363,7 @@ snapshots:
|
|||||||
'@push.rocks/smartfile': 11.2.7
|
'@push.rocks/smartfile': 11.2.7
|
||||||
'@push.rocks/smartlog': 3.1.8
|
'@push.rocks/smartlog': 3.1.8
|
||||||
'@push.rocks/smartlog-destination-local': 9.0.2
|
'@push.rocks/smartlog-destination-local': 9.0.2
|
||||||
'@push.rocks/smartpath': 5.0.18
|
'@push.rocks/smartpath': 5.1.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartspawn': 3.0.3
|
'@push.rocks/smartspawn': 3.0.3
|
||||||
'@rspack/core': 1.4.11
|
'@rspack/core': 1.4.11
|
||||||
@@ -4432,7 +4385,7 @@ snapshots:
|
|||||||
'@push.rocks/smartlog': 3.1.8
|
'@push.rocks/smartlog': 3.1.8
|
||||||
'@push.rocks/smartnpm': 2.0.6
|
'@push.rocks/smartnpm': 2.0.6
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smartshell': 3.3.0
|
'@push.rocks/smartshell': 3.3.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- aws-crt
|
- aws-crt
|
||||||
@@ -4463,7 +4416,7 @@ snapshots:
|
|||||||
'@push.rocks/smartmongo': 2.0.12(socks@2.8.7)
|
'@push.rocks/smartmongo': 2.0.12(socks@2.8.7)
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smarts3': 2.2.6
|
'@push.rocks/smarts3': 2.2.6
|
||||||
'@push.rocks/smartshell': 3.3.0
|
'@push.rocks/smartshell': 3.3.0
|
||||||
'@push.rocks/smarttime': 4.1.1
|
'@push.rocks/smarttime': 4.1.1
|
||||||
@@ -4643,12 +4596,12 @@ snapshots:
|
|||||||
'@push.rocks/smartexit': 1.0.23
|
'@push.rocks/smartexit': 1.0.23
|
||||||
'@push.rocks/smartfile': 11.2.7
|
'@push.rocks/smartfile': 11.2.7
|
||||||
'@push.rocks/smartjson': 5.0.20
|
'@push.rocks/smartjson': 5.0.20
|
||||||
'@push.rocks/smartpath': 5.0.18
|
'@push.rocks/smartpath': 5.1.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartstring': 4.0.15
|
'@push.rocks/smartstring': 4.0.15
|
||||||
'@push.rocks/smartunique': 3.0.9
|
'@push.rocks/smartunique': 3.0.9
|
||||||
'@push.rocks/taskbuffer': 3.1.7
|
'@push.rocks/taskbuffer': 3.1.7
|
||||||
'@tsclass/tsclass': 4.1.2
|
'@tsclass/tsclass': 4.4.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- aws-crt
|
- aws-crt
|
||||||
|
|
||||||
@@ -4695,7 +4648,7 @@ snapshots:
|
|||||||
'@push.rocks/smartfile': 11.2.7
|
'@push.rocks/smartfile': 11.2.7
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
'@push.rocks/smartstream': 3.2.5
|
'@push.rocks/smartstream': 3.2.5
|
||||||
'@push.rocks/smartunique': 3.0.9
|
'@push.rocks/smartunique': 3.0.9
|
||||||
@@ -4846,7 +4799,7 @@ snapshots:
|
|||||||
'@push.rocks/smartmime': 2.0.4
|
'@push.rocks/smartmime': 2.0.4
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smartstream': 3.2.5
|
'@push.rocks/smartstream': 3.2.5
|
||||||
'@types/fs-extra': 11.0.4
|
'@types/fs-extra': 11.0.4
|
||||||
'@types/js-yaml': 4.0.9
|
'@types/js-yaml': 4.0.9
|
||||||
@@ -4857,7 +4810,7 @@ snapshots:
|
|||||||
'@push.rocks/smartguard@3.1.0':
|
'@push.rocks/smartguard@3.1.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 2.0.22
|
'@push.rocks/smartrequest': 2.1.0
|
||||||
|
|
||||||
'@push.rocks/smarthash@3.2.3':
|
'@push.rocks/smarthash@3.2.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4887,7 +4840,7 @@ snapshots:
|
|||||||
'@push.rocks/smartlog-interfaces@3.0.2':
|
'@push.rocks/smartlog-interfaces@3.0.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest-interfaces': 2.0.2
|
'@api.global/typedrequest-interfaces': 2.0.2
|
||||||
'@tsclass/tsclass': 4.1.2
|
'@tsclass/tsclass': 4.4.4
|
||||||
|
|
||||||
'@push.rocks/smartlog@3.1.8':
|
'@push.rocks/smartlog@3.1.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4933,7 +4886,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/mongodump': 1.1.0(socks@2.8.7)
|
'@push.rocks/mongodump': 1.1.0(socks@2.8.7)
|
||||||
'@push.rocks/smartdata': 5.16.4(socks@2.8.7)
|
'@push.rocks/smartdata': 5.16.4(socks@2.8.7)
|
||||||
'@push.rocks/smartpath': 5.0.18
|
'@push.rocks/smartpath': 5.1.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
mongodb-memory-server: 10.2.0(socks@2.8.7)
|
mongodb-memory-server: 10.2.0(socks@2.8.7)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -4946,16 +4899,6 @@ snapshots:
|
|||||||
- socks
|
- socks
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@push.rocks/smartnetwork@3.0.2':
|
|
||||||
dependencies:
|
|
||||||
'@pushrocks/smartping': 1.0.8
|
|
||||||
'@pushrocks/smartpromise': 3.1.10
|
|
||||||
'@pushrocks/smartstring': 4.0.7
|
|
||||||
'@types/default-gateway': 3.0.1
|
|
||||||
isopen: 1.3.0
|
|
||||||
public-ip: 6.0.2
|
|
||||||
systeminformation: 5.22.8
|
|
||||||
|
|
||||||
'@push.rocks/smartnetwork@4.1.2':
|
'@push.rocks/smartnetwork@4.1.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartping': 1.0.8
|
'@push.rocks/smartping': 1.0.8
|
||||||
@@ -4974,7 +4917,7 @@ snapshots:
|
|||||||
'@push.rocks/smartfile': 11.2.7
|
'@push.rocks/smartfile': 11.2.7
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 4.2.2
|
'@push.rocks/smartrequest': 4.3.1
|
||||||
'@push.rocks/smarttime': 4.1.1
|
'@push.rocks/smarttime': 4.1.1
|
||||||
'@push.rocks/smartversion': 3.0.5
|
'@push.rocks/smartversion': 3.0.5
|
||||||
package-json: 8.1.1
|
package-json: 8.1.1
|
||||||
@@ -5003,7 +4946,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
open: 8.4.2
|
open: 8.4.2
|
||||||
|
|
||||||
'@push.rocks/smartpath@5.0.18': {}
|
'@push.rocks/smartpath@5.1.0': {}
|
||||||
|
|
||||||
'@push.rocks/smartpath@6.0.0': {}
|
'@push.rocks/smartpath@6.0.0': {}
|
||||||
|
|
||||||
@@ -5049,14 +4992,14 @@ snapshots:
|
|||||||
- typescript
|
- typescript
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
'@push.rocks/smartrequest@2.0.22':
|
'@push.rocks/smartrequest@2.1.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smarturl': 3.0.7
|
'@push.rocks/smarturl': 3.1.0
|
||||||
agentkeepalive: 4.5.0
|
agentkeepalive: 4.5.0
|
||||||
form-data: 4.0.0
|
form-data: 4.0.4
|
||||||
|
|
||||||
'@push.rocks/smartrequest@4.2.2':
|
'@push.rocks/smartrequest@4.3.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartenv': 5.0.13
|
'@push.rocks/smartenv': 5.0.13
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
@@ -5104,7 +5047,7 @@ snapshots:
|
|||||||
'@push.rocks/smartxml': 1.1.1
|
'@push.rocks/smartxml': 1.1.1
|
||||||
'@push.rocks/smartyaml': 2.0.5
|
'@push.rocks/smartyaml': 2.0.5
|
||||||
'@push.rocks/webrequest': 3.0.37
|
'@push.rocks/webrequest': 3.0.37
|
||||||
'@tsclass/tsclass': 4.1.2
|
'@tsclass/tsclass': 4.4.4
|
||||||
|
|
||||||
'@push.rocks/smartsocket@2.1.0':
|
'@push.rocks/smartsocket@2.1.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5184,8 +5127,6 @@ snapshots:
|
|||||||
nanoid: 4.0.2
|
nanoid: 4.0.2
|
||||||
uuid: 9.0.1
|
uuid: 9.0.1
|
||||||
|
|
||||||
'@push.rocks/smarturl@3.0.7': {}
|
|
||||||
|
|
||||||
'@push.rocks/smarturl@3.1.0': {}
|
'@push.rocks/smarturl@3.1.0': {}
|
||||||
|
|
||||||
'@push.rocks/smartversion@3.0.5':
|
'@push.rocks/smartversion@3.0.5':
|
||||||
@@ -5225,7 +5166,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@pushrocks/smartdelay': 3.0.1
|
'@pushrocks/smartdelay': 3.0.1
|
||||||
'@pushrocks/smartpromise': 4.0.2
|
'@pushrocks/smartpromise': 4.0.2
|
||||||
'@tsclass/tsclass': 4.1.2
|
'@tsclass/tsclass': 4.4.4
|
||||||
|
|
||||||
'@push.rocks/webstore@2.0.20':
|
'@push.rocks/webstore@2.0.20':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5291,11 +5232,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
matcher: 5.0.0
|
matcher: 5.0.0
|
||||||
|
|
||||||
'@pushrocks/smartping@1.0.8':
|
|
||||||
dependencies:
|
|
||||||
'@types/ping': 0.4.4
|
|
||||||
ping: 0.4.4
|
|
||||||
|
|
||||||
'@pushrocks/smartpromise@3.1.10': {}
|
'@pushrocks/smartpromise@3.1.10': {}
|
||||||
|
|
||||||
'@pushrocks/smartpromise@4.0.2': {}
|
'@pushrocks/smartpromise@4.0.2': {}
|
||||||
@@ -5791,9 +5727,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
|
|
||||||
'@tsclass/tsclass@4.1.2':
|
'@tsclass/tsclass@4.4.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest: 4.25.0
|
type-fest: 4.41.0
|
||||||
|
|
||||||
'@tsclass/tsclass@9.2.0':
|
'@tsclass/tsclass@9.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5828,8 +5764,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 2.1.0
|
'@types/ms': 2.1.0
|
||||||
|
|
||||||
'@types/default-gateway@3.0.1': {}
|
|
||||||
|
|
||||||
'@types/default-gateway@7.2.2': {}
|
'@types/default-gateway@7.2.2': {}
|
||||||
|
|
||||||
'@types/express-serve-static-core@5.0.7':
|
'@types/express-serve-static-core@5.0.7':
|
||||||
@@ -5982,11 +5916,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
humanize-ms: 1.2.1
|
humanize-ms: 1.2.1
|
||||||
|
|
||||||
aggregate-error@4.0.1:
|
|
||||||
dependencies:
|
|
||||||
clean-stack: 4.2.0
|
|
||||||
indent-string: 5.0.0
|
|
||||||
|
|
||||||
ansi-256-colors@1.1.0: {}
|
ansi-256-colors@1.1.0: {}
|
||||||
|
|
||||||
ansi-regex@5.0.1: {}
|
ansi-regex@5.0.1: {}
|
||||||
@@ -6183,10 +6112,6 @@ snapshots:
|
|||||||
|
|
||||||
clean-stack@1.3.0: {}
|
clean-stack@1.3.0: {}
|
||||||
|
|
||||||
clean-stack@4.2.0:
|
|
||||||
dependencies:
|
|
||||||
escape-string-regexp: 5.0.0
|
|
||||||
|
|
||||||
cliui@8.0.1:
|
cliui@8.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
string-width: 4.2.3
|
string-width: 4.2.3
|
||||||
@@ -6658,12 +6583,6 @@ snapshots:
|
|||||||
|
|
||||||
form-data-encoder@2.1.4: {}
|
form-data-encoder@2.1.4: {}
|
||||||
|
|
||||||
form-data@4.0.0:
|
|
||||||
dependencies:
|
|
||||||
asynckit: 0.4.0
|
|
||||||
combined-stream: 1.0.8
|
|
||||||
mime-types: 2.1.35
|
|
||||||
|
|
||||||
form-data@4.0.4:
|
form-data@4.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
asynckit: 0.4.0
|
asynckit: 0.4.0
|
||||||
@@ -6931,8 +6850,6 @@ snapshots:
|
|||||||
parent-module: 1.0.1
|
parent-module: 1.0.1
|
||||||
resolve-from: 4.0.0
|
resolve-from: 4.0.0
|
||||||
|
|
||||||
indent-string@5.0.0: {}
|
|
||||||
|
|
||||||
inflight@1.0.6:
|
inflight@1.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
@@ -6963,10 +6880,6 @@ snapshots:
|
|||||||
has-tostringtag: 1.0.2
|
has-tostringtag: 1.0.2
|
||||||
safe-regex-test: 1.1.0
|
safe-regex-test: 1.1.0
|
||||||
|
|
||||||
is-ip@4.0.0:
|
|
||||||
dependencies:
|
|
||||||
ip-regex: 5.0.0
|
|
||||||
|
|
||||||
is-ip@5.0.1:
|
is-ip@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ip-regex: 5.0.0
|
ip-regex: 5.0.0
|
||||||
@@ -7830,13 +7743,6 @@ snapshots:
|
|||||||
|
|
||||||
proxy-from-env@1.1.0: {}
|
proxy-from-env@1.1.0: {}
|
||||||
|
|
||||||
public-ip@6.0.2:
|
|
||||||
dependencies:
|
|
||||||
aggregate-error: 4.0.1
|
|
||||||
dns-socket: 4.2.2
|
|
||||||
got: 12.6.1
|
|
||||||
is-ip: 4.0.0
|
|
||||||
|
|
||||||
public-ip@7.0.1:
|
public-ip@7.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
dns-socket: 4.2.2
|
dns-socket: 4.2.2
|
||||||
@@ -8310,8 +8216,6 @@ snapshots:
|
|||||||
|
|
||||||
symbol-tree@3.2.4: {}
|
symbol-tree@3.2.4: {}
|
||||||
|
|
||||||
systeminformation@5.22.8: {}
|
|
||||||
|
|
||||||
systeminformation@5.27.7: {}
|
systeminformation@5.27.7: {}
|
||||||
|
|
||||||
tar-fs@3.1.0:
|
tar-fs@3.1.0:
|
||||||
@@ -8402,8 +8306,6 @@ snapshots:
|
|||||||
|
|
||||||
type-fest@2.19.0: {}
|
type-fest@2.19.0: {}
|
||||||
|
|
||||||
type-fest@4.25.0: {}
|
|
||||||
|
|
||||||
type-fest@4.41.0: {}
|
type-fest@4.41.0: {}
|
||||||
|
|
||||||
type-is@1.6.18:
|
type-is@1.6.18:
|
||||||
|
123
readme.md
123
readme.md
@@ -38,7 +38,7 @@ const docker = new DockerHost();
|
|||||||
|
|
||||||
// Or connect to remote Docker host
|
// Or connect to remote Docker host
|
||||||
const remoteDocker = new DockerHost({
|
const remoteDocker = new DockerHost({
|
||||||
socketPath: 'tcp://remote-docker-host:2375'
|
socketPath: 'tcp://remote-docker-host:2375',
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -56,9 +56,9 @@ const docker = new DockerHost();
|
|||||||
|
|
||||||
// Custom initialization options
|
// Custom initialization options
|
||||||
const customDocker = new DockerHost({
|
const customDocker = new DockerHost({
|
||||||
socketPath: '/var/run/docker.sock', // Unix socket path
|
socketPath: '/var/run/docker.sock', // Unix socket path
|
||||||
// or
|
// or
|
||||||
socketPath: 'tcp://192.168.1.100:2375' // TCP connection
|
socketPath: 'tcp://192.168.1.100:2375', // TCP connection
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start and stop (for lifecycle management)
|
// Start and stop (for lifecycle management)
|
||||||
@@ -76,7 +76,7 @@ await docker.stop();
|
|||||||
const allContainers = await docker.getContainers();
|
const allContainers = await docker.getContainers();
|
||||||
|
|
||||||
// Each container includes detailed information
|
// Each container includes detailed information
|
||||||
allContainers.forEach(container => {
|
allContainers.forEach((container) => {
|
||||||
console.log(`Container: ${container.Names[0]}`);
|
console.log(`Container: ${container.Names[0]}`);
|
||||||
console.log(` ID: ${container.Id}`);
|
console.log(` ID: ${container.Id}`);
|
||||||
console.log(` Status: ${container.Status}`);
|
console.log(` Status: ${container.Status}`);
|
||||||
@@ -96,21 +96,18 @@ const container = await DockerContainer.create(docker, {
|
|||||||
name: 'my-nginx-server',
|
name: 'my-nginx-server',
|
||||||
HostConfig: {
|
HostConfig: {
|
||||||
PortBindings: {
|
PortBindings: {
|
||||||
'80/tcp': [{ HostPort: '8080' }]
|
'80/tcp': [{ HostPort: '8080' }],
|
||||||
},
|
},
|
||||||
RestartPolicy: {
|
RestartPolicy: {
|
||||||
Name: 'unless-stopped'
|
Name: 'unless-stopped',
|
||||||
},
|
},
|
||||||
Memory: 512 * 1024 * 1024, // 512MB memory limit
|
Memory: 512 * 1024 * 1024, // 512MB memory limit
|
||||||
},
|
},
|
||||||
Env: [
|
Env: ['NODE_ENV=production', 'LOG_LEVEL=info'],
|
||||||
'NODE_ENV=production',
|
|
||||||
'LOG_LEVEL=info'
|
|
||||||
],
|
|
||||||
Labels: {
|
Labels: {
|
||||||
'app': 'web-server',
|
app: 'web-server',
|
||||||
'environment': 'production'
|
environment: 'production',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Container created: ${container.Id}`);
|
console.log(`Container created: ${container.Id}`);
|
||||||
@@ -124,7 +121,10 @@ console.log(`Container created: ${container.Id}`);
|
|||||||
#### Get Container by ID
|
#### Get Container by ID
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const container = await DockerContainer.getContainerById(docker, 'container-id-here');
|
const container = await DockerContainer.getContainerById(
|
||||||
|
docker,
|
||||||
|
'container-id-here',
|
||||||
|
);
|
||||||
if (container) {
|
if (container) {
|
||||||
console.log(`Found container: ${container.Names[0]}`);
|
console.log(`Found container: ${container.Names[0]}`);
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ const image = await DockerImage.createFromRegistry(docker, {
|
|||||||
imageName: 'node',
|
imageName: 'node',
|
||||||
imageTag: '18-alpine',
|
imageTag: '18-alpine',
|
||||||
// Optional: provide registry authentication
|
// Optional: provide registry authentication
|
||||||
authToken: 'your-registry-auth-token'
|
authToken: 'your-registry-auth-token',
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Image pulled: ${image.RepoTags[0]}`);
|
console.log(`Image pulled: ${image.RepoTags[0]}`);
|
||||||
@@ -159,7 +159,7 @@ const tarStream = fs.createReadStream('./my-image.tar');
|
|||||||
const importedImage = await DockerImage.createFromTarStream(docker, {
|
const importedImage = await DockerImage.createFromTarStream(docker, {
|
||||||
tarStream,
|
tarStream,
|
||||||
imageUrl: 'file://./my-image.tar',
|
imageUrl: 'file://./my-image.tar',
|
||||||
imageTag: 'my-app:v1.0.0'
|
imageTag: 'my-app:v1.0.0',
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ exportStream.pipe(writeStream);
|
|||||||
await DockerImage.tagImageByIdOrName(docker, 'node:18-alpine', {
|
await DockerImage.tagImageByIdOrName(docker, 'node:18-alpine', {
|
||||||
registry: 'myregistry.com',
|
registry: 'myregistry.com',
|
||||||
imageName: 'my-node-app',
|
imageName: 'my-node-app',
|
||||||
imageTag: 'v2.0.0'
|
imageTag: 'v2.0.0',
|
||||||
});
|
});
|
||||||
// Result: myregistry.com/my-node-app:v2.0.0
|
// Result: myregistry.com/my-node-app:v2.0.0
|
||||||
```
|
```
|
||||||
@@ -201,15 +201,17 @@ const network = await DockerNetwork.createNetwork(docker, {
|
|||||||
EnableIPv6: false,
|
EnableIPv6: false,
|
||||||
IPAM: {
|
IPAM: {
|
||||||
Driver: 'default',
|
Driver: 'default',
|
||||||
Config: [{
|
Config: [
|
||||||
Subnet: '172.28.0.0/16',
|
{
|
||||||
Gateway: '172.28.0.1'
|
Subnet: '172.28.0.0/16',
|
||||||
}]
|
Gateway: '172.28.0.1',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
Labels: {
|
Labels: {
|
||||||
'project': 'my-app',
|
project: 'my-app',
|
||||||
'environment': 'production'
|
environment: 'production',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Network created: ${network.Id}`);
|
console.log(`Network created: ${network.Id}`);
|
||||||
@@ -220,14 +222,17 @@ console.log(`Network created: ${network.Id}`);
|
|||||||
```typescript
|
```typescript
|
||||||
// Get all networks
|
// Get all networks
|
||||||
const networks = await docker.getNetworks();
|
const networks = await docker.getNetworks();
|
||||||
networks.forEach(net => {
|
networks.forEach((net) => {
|
||||||
console.log(`Network: ${net.Name} (${net.Driver})`);
|
console.log(`Network: ${net.Name} (${net.Driver})`);
|
||||||
console.log(` Scope: ${net.Scope}`);
|
console.log(` Scope: ${net.Scope}`);
|
||||||
console.log(` Internal: ${net.Internal}`);
|
console.log(` Internal: ${net.Internal}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get specific network
|
// Get specific network
|
||||||
const appNetwork = await DockerNetwork.getNetworkByName(docker, 'my-app-network');
|
const appNetwork = await DockerNetwork.getNetworkByName(
|
||||||
|
docker,
|
||||||
|
'my-app-network',
|
||||||
|
);
|
||||||
|
|
||||||
// Get containers on network
|
// Get containers on network
|
||||||
const containers = await appNetwork.getContainersOnNetwork();
|
const containers = await appNetwork.getContainersOnNetwork();
|
||||||
@@ -246,28 +251,32 @@ const service = await DockerService.createService(docker, {
|
|||||||
name: 'web-api',
|
name: 'web-api',
|
||||||
image: 'my-api:latest',
|
image: 'my-api:latest',
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
ports: [{
|
ports: [
|
||||||
Protocol: 'tcp',
|
{
|
||||||
PublishedPort: 80,
|
Protocol: 'tcp',
|
||||||
TargetPort: 3000
|
PublishedPort: 80,
|
||||||
}],
|
TargetPort: 3000,
|
||||||
|
},
|
||||||
|
],
|
||||||
networks: ['my-app-network'],
|
networks: ['my-app-network'],
|
||||||
labels: {
|
labels: {
|
||||||
'app': 'api',
|
app: 'api',
|
||||||
'version': '2.0.0'
|
version: '2.0.0',
|
||||||
},
|
},
|
||||||
resources: {
|
resources: {
|
||||||
limits: {
|
limits: {
|
||||||
Memory: 256 * 1024 * 1024, // 256MB
|
Memory: 256 * 1024 * 1024, // 256MB
|
||||||
CPUs: 0.5
|
CPUs: 0.5,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
secrets: ['api-key', 'db-password'],
|
secrets: ['api-key', 'db-password'],
|
||||||
mounts: [{
|
mounts: [
|
||||||
Target: '/data',
|
{
|
||||||
Source: 'app-data',
|
Target: '/data',
|
||||||
Type: 'volume'
|
Source: 'app-data',
|
||||||
}]
|
Type: 'volume',
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Service deployed: ${service.ID}`);
|
console.log(`Service deployed: ${service.ID}`);
|
||||||
@@ -278,7 +287,7 @@ console.log(`Service deployed: ${service.ID}`);
|
|||||||
```typescript
|
```typescript
|
||||||
// List all services
|
// List all services
|
||||||
const services = await docker.getServices();
|
const services = await docker.getServices();
|
||||||
services.forEach(service => {
|
services.forEach((service) => {
|
||||||
console.log(`Service: ${service.Spec.Name}`);
|
console.log(`Service: ${service.Spec.Name}`);
|
||||||
console.log(` Replicas: ${service.Spec.Mode.Replicated.Replicas}`);
|
console.log(` Replicas: ${service.Spec.Mode.Replicated.Replicas}`);
|
||||||
console.log(` Image: ${service.Spec.TaskTemplate.ContainerSpec.Image}`);
|
console.log(` Image: ${service.Spec.TaskTemplate.ContainerSpec.Image}`);
|
||||||
@@ -307,16 +316,16 @@ const secret = await DockerSecret.createSecret(docker, {
|
|||||||
name: 'api-key',
|
name: 'api-key',
|
||||||
data: Buffer.from('super-secret-key-123').toString('base64'),
|
data: Buffer.from('super-secret-key-123').toString('base64'),
|
||||||
labels: {
|
labels: {
|
||||||
'app': 'my-app',
|
app: 'my-app',
|
||||||
'type': 'api-key'
|
type: 'api-key',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Secret created: ${secret.ID}`);
|
console.log(`Secret created: ${secret.ID}`);
|
||||||
|
|
||||||
// List secrets
|
// List secrets
|
||||||
const secrets = await DockerSecret.getSecrets(docker);
|
const secrets = await DockerSecret.getSecrets(docker);
|
||||||
secrets.forEach(secret => {
|
secrets.forEach((secret) => {
|
||||||
console.log(`Secret: ${secret.Spec.Name}`);
|
console.log(`Secret: ${secret.Spec.Name}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -325,7 +334,7 @@ const apiKeySecret = await DockerSecret.getSecretByName(docker, 'api-key');
|
|||||||
|
|
||||||
// Update secret
|
// Update secret
|
||||||
await apiKeySecret.update({
|
await apiKeySecret.update({
|
||||||
data: Buffer.from('new-secret-key-456').toString('base64')
|
data: Buffer.from('new-secret-key-456').toString('base64'),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove secret
|
// Remove secret
|
||||||
@@ -342,7 +351,7 @@ await docker.addS3Storage({
|
|||||||
endpoint: 's3.amazonaws.com',
|
endpoint: 's3.amazonaws.com',
|
||||||
accessKeyId: 'your-access-key',
|
accessKeyId: 'your-access-key',
|
||||||
secretAccessKey: 'your-secret-key',
|
secretAccessKey: 'your-secret-key',
|
||||||
bucket: 'docker-images'
|
bucket: 'docker-images',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Store an image to S3
|
// Store an image to S3
|
||||||
@@ -368,7 +377,7 @@ const subscription = eventStream.subscribe({
|
|||||||
console.log(`Time: ${new Date(event.time * 1000).toISOString()}`);
|
console.log(`Time: ${new Date(event.time * 1000).toISOString()}`);
|
||||||
},
|
},
|
||||||
error: (err) => console.error('Event stream error:', err),
|
error: (err) => console.error('Event stream error:', err),
|
||||||
complete: () => console.log('Event stream completed')
|
complete: () => console.log('Event stream completed'),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Unsubscribe when done
|
// Unsubscribe when done
|
||||||
@@ -384,7 +393,7 @@ Authenticate with Docker registries for private images:
|
|||||||
await docker.auth({
|
await docker.auth({
|
||||||
username: 'your-username',
|
username: 'your-username',
|
||||||
password: 'your-password',
|
password: 'your-password',
|
||||||
serveraddress: 'https://index.docker.io/v1/'
|
serveraddress: 'https://index.docker.io/v1/',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Or use existing Docker config
|
// Or use existing Docker config
|
||||||
@@ -394,7 +403,7 @@ const authToken = await docker.getAuthTokenFromDockerConfig('myregistry.com');
|
|||||||
const privateImage = await DockerImage.createFromRegistry(docker, {
|
const privateImage = await DockerImage.createFromRegistry(docker, {
|
||||||
imageName: 'myregistry.com/private/image',
|
imageName: 'myregistry.com/private/image',
|
||||||
imageTag: 'latest',
|
imageTag: 'latest',
|
||||||
authToken
|
authToken,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -407,14 +416,14 @@ Initialize and manage Docker Swarm:
|
|||||||
await docker.activateSwarm({
|
await docker.activateSwarm({
|
||||||
ListenAddr: '0.0.0.0:2377',
|
ListenAddr: '0.0.0.0:2377',
|
||||||
AdvertiseAddr: '192.168.1.100:2377',
|
AdvertiseAddr: '192.168.1.100:2377',
|
||||||
ForceNewCluster: false
|
ForceNewCluster: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now you can create services, secrets, and use swarm features
|
// Now you can create services, secrets, and use swarm features
|
||||||
const service = await DockerService.createService(docker, {
|
const service = await DockerService.createService(docker, {
|
||||||
name: 'my-swarm-service',
|
name: 'my-swarm-service',
|
||||||
image: 'nginx:latest',
|
image: 'nginx:latest',
|
||||||
replicas: 5
|
replicas: 5,
|
||||||
// ... more service config
|
// ... more service config
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -430,13 +439,13 @@ async function deployStack() {
|
|||||||
// Create network
|
// Create network
|
||||||
const network = await DockerNetwork.createNetwork(docker, {
|
const network = await DockerNetwork.createNetwork(docker, {
|
||||||
Name: 'app-network',
|
Name: 'app-network',
|
||||||
Driver: 'overlay' // for swarm mode
|
Driver: 'overlay', // for swarm mode
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create secrets
|
// Create secrets
|
||||||
const dbPassword = await DockerSecret.createSecret(docker, {
|
const dbPassword = await DockerSecret.createSecret(docker, {
|
||||||
name: 'db-password',
|
name: 'db-password',
|
||||||
data: Buffer.from('strong-password').toString('base64')
|
data: Buffer.from('strong-password').toString('base64'),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deploy database service
|
// Deploy database service
|
||||||
@@ -445,7 +454,7 @@ async function deployStack() {
|
|||||||
image: 'postgres:14',
|
image: 'postgres:14',
|
||||||
networks: ['app-network'],
|
networks: ['app-network'],
|
||||||
secrets: ['db-password'],
|
secrets: ['db-password'],
|
||||||
env: ['POSTGRES_PASSWORD_FILE=/run/secrets/db-password']
|
env: ['POSTGRES_PASSWORD_FILE=/run/secrets/db-password'],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deploy application service
|
// Deploy application service
|
||||||
@@ -454,7 +463,7 @@ async function deployStack() {
|
|||||||
image: 'my-app:latest',
|
image: 'my-app:latest',
|
||||||
replicas: 3,
|
replicas: 3,
|
||||||
networks: ['app-network'],
|
networks: ['app-network'],
|
||||||
ports: [{ Protocol: 'tcp', PublishedPort: 80, TargetPort: 3000 }]
|
ports: [{ Protocol: 'tcp', PublishedPort: 80, TargetPort: 3000 }],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Stack deployed successfully!');
|
console.log('Stack deployed successfully!');
|
||||||
@@ -471,7 +480,7 @@ import type {
|
|||||||
IServiceCreationDescriptor,
|
IServiceCreationDescriptor,
|
||||||
INetworkCreationDescriptor,
|
INetworkCreationDescriptor,
|
||||||
IImageCreationDescriptor,
|
IImageCreationDescriptor,
|
||||||
ISecretCreationDescriptor
|
ISecretCreationDescriptor,
|
||||||
} from '@apiclient.xyz/docker';
|
} from '@apiclient.xyz/docker';
|
||||||
|
|
||||||
// Full IntelliSense support for all configuration options
|
// Full IntelliSense support for all configuration options
|
||||||
|
40
test-stream.js
Normal file
40
test-stream.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
const { SmartRequest } = require('@push.rocks/smartrequest');
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
try {
|
||||||
|
const response = await SmartRequest.create()
|
||||||
|
.url('http://unix:/run/user/1000/docker.sock:/images/hello-world:latest/get')
|
||||||
|
.header('Host', 'docker.sock')
|
||||||
|
.get();
|
||||||
|
|
||||||
|
console.log('Response status:', response.status);
|
||||||
|
console.log('Response type:', typeof response);
|
||||||
|
|
||||||
|
const stream = response.streamNode();
|
||||||
|
console.log('Stream type:', typeof stream);
|
||||||
|
console.log('Has on method:', typeof stream.on);
|
||||||
|
|
||||||
|
if (stream) {
|
||||||
|
let chunks = 0;
|
||||||
|
stream.on('data', (chunk) => {
|
||||||
|
chunks++;
|
||||||
|
if (chunks <= 3) console.log('Got chunk', chunks, chunk.length);
|
||||||
|
});
|
||||||
|
stream.on('end', () => {
|
||||||
|
console.log('Stream ended, total chunks:', chunks);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
stream.on('error', (err) => {
|
||||||
|
console.error('Stream error:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('No stream available');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test();
|
46
test-stream.mjs
Normal file
46
test-stream.mjs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { SmartRequest } from '@push.rocks/smartrequest';
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
try {
|
||||||
|
const response = await SmartRequest.create()
|
||||||
|
.url('http://unix:/run/user/1000/docker.sock:/images/hello-world:latest/get')
|
||||||
|
.header('Host', 'docker.sock')
|
||||||
|
.get();
|
||||||
|
|
||||||
|
console.log('Response status:', response.status);
|
||||||
|
console.log('Response type:', typeof response);
|
||||||
|
|
||||||
|
const stream = response.streamNode();
|
||||||
|
console.log('Stream type:', typeof stream);
|
||||||
|
console.log('Has on method:', typeof stream.on);
|
||||||
|
|
||||||
|
if (stream) {
|
||||||
|
let chunks = 0;
|
||||||
|
stream.on('data', (chunk) => {
|
||||||
|
chunks++;
|
||||||
|
if (chunks <= 3) console.log('Got chunk', chunks, chunk.length);
|
||||||
|
});
|
||||||
|
stream.on('end', () => {
|
||||||
|
console.log('Stream ended, total chunks:', chunks);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
stream.on('error', (err) => {
|
||||||
|
console.error('Stream error:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set a timeout in case stream doesn't end
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('Timeout after 5 seconds');
|
||||||
|
process.exit(1);
|
||||||
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
console.log('No stream available');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test();
|
@@ -41,7 +41,10 @@ tap.test('should create a network', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should remove a network', async () => {
|
tap.test('should remove a network', async () => {
|
||||||
const webgateway = await docker.DockerNetwork.getNetworkByName(testDockerHost, 'webgateway');
|
const webgateway = await docker.DockerNetwork.getNetworkByName(
|
||||||
|
testDockerHost,
|
||||||
|
'webgateway',
|
||||||
|
);
|
||||||
await webgateway.remove();
|
await webgateway.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,7 +81,10 @@ tap.test('should create a secret', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should remove a secret by name', async () => {
|
tap.test('should remove a secret by name', async () => {
|
||||||
const mySecret = await docker.DockerSecret.getSecretByName(testDockerHost, 'testSecret');
|
const mySecret = await docker.DockerSecret.getSecretByName(
|
||||||
|
testDockerHost,
|
||||||
|
'testSecret',
|
||||||
|
);
|
||||||
await mySecret.remove();
|
await mySecret.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -102,11 +108,14 @@ tap.test('should create a service', async () => {
|
|||||||
labels: {},
|
labels: {},
|
||||||
contentArg: '{"hi": "wow"}',
|
contentArg: '{"hi": "wow"}',
|
||||||
});
|
});
|
||||||
const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
|
const testImage = await docker.DockerImage.createFromRegistry(
|
||||||
creationObject: {
|
testDockerHost,
|
||||||
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
{
|
||||||
}
|
creationObject: {
|
||||||
});
|
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
const testService = await docker.DockerService.createService(testDockerHost, {
|
const testService = await docker.DockerService.createService(testDockerHost, {
|
||||||
image: testImage,
|
image: testImage,
|
||||||
labels: {},
|
labels: {},
|
||||||
@@ -124,13 +133,16 @@ tap.test('should create a service', async () => {
|
|||||||
|
|
||||||
tap.test('should export images', async (toolsArg) => {
|
tap.test('should export images', async (toolsArg) => {
|
||||||
const done = toolsArg.defer();
|
const done = toolsArg.defer();
|
||||||
const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
|
const testImage = await docker.DockerImage.createFromRegistry(
|
||||||
creationObject: {
|
testDockerHost,
|
||||||
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
{
|
||||||
}
|
creationObject: {
|
||||||
});
|
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
const fsWriteStream = plugins.smartfile.fsStream.createWriteStream(
|
const fsWriteStream = plugins.smartfile.fsStream.createWriteStream(
|
||||||
plugins.path.join(paths.nogitDir, 'testimage.tar')
|
plugins.path.join(paths.nogitDir, 'testimage.tar'),
|
||||||
);
|
);
|
||||||
const exportStream = await testImage.exportToTarStream();
|
const exportStream = await testImage.exportToTarStream();
|
||||||
exportStream.pipe(fsWriteStream).on('finish', () => {
|
exportStream.pipe(fsWriteStream).on('finish', () => {
|
||||||
@@ -139,17 +151,20 @@ tap.test('should export images', async (toolsArg) => {
|
|||||||
await done.promise;
|
await done.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should import images', async (toolsArg) => {
|
tap.test('should import images', async () => {
|
||||||
const done = toolsArg.defer();
|
|
||||||
const fsReadStream = plugins.smartfile.fsStream.createReadStream(
|
const fsReadStream = plugins.smartfile.fsStream.createReadStream(
|
||||||
plugins.path.join(paths.nogitDir, 'testimage.tar')
|
plugins.path.join(paths.nogitDir, 'testimage.tar'),
|
||||||
);
|
);
|
||||||
await docker.DockerImage.createFromTarStream(testDockerHost, {
|
const importedImage = await docker.DockerImage.createFromTarStream(
|
||||||
tarStream: fsReadStream,
|
testDockerHost,
|
||||||
creationObject: {
|
{
|
||||||
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
tarStream: fsReadStream,
|
||||||
}
|
creationObject: {
|
||||||
})
|
imageUrl: 'code.foss.global/host.today/ht-docker-node:latest',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(importedImage).toBeInstanceOf(docker.DockerImage);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should expose a working DockerImageStore', async () => {
|
tap.test('should expose a working DockerImageStore', async () => {
|
||||||
@@ -163,7 +178,16 @@ tap.test('should expose a working DockerImageStore', async () => {
|
|||||||
await testDockerHost.addS3Storage(s3Descriptor);
|
await testDockerHost.addS3Storage(s3Descriptor);
|
||||||
|
|
||||||
//
|
//
|
||||||
await testDockerHost.imageStore.storeImage('hello', plugins.smartfile.fsStream.createReadStream(plugins.path.join(paths.nogitDir, 'testimage.tar')));
|
await testDockerHost.imageStore.storeImage(
|
||||||
})
|
'hello2',
|
||||||
|
plugins.smartfile.fsStream.createReadStream(
|
||||||
|
plugins.path.join(paths.nogitDir, 'testimage.tar'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('cleanup', async () => {
|
||||||
|
await testDockerHost.stop();
|
||||||
|
});
|
||||||
|
|
||||||
export default tap.start();
|
export default tap.start();
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@apiclient.xyz/docker',
|
name: '@apiclient.xyz/docker',
|
||||||
version: '1.3.2',
|
version: '1.3.5',
|
||||||
description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.'
|
description: 'Provides easy communication with Docker remote API from Node.js, with TypeScript support.'
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,9 @@ export class DockerContainer {
|
|||||||
/**
|
/**
|
||||||
* get all containers
|
* get all containers
|
||||||
*/
|
*/
|
||||||
public static async getContainers(dockerHostArg: DockerHost): Promise<DockerContainer[]> {
|
public static async getContainers(
|
||||||
|
dockerHostArg: DockerHost,
|
||||||
|
): Promise<DockerContainer[]> {
|
||||||
const result: DockerContainer[] = [];
|
const result: DockerContainer[] = [];
|
||||||
const response = await dockerHostArg.request('GET', '/containers/json');
|
const response = await dockerHostArg.request('GET', '/containers/json');
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ export class DockerContainer {
|
|||||||
*/
|
*/
|
||||||
public static async create(
|
public static async create(
|
||||||
dockerHost: DockerHost,
|
dockerHost: DockerHost,
|
||||||
containerCreationDescriptor: interfaces.IContainerCreationDescriptor
|
containerCreationDescriptor: interfaces.IContainerCreationDescriptor,
|
||||||
) {
|
) {
|
||||||
// check for unique hostname
|
// check for unique hostname
|
||||||
const existingContainers = await DockerContainer.getContainers(dockerHost);
|
const existingContainers = await DockerContainer.getContainers(dockerHost);
|
||||||
@@ -50,7 +52,10 @@ export class DockerContainer {
|
|||||||
if (response.statusCode < 300) {
|
if (response.statusCode < 300) {
|
||||||
logger.log('info', 'Container created successfully');
|
logger.log('info', 'Container created successfully');
|
||||||
} else {
|
} else {
|
||||||
logger.log('error', 'There has been a problem when creating the container');
|
logger.log(
|
||||||
|
'error',
|
||||||
|
'There has been a problem when creating the container',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -37,10 +37,13 @@ export class DockerHost {
|
|||||||
constructor(optionsArg: IDockerHostConstructorOptions) {
|
constructor(optionsArg: IDockerHostConstructorOptions) {
|
||||||
this.options = {
|
this.options = {
|
||||||
...{
|
...{
|
||||||
imageStoreDir: plugins.path.join(paths.nogitDir, 'temp-docker-image-store'),
|
imageStoreDir: plugins.path.join(
|
||||||
|
paths.nogitDir,
|
||||||
|
'temp-docker-image-store',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
...optionsArg,
|
...optionsArg,
|
||||||
}
|
};
|
||||||
let pathToUse: string;
|
let pathToUse: string;
|
||||||
if (optionsArg.dockerSockPath) {
|
if (optionsArg.dockerSockPath) {
|
||||||
pathToUse = optionsArg.dockerSockPath;
|
pathToUse = optionsArg.dockerSockPath;
|
||||||
@@ -62,7 +65,7 @@ export class DockerHost {
|
|||||||
this.imageStore = new DockerImageStore({
|
this.imageStore = new DockerImageStore({
|
||||||
bucketDir: null,
|
bucketDir: null,
|
||||||
localDirPath: this.options.imageStoreDir,
|
localDirPath: this.options.imageStoreDir,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async start() {
|
public async start() {
|
||||||
@@ -84,17 +87,22 @@ export class DockerHost {
|
|||||||
throw new Error(response.body.Status);
|
throw new Error(response.body.Status);
|
||||||
}
|
}
|
||||||
console.log(response.body.Status);
|
console.log(response.body.Status);
|
||||||
this.registryToken = plugins.smartstring.base64.encode(plugins.smartjson.stringify(authData));
|
this.registryToken = plugins.smartstring.base64.encode(
|
||||||
|
plugins.smartjson.stringify(authData),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the token from the .docker/config.json file for GitLab registry
|
* gets the token from the .docker/config.json file for GitLab registry
|
||||||
*/
|
*/
|
||||||
public async getAuthTokenFromDockerConfig(registryUrlArg: string) {
|
public async getAuthTokenFromDockerConfig(registryUrlArg: string) {
|
||||||
const dockerConfigPath = plugins.smartpath.get.home('~/.docker/config.json');
|
const dockerConfigPath = plugins.smartpath.get.home(
|
||||||
|
'~/.docker/config.json',
|
||||||
|
);
|
||||||
const configObject = plugins.smartfile.fs.toObjectSync(dockerConfigPath);
|
const configObject = plugins.smartfile.fs.toObjectSync(dockerConfigPath);
|
||||||
const gitlabAuthBase64 = configObject.auths[registryUrlArg].auth;
|
const gitlabAuthBase64 = configObject.auths[registryUrlArg].auth;
|
||||||
const gitlabAuth: string = plugins.smartstring.base64.decode(gitlabAuthBase64);
|
const gitlabAuth: string =
|
||||||
|
plugins.smartstring.base64.decode(gitlabAuthBase64);
|
||||||
const gitlabAuthArray = gitlabAuth.split(':');
|
const gitlabAuthArray = gitlabAuth.split(':');
|
||||||
await this.auth({
|
await this.auth({
|
||||||
username: gitlabAuthArray[0],
|
username: gitlabAuthArray[0],
|
||||||
@@ -116,7 +124,9 @@ export class DockerHost {
|
|||||||
/**
|
/**
|
||||||
* create a network
|
* create a network
|
||||||
*/
|
*/
|
||||||
public async createNetwork(optionsArg: Parameters<typeof DockerNetwork.createNetwork>[1]) {
|
public async createNetwork(
|
||||||
|
optionsArg: Parameters<typeof DockerNetwork.createNetwork>[1],
|
||||||
|
) {
|
||||||
return await DockerNetwork.createNetwork(this, optionsArg);
|
return await DockerNetwork.createNetwork(this, optionsArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +137,6 @@ export class DockerHost {
|
|||||||
return await DockerNetwork.getNetworkByName(this, networkNameArg);
|
return await DockerNetwork.getNetworkByName(this, networkNameArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// CONTAINERS
|
// CONTAINERS
|
||||||
// ==============
|
// ==============
|
||||||
@@ -226,54 +235,160 @@ export class DockerHost {
|
|||||||
*/
|
*/
|
||||||
public async request(methodArg: string, routeArg: string, dataArg = {}) {
|
public async request(methodArg: string, routeArg: string, dataArg = {}) {
|
||||||
const requestUrl = `${this.socketPath}${routeArg}`;
|
const requestUrl = `${this.socketPath}${routeArg}`;
|
||||||
const response = await plugins.smartrequest.request(requestUrl, {
|
|
||||||
method: methodArg,
|
// Build the request using the fluent API
|
||||||
headers: {
|
const smartRequest = plugins.smartrequest.SmartRequest.create()
|
||||||
'Content-Type': 'application/json',
|
.url(requestUrl)
|
||||||
'X-Registry-Auth': this.registryToken,
|
.header('Content-Type', 'application/json')
|
||||||
Host: 'docker.sock',
|
.header('X-Registry-Auth', this.registryToken)
|
||||||
},
|
.header('Host', 'docker.sock')
|
||||||
requestBody: dataArg,
|
.options({ keepAlive: false });
|
||||||
keepAlive: false,
|
|
||||||
});
|
// Add body for methods that support it
|
||||||
if (response.statusCode !== 200) {
|
if (dataArg && Object.keys(dataArg).length > 0) {
|
||||||
console.log(response.body);
|
smartRequest.json(dataArg);
|
||||||
}
|
}
|
||||||
return response;
|
|
||||||
|
// Execute the request based on method
|
||||||
|
let response;
|
||||||
|
switch (methodArg.toUpperCase()) {
|
||||||
|
case 'GET':
|
||||||
|
response = await smartRequest.get();
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
response = await smartRequest.post();
|
||||||
|
break;
|
||||||
|
case 'PUT':
|
||||||
|
response = await smartRequest.put();
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
response = await smartRequest.delete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported HTTP method: ${methodArg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the response body based on content type
|
||||||
|
let body;
|
||||||
|
const contentType = response.headers['content-type'] || '';
|
||||||
|
|
||||||
|
// Docker's streaming endpoints (like /images/create) return newline-delimited JSON
|
||||||
|
// which can't be parsed as a single JSON object
|
||||||
|
const isStreamingEndpoint =
|
||||||
|
routeArg.includes('/images/create') ||
|
||||||
|
routeArg.includes('/images/load') ||
|
||||||
|
routeArg.includes('/build');
|
||||||
|
|
||||||
|
if (contentType.includes('application/json') && !isStreamingEndpoint) {
|
||||||
|
body = await response.json();
|
||||||
|
} else {
|
||||||
|
body = await response.text();
|
||||||
|
// Try to parse as JSON if it looks like JSON and is not a streaming response
|
||||||
|
if (
|
||||||
|
!isStreamingEndpoint &&
|
||||||
|
body &&
|
||||||
|
(body.startsWith('{') || body.startsWith('['))
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
body = JSON.parse(body);
|
||||||
|
} catch {
|
||||||
|
// Keep as text if parsing fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a response object compatible with existing code
|
||||||
|
const legacyResponse = {
|
||||||
|
statusCode: response.status,
|
||||||
|
body: body,
|
||||||
|
headers: response.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return legacyResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async requestStreaming(methodArg: string, routeArg: string, readStream?: plugins.smartstream.stream.Readable) {
|
public async requestStreaming(
|
||||||
|
methodArg: string,
|
||||||
|
routeArg: string,
|
||||||
|
readStream?: plugins.smartstream.stream.Readable,
|
||||||
|
) {
|
||||||
const requestUrl = `${this.socketPath}${routeArg}`;
|
const requestUrl = `${this.socketPath}${routeArg}`;
|
||||||
const response = await plugins.smartrequest.request(
|
|
||||||
requestUrl,
|
// Build the request using the fluent API
|
||||||
{
|
const smartRequest = plugins.smartrequest.SmartRequest.create()
|
||||||
method: methodArg,
|
.url(requestUrl)
|
||||||
headers: {
|
.header('Content-Type', 'application/json')
|
||||||
'Content-Type': 'application/json',
|
.header('X-Registry-Auth', this.registryToken)
|
||||||
'X-Registry-Auth': this.registryToken,
|
.header('Host', 'docker.sock')
|
||||||
Host: 'docker.sock',
|
.timeout(30000)
|
||||||
},
|
.options({ keepAlive: false, autoDrain: true }); // Disable auto-drain for streaming
|
||||||
requestBody: null,
|
|
||||||
keepAlive: false,
|
// If we have a readStream, use the new stream method with logging
|
||||||
},
|
if (readStream) {
|
||||||
true,
|
let counter = 0;
|
||||||
(readStream ? reqArg => {
|
const smartduplex = new plugins.smartstream.SmartDuplex({
|
||||||
let counter = 0;
|
writeFunction: async (chunkArg) => {
|
||||||
const smartduplex = new plugins.smartstream.SmartDuplex({
|
if (counter % 1000 === 0) {
|
||||||
writeFunction: async (chunkArg) => {
|
console.log(`posting chunk ${counter}`);
|
||||||
if (counter % 1000 === 0) {
|
|
||||||
console.log(`posting chunk ${counter}`);
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
return chunkArg;
|
|
||||||
}
|
}
|
||||||
});
|
counter++;
|
||||||
readStream.pipe(smartduplex).pipe(reqArg);
|
return chunkArg;
|
||||||
} : null),
|
},
|
||||||
);
|
});
|
||||||
console.log(response.statusCode);
|
|
||||||
console.log(response.body);
|
// Pipe through the logging duplex stream
|
||||||
return response;
|
const loggedStream = readStream.pipe(smartduplex);
|
||||||
|
|
||||||
|
// Use the new stream method to stream the data
|
||||||
|
smartRequest.stream(loggedStream, 'application/octet-stream');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the request based on method
|
||||||
|
let response;
|
||||||
|
switch (methodArg.toUpperCase()) {
|
||||||
|
case 'GET':
|
||||||
|
response = await smartRequest.get();
|
||||||
|
break;
|
||||||
|
case 'POST':
|
||||||
|
response = await smartRequest.post();
|
||||||
|
break;
|
||||||
|
case 'PUT':
|
||||||
|
response = await smartRequest.put();
|
||||||
|
break;
|
||||||
|
case 'DELETE':
|
||||||
|
response = await smartRequest.delete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported HTTP method: ${methodArg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(response.status);
|
||||||
|
|
||||||
|
// For streaming responses, get the Node.js stream
|
||||||
|
const nodeStream = response.streamNode();
|
||||||
|
|
||||||
|
if (!nodeStream) {
|
||||||
|
// If no stream is available, consume the body as text
|
||||||
|
const body = await response.text();
|
||||||
|
console.log(body);
|
||||||
|
|
||||||
|
// Return a compatible response object
|
||||||
|
return {
|
||||||
|
statusCode: response.status,
|
||||||
|
body: body,
|
||||||
|
headers: response.headers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// For streaming responses, return the stream with added properties
|
||||||
|
(nodeStream as any).statusCode = response.status;
|
||||||
|
(nodeStream as any).body = ''; // For compatibility
|
||||||
|
|
||||||
|
return nodeStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,10 +400,14 @@ export class DockerHost {
|
|||||||
if (!optionsArg.bucketName) {
|
if (!optionsArg.bucketName) {
|
||||||
throw new Error('bucketName is required');
|
throw new Error('bucketName is required');
|
||||||
}
|
}
|
||||||
const bucket = await this.smartBucket.getBucketByName(optionsArg.bucketName);
|
const bucket = await this.smartBucket.getBucketByName(
|
||||||
|
optionsArg.bucketName,
|
||||||
|
);
|
||||||
let wantedDirectory = await bucket.getBaseDirectory();
|
let wantedDirectory = await bucket.getBaseDirectory();
|
||||||
if (optionsArg.directoryPath) {
|
if (optionsArg.directoryPath) {
|
||||||
wantedDirectory = await wantedDirectory.getSubDirectoryByName(optionsArg.directoryPath);
|
wantedDirectory = await wantedDirectory.getSubDirectoryByName(
|
||||||
|
optionsArg.directoryPath,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.imageStore.options.bucketDir = wantedDirectory;
|
this.imageStore.options.bucketDir = wantedDirectory;
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,10 @@ export class DockerImage {
|
|||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getImageByName(dockerHost: DockerHost, imageNameArg: string) {
|
public static async getImageByName(
|
||||||
|
dockerHost: DockerHost,
|
||||||
|
imageNameArg: string,
|
||||||
|
) {
|
||||||
const images = await this.getImages(dockerHost);
|
const images = await this.getImages(dockerHost);
|
||||||
const result = images.find((image) => {
|
const result = images.find((image) => {
|
||||||
if (image.RepoTags) {
|
if (image.RepoTags) {
|
||||||
@@ -32,8 +35,8 @@ export class DockerImage {
|
|||||||
public static async createFromRegistry(
|
public static async createFromRegistry(
|
||||||
dockerHostArg: DockerHost,
|
dockerHostArg: DockerHost,
|
||||||
optionsArg: {
|
optionsArg: {
|
||||||
creationObject: interfaces.IImageCreationDescriptor
|
creationObject: interfaces.IImageCreationDescriptor;
|
||||||
}
|
},
|
||||||
): Promise<DockerImage> {
|
): Promise<DockerImage> {
|
||||||
// lets create a sanatized imageUrlObject
|
// lets create a sanatized imageUrlObject
|
||||||
const imageUrlObject: {
|
const imageUrlObject: {
|
||||||
@@ -50,7 +53,7 @@ export class DockerImage {
|
|||||||
const imageTag = imageUrlObject.imageUrl.split(':')[1];
|
const imageTag = imageUrlObject.imageUrl.split(':')[1];
|
||||||
if (imageUrlObject.imageTag) {
|
if (imageUrlObject.imageTag) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${imageUrlObject.imageTag} because it is already tagged with ${imageTag}`
|
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${imageUrlObject.imageTag} because it is already tagged with ${imageTag}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
imageUrlObject.imageUrl = imageUrl;
|
imageUrlObject.imageUrl = imageUrl;
|
||||||
@@ -65,12 +68,18 @@ export class DockerImage {
|
|||||||
const response = await dockerHostArg.request(
|
const response = await dockerHostArg.request(
|
||||||
'POST',
|
'POST',
|
||||||
`/images/create?fromImage=${encodeURIComponent(
|
`/images/create?fromImage=${encodeURIComponent(
|
||||||
imageUrlObject.imageUrl
|
imageUrlObject.imageUrl,
|
||||||
)}&tag=${encodeURIComponent(imageUrlObject.imageTag)}`
|
)}&tag=${encodeURIComponent(imageUrlObject.imageTag)}`,
|
||||||
);
|
);
|
||||||
if (response.statusCode < 300) {
|
if (response.statusCode < 300) {
|
||||||
logger.log('info', `Successfully pulled image ${imageUrlObject.imageUrl} from the registry`);
|
logger.log(
|
||||||
const image = await DockerImage.getImageByName(dockerHostArg, imageUrlObject.imageOriginTag);
|
'info',
|
||||||
|
`Successfully pulled image ${imageUrlObject.imageUrl} from the registry`,
|
||||||
|
);
|
||||||
|
const image = await DockerImage.getImageByName(
|
||||||
|
dockerHostArg,
|
||||||
|
imageUrlObject.imageOriginTag,
|
||||||
|
);
|
||||||
return image;
|
return image;
|
||||||
} else {
|
} else {
|
||||||
logger.log('error', `Failed at the attempt of creating a new image`);
|
logger.log('error', `Failed at the attempt of creating a new image`);
|
||||||
@@ -87,13 +96,13 @@ export class DockerImage {
|
|||||||
optionsArg: {
|
optionsArg: {
|
||||||
creationObject: interfaces.IImageCreationDescriptor;
|
creationObject: interfaces.IImageCreationDescriptor;
|
||||||
tarStream: plugins.smartstream.stream.Readable;
|
tarStream: plugins.smartstream.stream.Readable;
|
||||||
}
|
},
|
||||||
): Promise<DockerImage> {
|
): Promise<DockerImage> {
|
||||||
// Start the request for importing an image
|
// Start the request for importing an image
|
||||||
const response = await dockerHostArg.requestStreaming(
|
const response = await dockerHostArg.requestStreaming(
|
||||||
'POST',
|
'POST',
|
||||||
'/images/load',
|
'/images/load',
|
||||||
optionsArg.tarStream
|
optionsArg.tarStream,
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +153,7 @@ export class DockerImage {
|
|||||||
|
|
||||||
if (!loadedImageTag) {
|
if (!loadedImageTag) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not parse the loaded image info from Docker response.\nResponse was:\n${rawOutput}`
|
`Could not parse the loaded image info from Docker response.\nResponse was:\n${rawOutput}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,34 +162,31 @@ export class DockerImage {
|
|||||||
// "myrepo/myimage:latest" OR "sha256:someHash..."
|
// "myrepo/myimage:latest" OR "sha256:someHash..."
|
||||||
// If Docker gave you an ID (e.g. "sha256:..."), you may need a separate
|
// If Docker gave you an ID (e.g. "sha256:..."), you may need a separate
|
||||||
// DockerImage.getImageById method; or if you prefer, you can treat it as a name.
|
// DockerImage.getImageById method; or if you prefer, you can treat it as a name.
|
||||||
const newlyImportedImage = await DockerImage.getImageByName(dockerHostArg, loadedImageTag);
|
const newlyImportedImage = await DockerImage.getImageByName(
|
||||||
|
dockerHostArg,
|
||||||
|
loadedImageTag,
|
||||||
|
);
|
||||||
|
|
||||||
if (!newlyImportedImage) {
|
if (!newlyImportedImage) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Image load succeeded, but no local reference found for "${loadedImageTag}".`
|
`Image load succeeded, but no local reference found for "${loadedImageTag}".`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(
|
logger.log('info', `Successfully imported image "${loadedImageTag}".`);
|
||||||
'info',
|
|
||||||
`Successfully imported image "${loadedImageTag}".`
|
|
||||||
);
|
|
||||||
|
|
||||||
return newlyImportedImage;
|
return newlyImportedImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async tagImageByIdOrName(
|
public static async tagImageByIdOrName(
|
||||||
dockerHost: DockerHost,
|
dockerHost: DockerHost,
|
||||||
idOrNameArg: string,
|
idOrNameArg: string,
|
||||||
newTagArg: string
|
newTagArg: string,
|
||||||
) {
|
) {
|
||||||
const response = await dockerHost.request(
|
const response = await dockerHost.request(
|
||||||
'POST',
|
'POST',
|
||||||
`/images/${encodeURIComponent(idOrNameArg)}/${encodeURIComponent(newTagArg)}`
|
`/images/${encodeURIComponent(idOrNameArg)}/${encodeURIComponent(newTagArg)}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async buildImage(dockerHostArg: DockerHost, dockerImageTag) {
|
public static async buildImage(dockerHostArg: DockerHost, dockerImageTag) {
|
||||||
@@ -249,27 +255,43 @@ export class DockerImage {
|
|||||||
*/
|
*/
|
||||||
public async exportToTarStream(): Promise<plugins.smartstream.stream.Readable> {
|
public async exportToTarStream(): Promise<plugins.smartstream.stream.Readable> {
|
||||||
logger.log('info', `Exporting image ${this.RepoTags[0]} to tar stream.`);
|
logger.log('info', `Exporting image ${this.RepoTags[0]} to tar stream.`);
|
||||||
const response = await this.dockerHost.requestStreaming('GET', `/images/${encodeURIComponent(this.RepoTags[0])}/get`);
|
const response = await this.dockerHost.requestStreaming(
|
||||||
|
'GET',
|
||||||
|
`/images/${encodeURIComponent(this.RepoTags[0])}/get`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if response is a Node.js stream
|
||||||
|
if (!response || typeof response.on !== 'function') {
|
||||||
|
throw new Error('Failed to get streaming response for image export');
|
||||||
|
}
|
||||||
|
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
const webduplexStream = new plugins.smartstream.SmartDuplex({
|
const webduplexStream = new plugins.smartstream.SmartDuplex({
|
||||||
writeFunction: async (chunk, tools) => {
|
writeFunction: async (chunk, tools) => {
|
||||||
if (counter % 1000 === 0)
|
if (counter % 1000 === 0) console.log(`Got chunk: ${counter}`);
|
||||||
console.log(`Got chunk: ${counter}`);
|
|
||||||
counter++;
|
counter++;
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
response.on('data', (chunk) => {
|
response.on('data', (chunk) => {
|
||||||
if (!webduplexStream.write(chunk)) {
|
if (!webduplexStream.write(chunk)) {
|
||||||
response.pause();
|
response.pause();
|
||||||
webduplexStream.once('drain', () => {
|
webduplexStream.once('drain', () => {
|
||||||
response.resume();
|
response.resume();
|
||||||
})
|
});
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
response.on('end', () => {
|
response.on('end', () => {
|
||||||
webduplexStream.end();
|
webduplexStream.end();
|
||||||
})
|
});
|
||||||
|
|
||||||
|
response.on('error', (error) => {
|
||||||
|
logger.log('error', `Error during image export: ${error.message}`);
|
||||||
|
webduplexStream.destroy(error);
|
||||||
|
});
|
||||||
|
|
||||||
return webduplexStream;
|
return webduplexStream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,25 @@ export class DockerImageStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method to store tar stream
|
// Method to store tar stream
|
||||||
public async storeImage(imageName: string, tarStream: plugins.smartstream.stream.Readable): Promise<void> {
|
public async storeImage(
|
||||||
|
imageName: string,
|
||||||
|
tarStream: plugins.smartstream.stream.Readable,
|
||||||
|
): Promise<void> {
|
||||||
logger.log('info', `Storing image ${imageName}...`);
|
logger.log('info', `Storing image ${imageName}...`);
|
||||||
const uniqueProcessingId = plugins.smartunique.shortId();
|
const uniqueProcessingId = plugins.smartunique.shortId();
|
||||||
|
|
||||||
const initialTarDownloadPath = plugins.path.join(this.options.localDirPath, `${uniqueProcessingId}.tar`);
|
const initialTarDownloadPath = plugins.path.join(
|
||||||
const extractionDir = plugins.path.join(this.options.localDirPath, uniqueProcessingId);
|
this.options.localDirPath,
|
||||||
|
`${uniqueProcessingId}.tar`,
|
||||||
|
);
|
||||||
|
const extractionDir = plugins.path.join(
|
||||||
|
this.options.localDirPath,
|
||||||
|
uniqueProcessingId,
|
||||||
|
);
|
||||||
// Create a write stream to store the tar file
|
// Create a write stream to store the tar file
|
||||||
const writeStream = plugins.smartfile.fsStream.createWriteStream(initialTarDownloadPath);
|
const writeStream = plugins.smartfile.fsStream.createWriteStream(
|
||||||
|
initialTarDownloadPath,
|
||||||
|
);
|
||||||
|
|
||||||
// lets wait for the write stream to finish
|
// lets wait for the write stream to finish
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
@@ -37,23 +48,43 @@ export class DockerImageStore {
|
|||||||
writeStream.on('finish', resolve);
|
writeStream.on('finish', resolve);
|
||||||
writeStream.on('error', reject);
|
writeStream.on('error', reject);
|
||||||
});
|
});
|
||||||
logger.log('info', `Image ${imageName} stored locally for processing. Extracting...`);
|
logger.log(
|
||||||
|
'info',
|
||||||
|
`Image ${imageName} stored locally for processing. Extracting...`,
|
||||||
|
);
|
||||||
|
|
||||||
// lets process the image
|
// lets process the image
|
||||||
const tarArchive = await plugins.smartarchive.SmartArchive.fromArchiveFile(initialTarDownloadPath);
|
const tarArchive = await plugins.smartarchive.SmartArchive.fromArchiveFile(
|
||||||
|
initialTarDownloadPath,
|
||||||
|
);
|
||||||
await tarArchive.exportToFs(extractionDir);
|
await tarArchive.exportToFs(extractionDir);
|
||||||
logger.log('info', `Image ${imageName} extracted.`);
|
logger.log('info', `Image ${imageName} extracted.`);
|
||||||
await plugins.smartfile.fs.remove(initialTarDownloadPath);
|
await plugins.smartfile.fs.remove(initialTarDownloadPath);
|
||||||
logger.log('info', `deleted original tar to save space.`);
|
logger.log('info', `deleted original tar to save space.`);
|
||||||
logger.log('info', `now repackaging for s3...`);
|
logger.log('info', `now repackaging for s3...`);
|
||||||
const smartfileIndexJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'index.json'));
|
const smartfileIndexJson = await plugins.smartfile.SmartFile.fromFilePath(
|
||||||
const smartfileManifestJson = await plugins.smartfile.SmartFile.fromFilePath(plugins.path.join(extractionDir, 'manifest.json'));
|
plugins.path.join(extractionDir, 'index.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 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 indexJson = JSON.parse(smartfileIndexJson.contents.toString());
|
||||||
const manifestJson = JSON.parse(smartfileManifestJson.contents.toString());
|
const manifestJson = JSON.parse(smartfileManifestJson.contents.toString());
|
||||||
const ociLayoutJson = JSON.parse(smartfileOciLayoutJson.contents.toString());
|
const ociLayoutJson = JSON.parse(
|
||||||
const repositoriesJson = JSON.parse(smartfileRepositoriesJson.contents.toString());
|
smartfileOciLayoutJson.contents.toString(),
|
||||||
|
);
|
||||||
|
const repositoriesJson = JSON.parse(
|
||||||
|
smartfileRepositoriesJson.contents.toString(),
|
||||||
|
);
|
||||||
|
|
||||||
indexJson.manifests[0].annotations['io.containerd.image.name'] = imageName;
|
indexJson.manifests[0].annotations['io.containerd.image.name'] = imageName;
|
||||||
manifestJson[0].RepoTags[0] = imageName;
|
manifestJson[0].RepoTags[0] = imageName;
|
||||||
@@ -62,10 +93,18 @@ export class DockerImageStore {
|
|||||||
repositoriesJson[imageName] = repoFirstValue;
|
repositoriesJson[imageName] = repoFirstValue;
|
||||||
delete repositoriesJson[repoFirstKey];
|
delete repositoriesJson[repoFirstKey];
|
||||||
|
|
||||||
smartfileIndexJson.contents = Buffer.from(JSON.stringify(indexJson, null, 2));
|
smartfileIndexJson.contents = Buffer.from(
|
||||||
smartfileManifestJson.contents = Buffer.from(JSON.stringify(manifestJson, null, 2));
|
JSON.stringify(indexJson, null, 2),
|
||||||
smartfileOciLayoutJson.contents = Buffer.from(JSON.stringify(ociLayoutJson, null, 2));
|
);
|
||||||
smartfileRepositoriesJson.contents = Buffer.from(JSON.stringify(repositoriesJson, 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([
|
await Promise.all([
|
||||||
smartfileIndexJson.write(),
|
smartfileIndexJson.write(),
|
||||||
smartfileManifestJson.write(),
|
smartfileManifestJson.write(),
|
||||||
@@ -77,8 +116,12 @@ export class DockerImageStore {
|
|||||||
const tartools = new plugins.smartarchive.TarTools();
|
const tartools = new plugins.smartarchive.TarTools();
|
||||||
const newTarPack = await tartools.packDirectory(extractionDir);
|
const newTarPack = await tartools.packDirectory(extractionDir);
|
||||||
const finalTarName = `${uniqueProcessingId}.processed.tar`;
|
const finalTarName = `${uniqueProcessingId}.processed.tar`;
|
||||||
const finalTarPath = plugins.path.join(this.options.localDirPath, finalTarName);
|
const finalTarPath = plugins.path.join(
|
||||||
const finalWriteStream = plugins.smartfile.fsStream.createWriteStream(finalTarPath);
|
this.options.localDirPath,
|
||||||
|
finalTarName,
|
||||||
|
);
|
||||||
|
const finalWriteStream =
|
||||||
|
plugins.smartfile.fsStream.createWriteStream(finalTarPath);
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
newTarPack.finalize();
|
newTarPack.finalize();
|
||||||
newTarPack.pipe(finalWriteStream);
|
newTarPack.pipe(finalWriteStream);
|
||||||
@@ -87,7 +130,8 @@ export class DockerImageStore {
|
|||||||
});
|
});
|
||||||
logger.log('ok', `Repackaged image ${imageName} for s3.`);
|
logger.log('ok', `Repackaged image ${imageName} for s3.`);
|
||||||
await plugins.smartfile.fs.remove(extractionDir);
|
await plugins.smartfile.fs.remove(extractionDir);
|
||||||
const finalTarReadStream = plugins.smartfile.fsStream.createReadStream(finalTarPath);
|
const finalTarReadStream =
|
||||||
|
plugins.smartfile.fsStream.createReadStream(finalTarPath);
|
||||||
await this.options.bucketDir.fastPutStream({
|
await this.options.bucketDir.fastPutStream({
|
||||||
stream: finalTarReadStream,
|
stream: finalTarReadStream,
|
||||||
path: `${imageName}.tar`,
|
path: `${imageName}.tar`,
|
||||||
@@ -102,8 +146,13 @@ export class DockerImageStore {
|
|||||||
public async stop() {}
|
public async stop() {}
|
||||||
|
|
||||||
// Method to retrieve tar stream
|
// Method to retrieve tar stream
|
||||||
public async getImage(imageName: string): Promise<plugins.smartstream.stream.Readable> {
|
public async getImage(
|
||||||
const imagePath = plugins.path.join(this.options.localDirPath, `${imageName}.tar`);
|
imageName: string,
|
||||||
|
): Promise<plugins.smartstream.stream.Readable> {
|
||||||
|
const imagePath = plugins.path.join(
|
||||||
|
this.options.localDirPath,
|
||||||
|
`${imageName}.tar`,
|
||||||
|
);
|
||||||
|
|
||||||
if (!(await plugins.smartfile.fs.fileExists(imagePath))) {
|
if (!(await plugins.smartfile.fs.fileExists(imagePath))) {
|
||||||
throw new Error(`Image ${imageName} does not exist.`);
|
throw new Error(`Image ${imageName} does not exist.`);
|
||||||
|
@@ -6,7 +6,9 @@ import { DockerService } from './classes.service.js';
|
|||||||
import { logger } from './logger.js';
|
import { logger } from './logger.js';
|
||||||
|
|
||||||
export class DockerNetwork {
|
export class DockerNetwork {
|
||||||
public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> {
|
public static async getNetworks(
|
||||||
|
dockerHost: DockerHost,
|
||||||
|
): Promise<DockerNetwork[]> {
|
||||||
const dockerNetworks: DockerNetwork[] = [];
|
const dockerNetworks: DockerNetwork[] = [];
|
||||||
const response = await dockerHost.request('GET', '/networks');
|
const response = await dockerHost.request('GET', '/networks');
|
||||||
for (const networkObject of response.body) {
|
for (const networkObject of response.body) {
|
||||||
@@ -17,14 +19,19 @@ export class DockerNetwork {
|
|||||||
return dockerNetworks;
|
return dockerNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getNetworkByName(dockerHost: DockerHost, dockerNetworkNameArg: string) {
|
public static async getNetworkByName(
|
||||||
|
dockerHost: DockerHost,
|
||||||
|
dockerNetworkNameArg: string,
|
||||||
|
) {
|
||||||
const networks = await DockerNetwork.getNetworks(dockerHost);
|
const networks = await DockerNetwork.getNetworks(dockerHost);
|
||||||
return networks.find((dockerNetwork) => dockerNetwork.Name === dockerNetworkNameArg);
|
return networks.find(
|
||||||
|
(dockerNetwork) => dockerNetwork.Name === dockerNetworkNameArg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async createNetwork(
|
public static async createNetwork(
|
||||||
dockerHost: DockerHost,
|
dockerHost: DockerHost,
|
||||||
networkCreationDescriptor: interfaces.INetworkCreationDescriptor
|
networkCreationDescriptor: interfaces.INetworkCreationDescriptor,
|
||||||
): Promise<DockerNetwork> {
|
): Promise<DockerNetwork> {
|
||||||
const response = await dockerHost.request('POST', '/networks/create', {
|
const response = await dockerHost.request('POST', '/networks/create', {
|
||||||
Name: networkCreationDescriptor.Name,
|
Name: networkCreationDescriptor.Name,
|
||||||
@@ -47,9 +54,15 @@ export class DockerNetwork {
|
|||||||
});
|
});
|
||||||
if (response.statusCode < 300) {
|
if (response.statusCode < 300) {
|
||||||
logger.log('info', 'Created network successfully');
|
logger.log('info', 'Created network successfully');
|
||||||
return await DockerNetwork.getNetworkByName(dockerHost, networkCreationDescriptor.Name);
|
return await DockerNetwork.getNetworkByName(
|
||||||
|
dockerHost,
|
||||||
|
networkCreationDescriptor.Name,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
logger.log('error', 'There has been an error creating the wanted network');
|
logger.log(
|
||||||
|
'error',
|
||||||
|
'There has been an error creating the wanted network',
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +88,7 @@ export class DockerNetwork {
|
|||||||
Subnet: string;
|
Subnet: string;
|
||||||
IPRange: string;
|
IPRange: string;
|
||||||
Gateway: string;
|
Gateway: string;
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,7 +100,10 @@ export class DockerNetwork {
|
|||||||
* removes the network
|
* removes the network
|
||||||
*/
|
*/
|
||||||
public async remove() {
|
public async remove() {
|
||||||
const response = await this.dockerHost.request('DELETE', `/networks/${this.Id}`);
|
const response = await this.dockerHost.request(
|
||||||
|
'DELETE',
|
||||||
|
`/networks/${this.Id}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getContainersOnNetwork(): Promise<
|
public async getContainersOnNetwork(): Promise<
|
||||||
@@ -100,7 +116,10 @@ export class DockerNetwork {
|
|||||||
}>
|
}>
|
||||||
> {
|
> {
|
||||||
const returnArray = [];
|
const returnArray = [];
|
||||||
const response = await this.dockerHost.request('GET', `/networks/${this.Id}`);
|
const response = await this.dockerHost.request(
|
||||||
|
'GET',
|
||||||
|
`/networks/${this.Id}`,
|
||||||
|
);
|
||||||
for (const key of Object.keys(response.body.Containers)) {
|
for (const key of Object.keys(response.body.Containers)) {
|
||||||
returnArray.push(response.body.Containers[key]);
|
returnArray.push(response.body.Containers[key]);
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,17 @@ export class DockerSecret {
|
|||||||
return secrets.find((secret) => secret.ID === idArg);
|
return secrets.find((secret) => secret.ID === idArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getSecretByName(dockerHostArg: DockerHost, nameArg: string) {
|
public static async getSecretByName(
|
||||||
|
dockerHostArg: DockerHost,
|
||||||
|
nameArg: string,
|
||||||
|
) {
|
||||||
const secrets = await this.getSecrets(dockerHostArg);
|
const secrets = await this.getSecrets(dockerHostArg);
|
||||||
return secrets.find((secret) => secret.Spec.Name === nameArg);
|
return secrets.find((secret) => secret.Spec.Name === nameArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async createSecret(
|
public static async createSecret(
|
||||||
dockerHostArg: DockerHost,
|
dockerHostArg: DockerHost,
|
||||||
secretDescriptor: interfaces.ISecretCreationDescriptor
|
secretDescriptor: interfaces.ISecretCreationDescriptor,
|
||||||
) {
|
) {
|
||||||
const labels: interfaces.TLabels = {
|
const labels: interfaces.TLabels = {
|
||||||
...secretDescriptor.labels,
|
...secretDescriptor.labels,
|
||||||
@@ -45,7 +48,7 @@ export class DockerSecret {
|
|||||||
Object.assign(newSecretInstance, response.body);
|
Object.assign(newSecretInstance, response.body);
|
||||||
Object.assign(
|
Object.assign(
|
||||||
newSecretInstance,
|
newSecretInstance,
|
||||||
await DockerSecret.getSecretByID(dockerHostArg, newSecretInstance.ID)
|
await DockerSecret.getSecretByID(dockerHostArg, newSecretInstance.ID),
|
||||||
);
|
);
|
||||||
return newSecretInstance;
|
return newSecretInstance;
|
||||||
}
|
}
|
||||||
@@ -77,7 +80,7 @@ export class DockerSecret {
|
|||||||
Name: this.Spec.Name,
|
Name: this.Spec.Name,
|
||||||
Labels: this.Spec.Labels,
|
Labels: this.Spec.Labels,
|
||||||
Data: plugins.smartstring.base64.encode(contentArg),
|
Data: plugins.smartstring.base64.encode(contentArg),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ export class DockerService {
|
|||||||
|
|
||||||
public static async getServiceByName(
|
public static async getServiceByName(
|
||||||
dockerHost: DockerHost,
|
dockerHost: DockerHost,
|
||||||
networkName: string
|
networkName: string,
|
||||||
): Promise<DockerService> {
|
): Promise<DockerService> {
|
||||||
const allServices = await DockerService.getServices(dockerHost);
|
const allServices = await DockerService.getServices(dockerHost);
|
||||||
const wantedService = allServices.find((service) => {
|
const wantedService = allServices.find((service) => {
|
||||||
@@ -35,10 +35,13 @@ export class DockerService {
|
|||||||
*/
|
*/
|
||||||
public static async createService(
|
public static async createService(
|
||||||
dockerHost: DockerHost,
|
dockerHost: DockerHost,
|
||||||
serviceCreationDescriptor: interfaces.IServiceCreationDescriptor
|
serviceCreationDescriptor: interfaces.IServiceCreationDescriptor,
|
||||||
): Promise<DockerService> {
|
): Promise<DockerService> {
|
||||||
// lets get the image
|
// lets get the image
|
||||||
logger.log('info', `now creating service ${serviceCreationDescriptor.name}`);
|
logger.log(
|
||||||
|
'info',
|
||||||
|
`now creating service ${serviceCreationDescriptor.name}`,
|
||||||
|
);
|
||||||
|
|
||||||
// await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
|
// await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
|
||||||
const serviceVersion = await serviceCreationDescriptor.image.getVersion();
|
const serviceVersion = await serviceCreationDescriptor.image.getVersion();
|
||||||
@@ -71,8 +74,12 @@ export class DockerService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serviceCreationDescriptor.resources && serviceCreationDescriptor.resources.volumeMounts) {
|
if (
|
||||||
for (const volumeMount of serviceCreationDescriptor.resources.volumeMounts) {
|
serviceCreationDescriptor.resources &&
|
||||||
|
serviceCreationDescriptor.resources.volumeMounts
|
||||||
|
) {
|
||||||
|
for (const volumeMount of serviceCreationDescriptor.resources
|
||||||
|
.volumeMounts) {
|
||||||
mounts.push({
|
mounts.push({
|
||||||
Target: volumeMount.containerFsPath,
|
Target: volumeMount.containerFsPath,
|
||||||
Source: volumeMount.hostFsPath,
|
Source: volumeMount.hostFsPath,
|
||||||
@@ -89,6 +96,11 @@ export class DockerService {
|
|||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
for (const network of serviceCreationDescriptor.networks) {
|
for (const network of serviceCreationDescriptor.networks) {
|
||||||
|
// Skip null networks (can happen if network creation fails)
|
||||||
|
if (!network) {
|
||||||
|
logger.log('warn', 'Skipping null network in service creation');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
networkArray.push({
|
networkArray.push({
|
||||||
Target: network.Name,
|
Target: network.Name,
|
||||||
Aliases: [serviceCreationDescriptor.networkAlias],
|
Aliases: [serviceCreationDescriptor.networkAlias],
|
||||||
@@ -125,7 +137,8 @@ export class DockerService {
|
|||||||
// lets configure limits
|
// lets configure limits
|
||||||
|
|
||||||
const memoryLimitMB =
|
const memoryLimitMB =
|
||||||
serviceCreationDescriptor.resources && serviceCreationDescriptor.resources.memorySizeMB
|
serviceCreationDescriptor.resources &&
|
||||||
|
serviceCreationDescriptor.resources.memorySizeMB
|
||||||
? serviceCreationDescriptor.resources.memorySizeMB
|
? serviceCreationDescriptor.resources.memorySizeMB
|
||||||
: 1000;
|
: 1000;
|
||||||
|
|
||||||
@@ -134,7 +147,8 @@ export class DockerService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (serviceCreationDescriptor.resources) {
|
if (serviceCreationDescriptor.resources) {
|
||||||
limits.MemoryBytes = serviceCreationDescriptor.resources.memorySizeMB * 1000000;
|
limits.MemoryBytes =
|
||||||
|
serviceCreationDescriptor.resources.memorySizeMB * 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await dockerHost.request('POST', '/services/create', {
|
const response = await dockerHost.request('POST', '/services/create', {
|
||||||
@@ -177,7 +191,7 @@ export class DockerService {
|
|||||||
|
|
||||||
const createdService = await DockerService.getServiceByName(
|
const createdService = await DockerService.getServiceByName(
|
||||||
dockerHost,
|
dockerHost,
|
||||||
serviceCreationDescriptor.name
|
serviceCreationDescriptor.name,
|
||||||
);
|
);
|
||||||
return createdService;
|
return createdService;
|
||||||
}
|
}
|
||||||
@@ -223,7 +237,10 @@ export class DockerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async reReadFromDockerEngine() {
|
public async reReadFromDockerEngine() {
|
||||||
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
|
const dockerData = await this.dockerHostRef.request(
|
||||||
|
'GET',
|
||||||
|
`/services/${this.ID}`,
|
||||||
|
);
|
||||||
// TODO: Better assign: Object.assign(this, dockerData);
|
// TODO: Better assign: Object.assign(this, dockerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,14 +248,21 @@ export class DockerService {
|
|||||||
// TODO: implement digest based update recognition
|
// TODO: implement digest based update recognition
|
||||||
|
|
||||||
await this.reReadFromDockerEngine();
|
await this.reReadFromDockerEngine();
|
||||||
const dockerImage = await DockerImage.createFromRegistry(this.dockerHostRef, {
|
const dockerImage = await DockerImage.createFromRegistry(
|
||||||
creationObject: {
|
this.dockerHostRef,
|
||||||
imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image,
|
{
|
||||||
}
|
creationObject: {
|
||||||
});
|
imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
|
const imageVersion = new plugins.smartversion.SmartVersion(
|
||||||
const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version);
|
dockerImage.Labels.version,
|
||||||
|
);
|
||||||
|
const serviceVersion = new plugins.smartversion.SmartVersion(
|
||||||
|
this.Spec.Labels.version,
|
||||||
|
);
|
||||||
if (imageVersion.greaterThan(serviceVersion)) {
|
if (imageVersion.greaterThan(serviceVersion)) {
|
||||||
console.log(`service ${this.Spec.Name} needs to be updated`);
|
console.log(`service ${this.Spec.Name} needs to be updated`);
|
||||||
return true;
|
return true;
|
||||||
|
@@ -2,7 +2,7 @@ import * as plugins from './plugins.js';
|
|||||||
|
|
||||||
export const packageDir = plugins.path.resolve(
|
export const packageDir = plugins.path.resolve(
|
||||||
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
||||||
'../'
|
'../',
|
||||||
);
|
);
|
||||||
|
|
||||||
export const nogitDir = plugins.path.resolve(packageDir, '.nogit/');
|
export const nogitDir = plugins.path.resolve(packageDir, '.nogit/');
|
||||||
|
@@ -6,9 +6,9 @@
|
|||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"moduleResolution": "NodeNext",
|
"moduleResolution": "NodeNext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"verbatimModuleSyntax": true
|
"verbatimModuleSyntax": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {}
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": ["dist_*/**/*.d.ts"]
|
||||||
"dist_*/**/*.d.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user