pr feedback
parent
896e8fb7e8
commit
54adcbb959
|
|
@ -4576,13 +4576,38 @@ class KubernetesStorage {
|
|||
}
|
||||
}
|
||||
static async watchUntilPVCNotPending(kubeClient, name, namespace) {
|
||||
let checkCount = 0;
|
||||
try {
|
||||
cloud_runner_logger_1.default.log(`watch Until PVC Not Pending ${name} ${namespace}`);
|
||||
const initialPhase = await this.getPVCPhase(kubeClient, name, namespace);
|
||||
cloud_runner_logger_1.default.log(`Initial PVC phase: ${initialPhase}`);
|
||||
// Wait until PVC is NOT Pending (i.e., Bound or Available)
|
||||
await (0, async_wait_until_1.waitUntil)(async () => {
|
||||
checkCount++;
|
||||
const phase = await this.getPVCPhase(kubeClient, name, namespace);
|
||||
// Log progress every 4 checks (every ~60 seconds)
|
||||
if (checkCount % 4 === 0) {
|
||||
cloud_runner_logger_1.default.log(`PVC ${name} still ${phase} (check ${checkCount})`);
|
||||
// Fetch and log PVC events for diagnostics
|
||||
try {
|
||||
const events = await kubeClient.listNamespacedEvent(namespace);
|
||||
const pvcEvents = events.body.items
|
||||
.filter((x) => x.involvedObject?.kind === 'PersistentVolumeClaim' && x.involvedObject?.name === name)
|
||||
.map((x) => ({
|
||||
message: x.message || '',
|
||||
reason: x.reason || '',
|
||||
type: x.type || '',
|
||||
count: x.count || 0,
|
||||
}))
|
||||
.slice(-5); // Get last 5 events
|
||||
if (pvcEvents.length > 0) {
|
||||
cloud_runner_logger_1.default.log(`PVC Events: ${JSON.stringify(pvcEvents, undefined, 2)}`);
|
||||
}
|
||||
}
|
||||
catch (eventError) {
|
||||
// Ignore event fetch errors
|
||||
}
|
||||
}
|
||||
return phase !== 'Pending';
|
||||
}, {
|
||||
timeout: 750000,
|
||||
|
|
@ -4599,12 +4624,65 @@ class KubernetesStorage {
|
|||
core.error(error.toString());
|
||||
try {
|
||||
const pvcBody = (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body;
|
||||
// Fetch PVC events for detailed diagnostics
|
||||
let pvcEvents = [];
|
||||
try {
|
||||
const events = await kubeClient.listNamespacedEvent(namespace);
|
||||
pvcEvents = events.body.items
|
||||
.filter((x) => x.involvedObject?.kind === 'PersistentVolumeClaim' && x.involvedObject?.name === name)
|
||||
.map((x) => ({
|
||||
message: x.message || '',
|
||||
reason: x.reason || '',
|
||||
type: x.type || '',
|
||||
count: x.count || 0,
|
||||
}));
|
||||
}
|
||||
catch (eventError) {
|
||||
// Ignore event fetch errors
|
||||
}
|
||||
// Check if storage class exists
|
||||
let storageClassInfo = '';
|
||||
try {
|
||||
const storageClassName = pvcBody.spec?.storageClassName;
|
||||
if (storageClassName) {
|
||||
// Create StorageV1Api from default config
|
||||
const kubeConfig = new k8s.KubeConfig();
|
||||
kubeConfig.loadFromDefault();
|
||||
const storageV1Api = kubeConfig.makeApiClient(k8s.StorageV1Api);
|
||||
try {
|
||||
const sc = await storageV1Api.readStorageClass(storageClassName);
|
||||
storageClassInfo = `StorageClass "${storageClassName}" exists. Provisioner: ${sc.body.provisioner || 'unknown'}`;
|
||||
}
|
||||
catch (scError) {
|
||||
if (scError.statusCode === 404) {
|
||||
storageClassInfo = `StorageClass "${storageClassName}" does NOT exist! This is likely why the PVC is stuck in Pending.`;
|
||||
}
|
||||
else {
|
||||
storageClassInfo = `Failed to check StorageClass "${storageClassName}": ${scError.message || scError}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (scCheckError) {
|
||||
// Ignore storage class check errors - not critical for diagnostics
|
||||
storageClassInfo = `Could not check storage class: ${scCheckError}`;
|
||||
}
|
||||
core.error(`PVC Body: ${JSON.stringify({
|
||||
phase: pvcBody.status?.phase,
|
||||
conditions: pvcBody.status?.conditions,
|
||||
accessModes: pvcBody.spec?.accessModes,
|
||||
storageClassName: pvcBody.spec?.storageClassName,
|
||||
storageRequest: pvcBody.spec?.resources?.requests?.storage,
|
||||
}, undefined, 4)}`);
|
||||
if (storageClassInfo) {
|
||||
core.error(storageClassInfo);
|
||||
}
|
||||
if (pvcEvents.length > 0) {
|
||||
core.error(`PVC Events: ${JSON.stringify(pvcEvents, undefined, 2)}`);
|
||||
}
|
||||
else {
|
||||
core.error('No PVC events found - this may indicate the storage provisioner is not responding');
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Ignore PVC read errors
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -47,6 +47,7 @@ class KubernetesStorage {
|
|||
}
|
||||
|
||||
public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) {
|
||||
let checkCount = 0;
|
||||
try {
|
||||
CloudRunnerLogger.log(`watch Until PVC Not Pending ${name} ${namespace}`);
|
||||
const initialPhase = await this.getPVCPhase(kubeClient, name, namespace);
|
||||
|
|
@ -55,7 +56,34 @@ class KubernetesStorage {
|
|||
// Wait until PVC is NOT Pending (i.e., Bound or Available)
|
||||
await waitUntil(
|
||||
async () => {
|
||||
checkCount++;
|
||||
const phase = await this.getPVCPhase(kubeClient, name, namespace);
|
||||
|
||||
// Log progress every 4 checks (every ~60 seconds)
|
||||
if (checkCount % 4 === 0) {
|
||||
CloudRunnerLogger.log(`PVC ${name} still ${phase} (check ${checkCount})`);
|
||||
|
||||
// Fetch and log PVC events for diagnostics
|
||||
try {
|
||||
const events = await kubeClient.listNamespacedEvent(namespace);
|
||||
const pvcEvents = events.body.items
|
||||
.filter((x) => x.involvedObject?.kind === 'PersistentVolumeClaim' && x.involvedObject?.name === name)
|
||||
.map((x) => ({
|
||||
message: x.message || '',
|
||||
reason: x.reason || '',
|
||||
type: x.type || '',
|
||||
count: x.count || 0,
|
||||
}))
|
||||
.slice(-5); // Get last 5 events
|
||||
|
||||
if (pvcEvents.length > 0) {
|
||||
CloudRunnerLogger.log(`PVC Events: ${JSON.stringify(pvcEvents, undefined, 2)}`);
|
||||
}
|
||||
} catch (eventError) {
|
||||
// Ignore event fetch errors
|
||||
}
|
||||
}
|
||||
|
||||
return phase !== 'Pending';
|
||||
},
|
||||
{
|
||||
|
|
@ -75,6 +103,49 @@ class KubernetesStorage {
|
|||
core.error(error.toString());
|
||||
try {
|
||||
const pvcBody = (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body;
|
||||
|
||||
// Fetch PVC events for detailed diagnostics
|
||||
let pvcEvents: any[] = [];
|
||||
try {
|
||||
const events = await kubeClient.listNamespacedEvent(namespace);
|
||||
pvcEvents = events.body.items
|
||||
.filter((x) => x.involvedObject?.kind === 'PersistentVolumeClaim' && x.involvedObject?.name === name)
|
||||
.map((x) => ({
|
||||
message: x.message || '',
|
||||
reason: x.reason || '',
|
||||
type: x.type || '',
|
||||
count: x.count || 0,
|
||||
}));
|
||||
} catch (eventError) {
|
||||
// Ignore event fetch errors
|
||||
}
|
||||
|
||||
// Check if storage class exists
|
||||
let storageClassInfo = '';
|
||||
try {
|
||||
const storageClassName = pvcBody.spec?.storageClassName;
|
||||
if (storageClassName) {
|
||||
// Create StorageV1Api from default config
|
||||
const kubeConfig = new k8s.KubeConfig();
|
||||
kubeConfig.loadFromDefault();
|
||||
const storageV1Api = kubeConfig.makeApiClient(k8s.StorageV1Api);
|
||||
|
||||
try {
|
||||
const sc = await storageV1Api.readStorageClass(storageClassName);
|
||||
storageClassInfo = `StorageClass "${storageClassName}" exists. Provisioner: ${sc.body.provisioner || 'unknown'}`;
|
||||
} catch (scError: any) {
|
||||
if (scError.statusCode === 404) {
|
||||
storageClassInfo = `StorageClass "${storageClassName}" does NOT exist! This is likely why the PVC is stuck in Pending.`;
|
||||
} else {
|
||||
storageClassInfo = `Failed to check StorageClass "${storageClassName}": ${scError.message || scError}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (scCheckError) {
|
||||
// Ignore storage class check errors - not critical for diagnostics
|
||||
storageClassInfo = `Could not check storage class: ${scCheckError}`;
|
||||
}
|
||||
|
||||
core.error(
|
||||
`PVC Body: ${JSON.stringify(
|
||||
{
|
||||
|
|
@ -82,11 +153,22 @@ class KubernetesStorage {
|
|||
conditions: pvcBody.status?.conditions,
|
||||
accessModes: pvcBody.spec?.accessModes,
|
||||
storageClassName: pvcBody.spec?.storageClassName,
|
||||
storageRequest: pvcBody.spec?.resources?.requests?.storage,
|
||||
},
|
||||
undefined,
|
||||
4,
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (storageClassInfo) {
|
||||
core.error(storageClassInfo);
|
||||
}
|
||||
|
||||
if (pvcEvents.length > 0) {
|
||||
core.error(`PVC Events: ${JSON.stringify(pvcEvents, undefined, 2)}`);
|
||||
} else {
|
||||
core.error('No PVC events found - this may indicate the storage provisioner is not responding');
|
||||
}
|
||||
} catch {
|
||||
// Ignore PVC read errors
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue