@quantum-hub/qhubctl 1.8.0 → 1.8.1
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/dist/commands/init.js
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'fs-extra';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { DEFAULT_STARTER, promptUserInput } from '../lib/init-user-input.js';
|
|
5
5
|
import { randomName } from '../lib/random-name.js';
|
|
6
|
-
import { cloneRepository
|
|
6
|
+
import { cloneRepository } from '../lib/repository.js';
|
|
7
7
|
import { error, stdout } from '../lib/output.js';
|
|
8
8
|
import { Runtime } from '../model/managed-service-config.js';
|
|
9
9
|
import { writeServiceConfig } from '../service/service-config-service.js';
|
|
@@ -52,18 +52,11 @@ export const initCommand = new Command('init')
|
|
|
52
52
|
}
|
|
53
53
|
writeServiceConfig(targetDirectory, serviceConfig);
|
|
54
54
|
if (input.starter) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
error('This starter template requires authentication. Use the "login" command to log in first.');
|
|
59
|
-
}
|
|
60
|
-
await cloneRepository(input.starter.url, targetDirectory, userConfig.auth.value);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
const zip = await downloadRepository(input.starter.url);
|
|
64
|
-
const starterName = path.basename(input.starter.url, '.zip');
|
|
65
|
-
extractStarter(zip, starterName, targetDirectory);
|
|
55
|
+
const userConfig = getUserConfig();
|
|
56
|
+
if (!userConfig.auth?.value) {
|
|
57
|
+
error('Starter templates require authentication. Use the "login" command to log in first.');
|
|
66
58
|
}
|
|
59
|
+
await cloneRepository(input.starter.url, targetDirectory, userConfig.auth.value);
|
|
67
60
|
}
|
|
68
61
|
stdout('\u{1F389} Initialized project. Happy hacking!');
|
|
69
62
|
if (input.starter) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { input, select, number } from '@inquirer/prompts';
|
|
2
2
|
import { GpuType, Runtime } from '../model/managed-service-config.js';
|
|
3
3
|
export const DEFAULT_STARTER = {
|
|
4
|
-
url: 'https://
|
|
4
|
+
url: 'https://repository.hub.kipu-quantum.com/cec4a31d-5856-4387-b4cf-718345803558/qhub-starter-python.git',
|
|
5
5
|
runtime: Runtime.PYTHON_TEMPLATE,
|
|
6
6
|
};
|
|
7
7
|
export const promptUserInput = async (defaultName) => {
|
|
@@ -21,7 +21,6 @@ export const promptUserInput = async (defaultName) => {
|
|
|
21
21
|
value: {
|
|
22
22
|
url: 'https://repository.hub.kipu-quantum.com/cec4a31d-5856-4387-b4cf-718345803558/qhub-starter-docker.git',
|
|
23
23
|
runtime: Runtime.DOCKER,
|
|
24
|
-
requiresAuth: true,
|
|
25
24
|
},
|
|
26
25
|
},
|
|
27
26
|
{
|
|
@@ -29,7 +28,6 @@ export const promptUserInput = async (defaultName) => {
|
|
|
29
28
|
value: {
|
|
30
29
|
url: 'https://repository.hub.kipu-quantum.com/cec4a31d-5856-4387-b4cf-718345803558/qhub-starter-gpu.git',
|
|
31
30
|
runtime: Runtime.DOCKER,
|
|
32
|
-
requiresAuth: true,
|
|
33
31
|
},
|
|
34
32
|
},
|
|
35
33
|
{ name: 'None (creates "qhub.json" in current directory)', value: undefined },
|
package/dist/lib/repository.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import AdmZip from 'adm-zip';
|
|
2
|
-
export declare const downloadRepository: (url: string, apiKey?: string) => Promise<AdmZip>;
|
|
3
1
|
/**
|
|
4
2
|
* Clones a git repository (shallow, depth=1) into targetDirectory and removes
|
|
5
3
|
* the .git metadata afterwards, leaving only the working-tree files.
|
|
6
4
|
*
|
|
7
|
-
* Authentication uses HTTP Basic Auth with username "
|
|
5
|
+
* Authentication uses HTTP Basic Auth with username "qhubctl" and the provided
|
|
8
6
|
* API key as the password.
|
|
9
7
|
*/
|
|
10
8
|
export declare const cloneRepository: (url: string, targetDirectory: string, apiKey: string) => Promise<void>;
|
|
11
|
-
export declare const extractStarter: (zip: AdmZip, starterName: string, targetDirectory: string) => void;
|
package/dist/lib/repository.js
CHANGED
|
@@ -1,47 +1,12 @@
|
|
|
1
|
-
import AdmZip from 'adm-zip';
|
|
2
1
|
import fs from 'fs-extra';
|
|
3
2
|
import git from 'isomorphic-git';
|
|
4
3
|
import http from 'isomorphic-git/http/node';
|
|
5
4
|
import nodeFs from 'node:fs';
|
|
6
|
-
import { debugEnabled } from './debug.js';
|
|
7
|
-
import { fetchOrThrow, PlatformError } from './fetch.js';
|
|
8
|
-
export const downloadRepository = async (url, apiKey) => {
|
|
9
|
-
const headers = {};
|
|
10
|
-
if (apiKey) {
|
|
11
|
-
// Use HTTP Basic Auth: username "planqk", password is the API key
|
|
12
|
-
const credentials = Buffer.from(`qhubctl:${apiKey}`).toString('base64');
|
|
13
|
-
headers['Authorization'] = `Basic ${credentials}`;
|
|
14
|
-
}
|
|
15
|
-
const config = {
|
|
16
|
-
cache: 'no-cache',
|
|
17
|
-
method: 'GET',
|
|
18
|
-
mode: 'same-origin',
|
|
19
|
-
referrerPolicy: 'no-referrer',
|
|
20
|
-
headers,
|
|
21
|
-
};
|
|
22
|
-
let zip;
|
|
23
|
-
try {
|
|
24
|
-
const response = await fetchOrThrow(url, config);
|
|
25
|
-
const buffer = await response.arrayBuffer();
|
|
26
|
-
zip = new AdmZip(Buffer.from(buffer), {});
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
if (error instanceof PlatformError) {
|
|
30
|
-
const errorMessage = await error.getErrorMessage();
|
|
31
|
-
throw new Error(errorMessage);
|
|
32
|
-
}
|
|
33
|
-
if (debugEnabled()) {
|
|
34
|
-
console.error(JSON.stringify(error));
|
|
35
|
-
}
|
|
36
|
-
throw new Error('Internal error occurred, please contact your Quantum Hub administrator');
|
|
37
|
-
}
|
|
38
|
-
return zip;
|
|
39
|
-
};
|
|
40
5
|
/**
|
|
41
6
|
* Clones a git repository (shallow, depth=1) into targetDirectory and removes
|
|
42
7
|
* the .git metadata afterwards, leaving only the working-tree files.
|
|
43
8
|
*
|
|
44
|
-
* Authentication uses HTTP Basic Auth with username "
|
|
9
|
+
* Authentication uses HTTP Basic Auth with username "qhubctl" and the provided
|
|
45
10
|
* API key as the password.
|
|
46
11
|
*/
|
|
47
12
|
export const cloneRepository = async (url, targetDirectory, apiKey) => {
|
|
@@ -66,17 +31,3 @@ export const cloneRepository = async (url, targetDirectory, apiKey) => {
|
|
|
66
31
|
// Remove git metadata so the project directory is a clean working tree
|
|
67
32
|
await fs.remove(`${targetDirectory}/.git`);
|
|
68
33
|
};
|
|
69
|
-
export const extractStarter = (zip, starterName, targetDirectory) => {
|
|
70
|
-
const templateFolder = `${starterName}/`;
|
|
71
|
-
for (const entry of zip.getEntries()) {
|
|
72
|
-
if (!entry.isDirectory && entry.entryName.startsWith(templateFolder)) {
|
|
73
|
-
let destinationPath = targetDirectory;
|
|
74
|
-
// check if file is in sub-folder
|
|
75
|
-
if (entry.entryName.replace(templateFolder, '').includes('/')) {
|
|
76
|
-
const pathWithinFolder = entry.entryName.replace(templateFolder, '');
|
|
77
|
-
destinationPath = destinationPath + '/' + pathWithinFolder.slice(0, Math.max(0, pathWithinFolder.lastIndexOf('/')));
|
|
78
|
-
}
|
|
79
|
-
zip.extractEntryTo(entry.entryName, destinationPath, false, true);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
};
|