Skip to content
This repository was archived by the owner on Feb 20, 2026. It is now read-only.

Commit 54d16e8

Browse files
authored
Fix cvm upgrade compatible for dstack v05x (#59)
1 parent adb14db commit 54d16e8

4 files changed

Lines changed: 42 additions & 9 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "phala",
3-
"version": "1.0.27",
3+
"version": "1.0.34",
44
"description": "CLI for Managing Phala Cloud Services",
55
"author": {
66
"name": "Phala Network",

src/api/cvms.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,10 @@ export async function restartCvm(appId: string): Promise<PostCvmResponse> {
199199
* @returns Upgrade response
200200
*/
201201
export async function upgradeCvm(appId: string, vmConfig: VMConfig): Promise<UpgradeCvmResponse> {
202-
try {
203-
const apiKey = getApiKey();
204-
const apiClient = createClient({ apiKey: apiKey });
205-
const response = await apiClient.put<UpgradeCvmResponse>(API_ENDPOINTS.CVM_UPGRADE(appId), vmConfig);
206-
return upgradeCvmResponseSchema.parse(response);
207-
} catch (error) {
208-
throw new Error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);
209-
}
202+
const apiKey = getApiKey();
203+
const apiClient = createClient({ apiKey: apiKey });
204+
const response = await apiClient.put<UpgradeCvmResponse>(API_ENDPOINTS.CVM_UPGRADE(appId), vmConfig);
205+
return upgradeCvmResponseSchema.parse(response);
210206
}
211207

212208
/**

src/commands/cvms/upgrade.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Command } from 'commander';
2+
import { FetchError } from 'ofetch';
23
import { upgradeCvm, getCvmByAppId } from '@/src/api/cvms';
34
import { logger } from '@/src/utils/logger';
45
import fs from 'node:fs';
@@ -44,6 +45,7 @@ export const upgradeCommand = new Command()
4445

4546
// Update Docker Compose file if provided
4647
let composeString = '';
48+
let env_keys = [];
4749
if (options.compose) {
4850
try {
4951
composeString = fs.readFileSync(options.compose, 'utf8');
@@ -74,6 +76,7 @@ export const upgradeCommand = new Command()
7476
try {
7577
envs = parseEnv([], options.envFile);
7678
encrypted_env = await encryptEnvVars(envs, currentCvm.encrypted_env_pubkey);
79+
env_keys = envs.map(i => i.key)
7780
} catch (error) {
7881
logger.error(`Failed to read environment file: ${error instanceof Error ? error.message : String(error)}`);
7982
process.exit(1);
@@ -90,9 +93,11 @@ export const upgradeCommand = new Command()
9093
version: "1.0.0",
9194
features: ["kms", "tproxy-net"],
9295
name: `app_${resolvedAppId}`,
96+
allowed_envs: env_keys,
9397
},
9498
encrypted_env,
9599
allow_restart: true,
100+
env_keys: env_keys,
96101
};
97102

98103
// Upgrade the CVM
@@ -116,6 +121,28 @@ export const upgradeCommand = new Command()
116121
);
117122
} catch (error) {
118123
logger.error(`Failed to upgrade CVM: ${error instanceof Error ? error.message : String(error)}`);
124+
125+
// Multiple ways to check if it's a FetchError:
126+
// 1. instanceof check (standard but may fail due to module loading)
127+
// 2. Check constructor.name (works across module boundaries)
128+
// 3. Check for FetchError-specific properties (status, statusText, data, request)
129+
const isFetchError = error instanceof FetchError ||
130+
(error as any)?.constructor?.name === 'FetchError' ||
131+
(error && typeof error === 'object' && 'status' in error && 'statusText' in error && 'data' in error);
132+
133+
if (isFetchError) {
134+
const fetchError = error as FetchError;
135+
logger.error('=== HTTP Error Details ===');
136+
logger.error('Status:', fetchError.status);
137+
logger.error('Status Text:', fetchError.statusText);
138+
logger.error('URL:', fetchError.request);
139+
logger.error('Response Body:', JSON.stringify(fetchError.data, null, 2));
140+
if (options.debug) {
141+
logger.error('Full Error Object:', error);
142+
}
143+
} else if (options.debug) {
144+
logger.error('Full Error:', error);
145+
}
119146
process.exit(1);
120147
}
121148
});

src/commands/deploy/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ const updateCvm = async (validatedOptions: Options, docker_compose_yml: string,
531531
app_compose: app_compose as ProvisionCvmComposeFileUpdateRequest["app_compose"],
532532
});
533533
if (!provision_result.success) {
534+
if ("isRequestError" in provision_result.error) {
535+
console.error('HTTP Error:', provision_result.error.status, provision_result.error.statusText);
536+
console.error('Error message:', provision_result.error.message);
537+
console.error('Response body:', JSON.stringify(provision_result.error.data, null, 2));
538+
}
534539
throw new Error(`Failed to provision cvm compose file: ${provision_result.error.message}`);
535540
}
536541
const provision = provision_result.data as any;
@@ -571,6 +576,11 @@ const updateCvm = async (validatedOptions: Options, docker_compose_yml: string,
571576
const commitResult = await safeCommitCvmComposeFileUpdate(client, data);
572577

573578
if (!commitResult.success) {
579+
if ("isRequestError" in commitResult.error) {
580+
console.error('HTTP Error:', commitResult.error.status, commitResult.error.statusText);
581+
console.error('Error message:', commitResult.error.message);
582+
console.error('Response body:', JSON.stringify(commitResult.error.data, null, 2));
583+
}
574584
throw new Error(`Failed to commit CVM compose file update: ${commitResult.error.message}`);
575585
}
576586
if (validatedOptions?.json !== false) {

0 commit comments

Comments
 (0)