bucketfs 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -5
- package/bin/cli.js +61 -0
- package/install.js +116 -0
- package/package.json +28 -7
- package/dist/index.js +0 -9
package/README.md
CHANGED
|
@@ -1,16 +1,79 @@
|
|
|
1
|
-
#
|
|
1
|
+
# bucketfs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Command-line interface for managing Training Pipes resources.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install
|
|
8
|
+
npm install -g bucketfs
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Or run directly with npx:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npx bucketfs <command>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Authenticate
|
|
21
|
+
bucketfs login
|
|
22
|
+
|
|
23
|
+
# List projects
|
|
24
|
+
bucketfs projects list
|
|
25
|
+
|
|
26
|
+
# Create a project
|
|
27
|
+
bucketfs projects create --name my-project
|
|
28
|
+
|
|
29
|
+
# Create a storage connection
|
|
30
|
+
bucketfs connections create \
|
|
31
|
+
--project <project-id> \
|
|
32
|
+
--provider aws \
|
|
33
|
+
--uri s3://my-bucket/prefix \
|
|
34
|
+
--region aws:us-east-1
|
|
35
|
+
|
|
36
|
+
# Create and start a mount
|
|
37
|
+
bucketfs mounts create \
|
|
38
|
+
--project <project-id> \
|
|
39
|
+
--connection <connection-id> \
|
|
40
|
+
--region us-east-1
|
|
41
|
+
|
|
42
|
+
bucketfs mounts start <mount-id>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Commands
|
|
46
|
+
|
|
47
|
+
| Command | Description |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `bucketfs login` | Store authentication token |
|
|
50
|
+
| `bucketfs logout` | Remove stored token |
|
|
51
|
+
| `bucketfs config show` | Show current configuration |
|
|
52
|
+
| `bucketfs config set-api-url <url>` | Set API base URL |
|
|
53
|
+
| `bucketfs projects list` | List projects |
|
|
54
|
+
| `bucketfs projects create --name <n>` | Create a project |
|
|
55
|
+
| `bucketfs projects get <id>` | Get project details |
|
|
56
|
+
| `bucketfs projects delete <id>` | Delete a project |
|
|
57
|
+
| `bucketfs connections list --project <id>` | List connections |
|
|
58
|
+
| `bucketfs connections create ...` | Create a connection |
|
|
59
|
+
| `bucketfs connections get <id>` | Get connection details |
|
|
60
|
+
| `bucketfs connections delete <id>` | Delete a connection |
|
|
61
|
+
| `bucketfs connections verify <id>` | Verify a connection |
|
|
62
|
+
| `bucketfs mounts list --project <id>` | List mounts |
|
|
63
|
+
| `bucketfs mounts create ...` | Create a mount |
|
|
64
|
+
| `bucketfs mounts get <id>` | Get mount details |
|
|
65
|
+
| `bucketfs mounts start <id>` | Start a mount |
|
|
66
|
+
| `bucketfs mounts stop <id>` | Stop a mount |
|
|
67
|
+
| `bucketfs mounts delete <id>` | Delete a mount |
|
|
68
|
+
| `bucketfs mounts flush <id>` | Trigger a flush |
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
Config is stored at `~/.bucketfs/config.json`. You can also use:
|
|
73
|
+
|
|
74
|
+
- `--api-url` flag to override the API base URL per-command
|
|
75
|
+
- `--token` flag to override the auth token per-command
|
|
76
|
+
- `BUCKETFS_TOKEN` environment variable
|
|
14
77
|
|
|
15
78
|
## License
|
|
16
79
|
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
const PLATFORM_PACKAGES = {
|
|
8
|
+
"darwin-arm64": "@bucketfs/cli-darwin-arm64",
|
|
9
|
+
"darwin-x64": "@bucketfs/cli-darwin-x64",
|
|
10
|
+
"linux-arm64": "@bucketfs/cli-linux-arm64",
|
|
11
|
+
"linux-x64": "@bucketfs/cli-linux-x64",
|
|
12
|
+
"win32-x64": "@bucketfs/cli-win32-x64",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function getBinaryName() {
|
|
16
|
+
return process.platform === "win32" ? "bucketfs.exe" : "bucketfs";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getBinaryPath() {
|
|
20
|
+
const platformKey = `${process.platform}-${process.arch}`;
|
|
21
|
+
const pkgName = PLATFORM_PACKAGES[platformKey];
|
|
22
|
+
const binaryName = getBinaryName();
|
|
23
|
+
|
|
24
|
+
if (!pkgName) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Unsupported platform: ${platformKey}. ` +
|
|
27
|
+
`Supported: ${Object.keys(PLATFORM_PACKAGES).join(", ")}`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Try optionalDependency first
|
|
32
|
+
try {
|
|
33
|
+
return require.resolve(`${pkgName}/bin/${binaryName}`);
|
|
34
|
+
} catch (_) {
|
|
35
|
+
// Fall through to fallback
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Try fallback binary (downloaded by postinstall)
|
|
39
|
+
const fallback = path.join(__dirname, "..", binaryName);
|
|
40
|
+
if (fs.existsSync(fallback)) {
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Could not find the bucketfs binary. The platform package ${pkgName} ` +
|
|
46
|
+
`was not installed and no fallback binary was found.\n\n` +
|
|
47
|
+
`Try reinstalling: npm install bucketfs\n` +
|
|
48
|
+
`Or ensure optionalDependencies are enabled.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const binary = getBinaryPath();
|
|
54
|
+
execFileSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
55
|
+
} catch (err) {
|
|
56
|
+
if (err.status !== undefined) {
|
|
57
|
+
process.exit(err.status);
|
|
58
|
+
}
|
|
59
|
+
console.error(err.message);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
package/install.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const zlib = require("zlib");
|
|
4
|
+
const https = require("https");
|
|
5
|
+
|
|
6
|
+
const PLATFORM_PACKAGES = {
|
|
7
|
+
"darwin-arm64": "@bucketfs/cli-darwin-arm64",
|
|
8
|
+
"darwin-x64": "@bucketfs/cli-darwin-x64",
|
|
9
|
+
"linux-arm64": "@bucketfs/cli-linux-arm64",
|
|
10
|
+
"linux-x64": "@bucketfs/cli-linux-x64",
|
|
11
|
+
"win32-x64": "@bucketfs/cli-win32-x64",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const VERSION = require("./package.json").version;
|
|
15
|
+
|
|
16
|
+
const binaryName =
|
|
17
|
+
process.platform === "win32" ? "bucketfs.exe" : "bucketfs";
|
|
18
|
+
|
|
19
|
+
const platformKey = `${process.platform}-${process.arch}`;
|
|
20
|
+
const platformPackage = PLATFORM_PACKAGES[platformKey];
|
|
21
|
+
|
|
22
|
+
if (!platformPackage) {
|
|
23
|
+
console.error(`bucketfs: unsupported platform ${platformKey}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isPlatformPackageInstalled() {
|
|
28
|
+
try {
|
|
29
|
+
require.resolve(`${platformPackage}/bin/${binaryName}`);
|
|
30
|
+
return true;
|
|
31
|
+
} catch (_) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function makeRequest(url) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
https
|
|
39
|
+
.get(url, (response) => {
|
|
40
|
+
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
41
|
+
const chunks = [];
|
|
42
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
43
|
+
response.on("end", () => resolve(Buffer.concat(chunks)));
|
|
44
|
+
} else if (
|
|
45
|
+
response.statusCode >= 300 &&
|
|
46
|
+
response.statusCode < 400 &&
|
|
47
|
+
response.headers.location
|
|
48
|
+
) {
|
|
49
|
+
makeRequest(response.headers.location).then(resolve, reject);
|
|
50
|
+
} else {
|
|
51
|
+
reject(
|
|
52
|
+
new Error(
|
|
53
|
+
`npm registry responded with HTTP ${response.statusCode}`
|
|
54
|
+
)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.on("error", reject);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function extractFileFromTarball(tarballBuffer, filepath) {
|
|
63
|
+
let offset = 0;
|
|
64
|
+
while (offset < tarballBuffer.length) {
|
|
65
|
+
const header = tarballBuffer.subarray(offset, offset + 512);
|
|
66
|
+
offset += 512;
|
|
67
|
+
|
|
68
|
+
const fileName = header.toString("utf-8", 0, 100).replace(/\0.*/g, "");
|
|
69
|
+
const fileSize = parseInt(
|
|
70
|
+
header.toString("utf-8", 124, 136).replace(/\0.*/g, ""),
|
|
71
|
+
8
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (isNaN(fileSize)) break;
|
|
75
|
+
|
|
76
|
+
if (fileName === filepath) {
|
|
77
|
+
return tarballBuffer.subarray(offset, offset + fileSize);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
offset = (offset + fileSize + 511) & ~511;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function downloadBinaryFromNpm() {
|
|
86
|
+
const scopedName = platformPackage.replace("@", "").replace("/", "-");
|
|
87
|
+
const url = `https://registry.npmjs.org/${platformPackage}/-/${scopedName}-${VERSION}.tgz`;
|
|
88
|
+
|
|
89
|
+
console.log(`bucketfs: downloading ${platformPackage}@${VERSION}...`);
|
|
90
|
+
|
|
91
|
+
const tarballGz = await makeRequest(url);
|
|
92
|
+
const tarball = zlib.unzipSync(tarballGz);
|
|
93
|
+
|
|
94
|
+
const binary = extractFileFromTarball(tarball, `package/bin/${binaryName}`);
|
|
95
|
+
if (!binary) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Could not find bin/${binaryName} in the downloaded package`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const dest = path.join(__dirname, binaryName);
|
|
102
|
+
fs.writeFileSync(dest, binary, { mode: 0o755 });
|
|
103
|
+
console.log(`bucketfs: binary installed to ${dest}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (isPlatformPackageInstalled()) {
|
|
107
|
+
// Already installed via optionalDependencies
|
|
108
|
+
process.exit(0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
downloadBinaryFromNpm().catch((err) => {
|
|
112
|
+
console.warn(
|
|
113
|
+
`bucketfs: failed to download binary (${err.message}). ` +
|
|
114
|
+
`The CLI may not work until a binary is available.`
|
|
115
|
+
);
|
|
116
|
+
});
|
package/package.json
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bucketfs",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "BucketFS CLI - manage Training Pipes resources from the command line",
|
|
5
|
+
"files": [
|
|
6
|
+
"bin/",
|
|
7
|
+
"install.js",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
10
|
+
"bin": {
|
|
11
|
+
"bucketfs": "bin/cli.js"
|
|
12
|
+
},
|
|
6
13
|
"scripts": {
|
|
7
|
-
"
|
|
14
|
+
"postinstall": "node install.js"
|
|
15
|
+
},
|
|
16
|
+
"optionalDependencies": {
|
|
17
|
+
"@bucketfs/cli-darwin-arm64": "0.0.2",
|
|
18
|
+
"@bucketfs/cli-darwin-x64": "0.0.2",
|
|
19
|
+
"@bucketfs/cli-linux-arm64": "0.0.2",
|
|
20
|
+
"@bucketfs/cli-linux-x64": "0.0.2",
|
|
21
|
+
"@bucketfs/cli-win32-x64": "0.0.2"
|
|
8
22
|
},
|
|
9
23
|
"keywords": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
24
|
+
"bucketfs",
|
|
25
|
+
"training-pipes",
|
|
26
|
+
"cli",
|
|
27
|
+
"storage",
|
|
28
|
+
"mount",
|
|
12
29
|
"AI"
|
|
13
30
|
],
|
|
14
31
|
"author": "Training Pipes",
|
|
15
|
-
"license": "UNLICENSED"
|
|
32
|
+
"license": "UNLICENSED",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/pwgardipee/training-pipes"
|
|
36
|
+
}
|
|
16
37
|
}
|