diff --git a/packages/api-v4/.changeset/pr-13269-added-1768236376323.md b/packages/api-v4/.changeset/pr-13269-added-1768236376323.md
new file mode 100644
index 00000000000..53800260763
--- /dev/null
+++ b/packages/api-v4/.changeset/pr-13269-added-1768236376323.md
@@ -0,0 +1,5 @@
+---
+"@linode/api-v4": Added
+---
+
+`Maintenance Policy` to Linode Capabilities ([#13269](https://github.com/linode/manager/pull/13269))
diff --git a/packages/api-v4/src/linodes/types.ts b/packages/api-v4/src/linodes/types.ts
index 04e915b48ad..79b35707a30 100644
--- a/packages/api-v4/src/linodes/types.ts
+++ b/packages/api-v4/src/linodes/types.ts
@@ -46,7 +46,13 @@ export interface Linode {
label: string;
lke_cluster_id: null | number;
locks: LockType[];
- maintenance_policy?: MaintenancePolicySlug;
+ /**
+ * The maintenance policy configured for this Linode.
+ *
+ * Will be `null` if the Maintenance Policy feature is not enabled or the Linode's
+ * region does not support maintenance policies.
+ */
+ maintenance_policy: MaintenancePolicySlug | null;
placement_group: LinodePlacementGroupPayload | null;
region: string;
site_type: RegionSite;
@@ -75,6 +81,7 @@ export interface LinodeBackups {
export type LinodeCapabilities =
| 'Block Storage Encryption'
| 'Block Storage Performance B1'
+ | 'Maintenance Policy'
| 'SMTP Enabled';
export type Window =
diff --git a/packages/manager/.changeset/pr-13269-fixed-1768236332373.md b/packages/manager/.changeset/pr-13269-fixed-1768236332373.md
new file mode 100644
index 00000000000..9210bb5e2b6
--- /dev/null
+++ b/packages/manager/.changeset/pr-13269-fixed-1768236332373.md
@@ -0,0 +1,5 @@
+---
+"@linode/manager": Fixed
+---
+
+Only show Maintenance Policy for Linodes that actually have a Maintenance Policy ([#13269](https://github.com/linode/manager/pull/13269))
diff --git a/packages/manager/src/features/Linodes/LinodeEntityDetail.test.tsx b/packages/manager/src/features/Linodes/LinodeEntityDetail.test.tsx
index f0a63b78eff..0f7d2aba767 100644
--- a/packages/manager/src/features/Linodes/LinodeEntityDetail.test.tsx
+++ b/packages/manager/src/features/Linodes/LinodeEntityDetail.test.tsx
@@ -336,6 +336,63 @@ describe('Linode Entity Detail', () => {
expect(await findByTestId('linode-encryption-status')).toBeVisible();
});
+
+ it('should display the Linode maintenance policy if it supports it and the flag is on', async () => {
+ const linode = linodeFactory.build({
+ maintenance_policy: 'linode/power_off_on',
+ capabilities: ['Maintenance Policy'],
+ });
+
+ server.use(
+ http.get('*/linode/instances/:linodeId', () => {
+ return HttpResponse.json(linode);
+ })
+ );
+
+ const { findByText, getByText } = renderWithTheme(
+ ,
+ {
+ flags: {
+ vmHostMaintenance: { enabled: true, beta: false, new: false },
+ },
+ }
+ );
+
+ expect(
+ await findByText('Maintenance Policy', { exact: false })
+ ).toBeVisible();
+
+ expect(getByText('Power Off / Power On')).toBeVisible();
+ });
+
+ it('should not display a maintenance policy if the linode does not have one', async () => {
+ const linode = linodeFactory.build({
+ maintenance_policy: null,
+ capabilities: [],
+ });
+
+ server.use(
+ http.get('*/linode/instances/:linodeId', () => {
+ return HttpResponse.json(linode);
+ })
+ );
+
+ const { findByText, queryByText } = renderWithTheme(
+ ,
+ {
+ flags: {
+ vmHostMaintenance: { enabled: true, beta: false, new: false },
+ },
+ }
+ );
+
+ // Ensure the Linode is loaded
+ await findByText(linode.ipv4[0]);
+
+ expect(
+ queryByText('Maintenance Policy', { exact: false })
+ ).not.toBeInTheDocument();
+ });
});
describe('getSubnetsString function', () => {
diff --git a/packages/manager/src/features/Linodes/LinodeEntityDetail.tsx b/packages/manager/src/features/Linodes/LinodeEntityDetail.tsx
index 3fde42e8fd0..2b1e855ac65 100644
--- a/packages/manager/src/features/Linodes/LinodeEntityDetail.tsx
+++ b/packages/manager/src/features/Linodes/LinodeEntityDetail.tsx
@@ -154,6 +154,7 @@ export const LinodeEntityDetail = (props: Props) => {
image={linode.image ?? 'Unknown Image'}
imageVendor={imageVendor}
isSummaryView={isSummaryView}
+ linodeCapabilities={linode.capabilities}
linodeId={linode.id}
linodeLabel={linode.label}
linodeMaintenancePolicySet={
diff --git a/packages/manager/src/features/Linodes/LinodeEntityDetailHeader.tsx b/packages/manager/src/features/Linodes/LinodeEntityDetailHeader.tsx
index 1d078e796a5..49f1aa82335 100644
--- a/packages/manager/src/features/Linodes/LinodeEntityDetailHeader.tsx
+++ b/packages/manager/src/features/Linodes/LinodeEntityDetailHeader.tsx
@@ -15,11 +15,7 @@ import { LinodeEntityDetailHeaderMaintenancePolicy } from './LinodeEntityDetailH
import { getLinodeIconStatus } from './LinodesLanding/utils';
import type { LinodeHandlers } from './LinodesLanding/LinodesLanding';
-import type {
- Config,
- LinodeBackups,
- MaintenancePolicySlug,
-} from '@linode/api-v4';
+import type { Config, LinodeBackups, LinodeCapabilities } from '@linode/api-v4';
import type { Linode, LinodeType } from '@linode/api-v4/lib/linodes/types';
import type { TypographyProps } from '@linode/ui';
import type { LinodeMaintenance } from 'src/utilities/linodes';
@@ -45,9 +41,10 @@ export interface HeaderProps {
image: string;
imageVendor: null | string;
isSummaryView?: boolean;
+ linodeCapabilities: LinodeCapabilities[];
linodeId: number;
linodeLabel: string;
- linodeMaintenancePolicySet: MaintenancePolicySlug | undefined;
+ linodeMaintenancePolicySet: Linode['maintenance_policy'];
linodeRegionDisplay: string;
linodeStatus: Linode['status'];
maintenance: LinodeMaintenance | null;
@@ -76,6 +73,7 @@ export const LinodeEntityDetailHeader = (
linodeLabel,
linodeRegionDisplay,
linodeStatus,
+ linodeCapabilities,
linodeMaintenancePolicySet,
maintenance,
openNotificationMenu,
@@ -87,6 +85,10 @@ export const LinodeEntityDetailHeader = (
const { isVMHostMaintenanceEnabled } = useVMHostMaintenanceEnabled();
+ const showMaintenancePolicy =
+ isVMHostMaintenanceEnabled &&
+ linodeCapabilities.includes('Maintenance Policy');
+
const isRunning = linodeStatus === 'running';
const isRebootNeeded = React.useMemo(
@@ -157,7 +159,7 @@ export const LinodeEntityDetailHeader = (
text={VPC_REBOOT_MESSAGE}
/>
)}
- {isVMHostMaintenanceEnabled && (
+ {showMaintenancePolicy && (