@nosana/node 1.1.29 → 1.1.30-rc
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/package.json +1 -1
- package/dist/src/NodeManager/node/resource/resourceManager.d.ts +11 -1
- package/dist/src/NodeManager/node/resource/resourceManager.js +20 -1
- package/dist/src/NodeManager/node/resource/volume/volumeManager.js +15 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import { Market } from '@nosana/sdk';
|
|
1
|
+
import { Market, RequiredResource } from '@nosana/sdk';
|
|
2
2
|
import { Resource } from '@nosana/sdk/dist/types/resources.js';
|
|
3
3
|
import { ContainerOrchestrationInterface } from '../../provider/containerOrchestration/interface.js';
|
|
4
4
|
import { NodeRepository } from '../../repository/NodeRepository.js';
|
|
5
5
|
import { ImageManager } from './image/imageManager.js';
|
|
6
6
|
import { VolumeManager } from './volume/volumeManager.js';
|
|
7
|
+
/**
|
|
8
|
+
* The market endpoint reports an HF resource's model as `url`, the field it
|
|
9
|
+
* also uses for S3, while everywhere else in the node — job definitions
|
|
10
|
+
* included — an HF resource names it `repo`. Translate on the way in, so only
|
|
11
|
+
* one shape reaches the download path.
|
|
12
|
+
*
|
|
13
|
+
* Resources that already carry `repo` are left alone: this is the market
|
|
14
|
+
* boundary, but the same manager serves job resources.
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeMarketResources(resources: RequiredResource[]): RequiredResource[];
|
|
7
17
|
export declare class ResourceManager {
|
|
8
18
|
private containerOrchestration;
|
|
9
19
|
private repository;
|
|
@@ -2,6 +2,25 @@ import { HostManager } from '../market/hostManager.js';
|
|
|
2
2
|
import { createResourceName } from './helpers/createResourceName.js';
|
|
3
3
|
import { ImageManager } from './image/imageManager.js';
|
|
4
4
|
import { VolumeManager } from './volume/volumeManager.js';
|
|
5
|
+
/**
|
|
6
|
+
* The market endpoint reports an HF resource's model as `url`, the field it
|
|
7
|
+
* also uses for S3, while everywhere else in the node — job definitions
|
|
8
|
+
* included — an HF resource names it `repo`. Translate on the way in, so only
|
|
9
|
+
* one shape reaches the download path.
|
|
10
|
+
*
|
|
11
|
+
* Resources that already carry `repo` are left alone: this is the market
|
|
12
|
+
* boundary, but the same manager serves job resources.
|
|
13
|
+
*/
|
|
14
|
+
export function normalizeMarketResources(resources) {
|
|
15
|
+
return resources.map((resource) => {
|
|
16
|
+
if (resource.type !== 'HF')
|
|
17
|
+
return resource;
|
|
18
|
+
const hf = resource;
|
|
19
|
+
if (hf.repo || !hf.url)
|
|
20
|
+
return resource;
|
|
21
|
+
return { ...hf, repo: hf.url };
|
|
22
|
+
});
|
|
23
|
+
}
|
|
5
24
|
export class ResourceManager {
|
|
6
25
|
constructor(containerOrchestration, repository) {
|
|
7
26
|
this.containerOrchestration = containerOrchestration;
|
|
@@ -24,7 +43,7 @@ export class ResourceManager {
|
|
|
24
43
|
return;
|
|
25
44
|
}
|
|
26
45
|
await this.images.pullMarketRequiredImages(data.required_images);
|
|
27
|
-
await this.volumes.pullMarketRequiredVolumes(data.required_remote_resources);
|
|
46
|
+
await this.volumes.pullMarketRequiredVolumes(normalizeMarketResources(data.required_remote_resources));
|
|
28
47
|
}
|
|
29
48
|
catch (error) {
|
|
30
49
|
throw error;
|
|
@@ -36,7 +36,7 @@ function describeContainerState(state) {
|
|
|
36
36
|
* last such line, since a run may log several before giving up.
|
|
37
37
|
*/
|
|
38
38
|
export function findReportedError(logs) {
|
|
39
|
-
for (const log of logs.reverse()) {
|
|
39
|
+
for (const log of [...logs].reverse()) {
|
|
40
40
|
if (log.log?.includes('{"event":"error"')) {
|
|
41
41
|
try {
|
|
42
42
|
const parsed = JSON.parse(log.log.slice(log.log.indexOf('{')));
|
|
@@ -48,6 +48,14 @@ export function findReportedError(logs) {
|
|
|
48
48
|
}
|
|
49
49
|
return undefined;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* A resource rendered for an error message. Resources carry credentials (`IAM`,
|
|
53
|
+
* HF `accessToken`), and errors reach the logs and the support channel, so
|
|
54
|
+
* those fields are replaced rather than reported.
|
|
55
|
+
*/
|
|
56
|
+
function describeResource(resource) {
|
|
57
|
+
return JSON.stringify(resource, (key, value) => key === 'IAM' || key === 'accessToken' ? '[hidden]' : value);
|
|
58
|
+
}
|
|
51
59
|
export class VolumeManager {
|
|
52
60
|
constructor(containerOrchestration, repository) {
|
|
53
61
|
this.containerOrchestration = containerOrchestration;
|
|
@@ -74,6 +82,12 @@ export class VolumeManager {
|
|
|
74
82
|
}
|
|
75
83
|
async createRemoteVolume(resource, controller) {
|
|
76
84
|
const resourceName = createResourceName(resource);
|
|
85
|
+
// Checked before anything is allocated. Left to the download, an empty repo
|
|
86
|
+
// becomes a request for `/api/models//tree/main` and comes back as a bare
|
|
87
|
+
// 404 with nothing in it naming the resource at fault.
|
|
88
|
+
if (resource.type === 'HF' && !resource.repo) {
|
|
89
|
+
throw new Error(`missing repo for HF resource ${describeResource(resource)}`);
|
|
90
|
+
}
|
|
77
91
|
let volumeName = this.repository.getVolumeResource(resourceName)?.volume;
|
|
78
92
|
let sync = true;
|
|
79
93
|
if (!volumeName) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nosana/node",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30-rc",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@nosana/node",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.30-rc",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@coral-xyz/anchor": "^0.28.1-beta.1",
|