fix(changepackage): treat HTTP 200 as success and repair resource modify calls
VirtFusion v7's PUT /servers/{id}/package/{pkg} returns HTTP 200 (with an
{info:[...]} body), not 204. changePackage() only accepted 204, so every
successful package change fell through to the default case and reported
"Update package request failed. VirtFusion API returned HTTP 200" — the
exact error seen in production. The early return also skipped the
memory/CPU/traffic modify loop entirely.
- Accept 200 (and keep 204) as success; log the info array so operator can
see skipped changes (e.g. "primary disk not updated... lower than current").
- modifyResource(): send cpuCores as the spec-required "cores" body field
(wrong field name omitted the required property → CPU changes rejected).
- modifyResource(): accept 201 alongside 200/204 — VF v7 returns 201 Created
on modify, mirroring the existing rename-endpoint fix.
- Surface modifyResource() failures in the package-change loop instead of
swallowing them.
Disk-downgrade safety is unchanged and confirmed: no disk flag is sent, the
modify allowlist excludes storage, no disk-modify endpoint exists, and VF
itself refuses to shrink the primary disk.
Verified against the VirtFusion v7 OpenAPI spec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -789,12 +789,20 @@ class Module
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ctx['request']->addOption(CURLOPT_POSTFIELDS, json_encode([$resource => $value]));
|
// The /modify/{resource} endpoints name their body field differently from our
|
||||||
|
// internal resource key: cpuCores is sent as "cores" (memory/traffic match 1:1).
|
||||||
|
// Sending the wrong field name omits the required property and the change is rejected.
|
||||||
|
$fieldMap = ['memory' => 'memory', 'cpuCores' => 'cores', 'traffic' => 'traffic'];
|
||||||
|
$field = $fieldMap[$resource];
|
||||||
|
|
||||||
|
$ctx['request']->addOption(CURLOPT_POSTFIELDS, json_encode([$field => $value]));
|
||||||
$data = $ctx['request']->put($ctx['cp']['url'] . '/servers/' . $ctx['serverId'] . '/modify/' . $resource);
|
$data = $ctx['request']->put($ctx['cp']['url'] . '/servers/' . $ctx['serverId'] . '/modify/' . $resource);
|
||||||
Log::insert(__FUNCTION__ . ':' . $resource, $ctx['request']->getRequestInfo(), $data);
|
Log::insert(__FUNCTION__ . ':' . $resource, $ctx['request']->getRequestInfo(), $data);
|
||||||
|
|
||||||
$httpCode = $ctx['request']->getRequestInfo('http_code');
|
// VF v7 returns 201 (Created) on a successful modify; older builds returned 200/204.
|
||||||
if ($httpCode == 200 || $httpCode == 204) {
|
// Accept all three so we cover the version range (mirrors the rename-endpoint fix).
|
||||||
|
$httpCode = (int) $ctx['request']->getRequestInfo('http_code');
|
||||||
|
if ($httpCode == 200 || $httpCode == 201 || $httpCode == 204) {
|
||||||
return json_decode($data) ?: (object) ['success' => true];
|
return json_decode($data) ?: (object) ['success' => true];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -274,8 +274,18 @@ class ModuleFunctions extends Module
|
|||||||
|
|
||||||
Log::insert(__FUNCTION__, $request->getRequestInfo(), $data);
|
Log::insert(__FUNCTION__, $request->getRequestInfo(), $data);
|
||||||
|
|
||||||
switch ($request->getRequestInfo('http_code')) {
|
switch ((int) $request->getRequestInfo('http_code')) {
|
||||||
|
|
||||||
|
case 200:
|
||||||
|
// VirtFusion v7 returns 200 (with an {info:[...]} body) on a package change;
|
||||||
|
// older builds returned 204. The info array reports what was/wasn't synced
|
||||||
|
// from the new package — e.g. "primary disk not updated. It either matches or
|
||||||
|
// is lower than the current value" (the panel never shrinks a disk). Log it so
|
||||||
|
// an operator can see when a requested change was skipped.
|
||||||
|
if (isset($data->info) && is_array($data->info)) {
|
||||||
|
Log::insert(__FUNCTION__ . ':info', [], $data->info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 204:
|
case 204:
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
@@ -310,7 +320,11 @@ class ModuleFunctions extends Module
|
|||||||
if ($resource === 'memory' && $value < 1024) {
|
if ($resource === 'memory' && $value < 1024) {
|
||||||
$value = $value * 1024;
|
$value = $value * 1024;
|
||||||
}
|
}
|
||||||
$this->modifyResource($params['serviceid'], $resource, $value);
|
if ($this->modifyResource($params['serviceid'], $resource, $value) === false) {
|
||||||
|
// A single resource tweak failing shouldn't fail the whole package
|
||||||
|
// change, but the failure must not be silent — log it for the operator.
|
||||||
|
Log::insert(__FUNCTION__ . ':modifyFailed', ['resource' => $resource, 'value' => $value], 'modifyResource returned false');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user