Skip to content
Draft
107 changes: 86 additions & 21 deletions src/packages/frontend/project/page/software-env-upgrade.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ import {
import {
DISMISS_IMG_1804,
DISMISS_IMG_2004,
DISMISS_IMG_2204,
UBUNTU2004_DEPRECATED,
UBUNTU2004_DEV,
UBUNTU2204,
UBUNTU2204_DEV,
UBUNTU2204_PREVIOUS,
} from "@cocalc/util/compute-images";
import { FALLBACK_COMPUTE_IMAGE } from "@cocalc/util/db-schema/defaults";
import { KUCALC_COCALC_COM } from "@cocalc/util/db-schema/site-defaults";
Expand All @@ -41,17 +45,22 @@ const UPGRADE_STYLE: React.CSSProperties = {
const DOC_UBUNTU_2004 = "https://doc.cocalc.com/news/ubuntu-2004.html";
const DOC_UBUNTU_2204 =
"https://cocalc.com/news/ubuntu-22-04-default-software-environment-9";
const DOC_UBUNTU_2404 =
"https://cocalc.com/news/ubuntu-24-04-based-environment-is-the-default-78";
const DOC_CHANGE_SOFTWARE_IMAGE =
"https://doc.cocalc.com/project-settings.html#software-environment";

// we only upgrade from not-frozen 18.04 and 20.04 images to the new default.
// we only upgrade from not-frozen 18.04, 20.04, and 22.04 images to the new default.
// do not bother about any other names, including ubuntu1804 and old
const TO_UPGRADE = [
FALLBACK_COMPUTE_IMAGE,
"previous",
"exp",
UBUNTU2004_DEPRECATED,
UBUNTU2004_DEV,
UBUNTU2204,
UBUNTU2204_DEV,
UBUNTU2204_PREVIOUS,
] as const;

function useComputeImage(project_id) {
Expand Down Expand Up @@ -106,11 +115,15 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
return useMemo(() => {
if (hide) return null;
if (compute_image == null) return null;
if (TO_UPGRADE.indexOf(compute_image) == -1) return null;
if (!TO_UPGRADE.includes(compute_image)) return null;
if (is_student_project) return null;

const only2204 =
[UBUNTU2004_DEPRECATED, UBUNTU2004_DEV].indexOf(compute_image) != -1;
const only2004 = [UBUNTU2004_DEPRECATED, UBUNTU2004_DEV].includes(
compute_image,
);
const only2204 = [UBUNTU2204, UBUNTU2204_DEV, UBUNTU2204_PREVIOUS].includes(
compute_image,
);

// just a safety measure, before accessing .title
if (software_envs == null || default_compute_image == null) return null;
Expand All @@ -120,16 +133,22 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
for (const key of [
compute_image,
UBUNTU2004_DEPRECATED,
UBUNTU2204,
default_compute_image,
]) {
if (software_envs[key] == null) return null;
}

const oldname = software_envs[compute_image].title;
const name2004 = software_envs[UBUNTU2004_DEPRECATED].title;
const name2204 = software_envs[default_compute_image].title;
const name2204 = software_envs[UBUNTU2204].title;
const name2404 = software_envs[default_compute_image].title;

const KEEP_IMAGE = only2204 ? DISMISS_IMG_2004 : DISMISS_IMG_1804;
const KEEP_IMAGE = only2204
? DISMISS_IMG_2204
: only2004
? DISMISS_IMG_2004
: DISMISS_IMG_1804;

async function set_image(image: string) {
set_updating(true);
Expand All @@ -154,10 +173,10 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
onClick={() => set_image(default_compute_image)}
bsStyle={"primary"}
>
Upgrade
Upgrade to {name2404}
</Button>
);
} else {
} else if (only2004) {
return (
<>
<Button
Expand All @@ -170,8 +189,28 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
onClick={() => set_image(default_compute_image)}
bsStyle={"primary"}
>
{name2404}
</Button>
</>
);
} else {
return (
<>
<Button
onClick={() => set_image(DISMISS_IMG_2004)}
bsStyle={"default"}
>
{name2004}
</Button>
<Button onClick={() => set_image(UBUNTU2204)} bsStyle={"default"}>
{name2204}
</Button>
<Button
onClick={() => set_image(default_compute_image)}
bsStyle={"primary"}
>
{name2404}
</Button>
</>
);
}
Expand All @@ -191,13 +230,35 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
}
}

function render_update_to_2004() {
if (only2204) return null;
return (
<>
<A href={DOC_UBUNTU_2004}>{name2004}</A>,{" "}
</>
);
function render_upgrade_options() {
if (only2204) {
return (
<>
<strong>
<A href={DOC_UBUNTU_2404}>{name2404}</A>
</strong>
</>
);
} else if (only2004) {
return (
<>
<A href={DOC_UBUNTU_2004}>{name2004}</A>,{" "}
<strong>
<A href={DOC_UBUNTU_2404}>{name2404}</A>
</strong>
</>
);
} else {
return (
<>
<A href={DOC_UBUNTU_2004}>{name2004}</A>,{" "}
<A href={DOC_UBUNTU_2204}>{name2204}</A>, or{" "}
<strong>
<A href={DOC_UBUNTU_2404}>{name2404}</A>
</strong>
</>
);
}
}

function render_main(): React.JSX.Element {
Expand All @@ -213,11 +274,7 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
<strong>Software Upgrade Available!</strong>{" "}
<VisibleMDLG>
Upgrade this project's software environment from {oldname} to{" "}
{render_update_to_2004()}
<strong>
<A href={DOC_UBUNTU_2204}>{name2204}</A>
</strong>
, or keep it as it is.
{render_upgrade_options()}, or keep it as it is.
<br />
<span style={{ color: COLORS.GRAY }}>
You can change this any time in{" "}
Expand All @@ -238,5 +295,13 @@ const SoftwareEnvUpgradeAlert: React.FC<Props> = (props: Props) => {
}

return render_main();
}, [compute_image, updating, hide, project_state]);
}, [
compute_image,
updating,
hide,
project_state,
software_envs,
default_compute_image,
is_student_project,
]);
};
17 changes: 16 additions & 1 deletion src/packages/util/compute-images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ type Group = (typeof GROUPS)[number];
// names of old images, that won't trigger the "upgrade banner", pointing to the most recent end-of-life image of that series
export const DISMISS_IMG_1804 = "ubuntu1804";
export const DISMISS_IMG_2004 = "ubuntu2004-eol";
export const DISMISS_IMG_2204 = "ubuntu2204-eol";
// names of old images triggering the upgrade banner to 22.04
export const UBUNTU2004_DEPRECATED = "ubuntu2004";
export const UBUNTU2004_DEV = "ubuntu2004-dev";
export const UBUNTU2204_DEV = "ubuntu2204-dev";
// new Ubuntu 24.04 image, for development
export const UBUNTU2404_DEV = "ubuntu2404-dev";
export const UBUNTU2204 = "ubuntu2204";
export const UBUNTU2204_PREVIOUS = "ubuntu2204-previous";

export interface ComputeImage {
id: string; // the key under which it is stored in the database
Expand Down Expand Up @@ -77,6 +79,13 @@ const COMPUTE_IMAGES: { [key: string]: ComputeImageProd } = {
"Ubuntu 22.04-based software stack, superseded by 24.04 in June 2025",
group: "Main",
},
[DISMISS_IMG_2204]: {
order: 1,
title: "Ubuntu 22.04 (EndOfLife)",
short: "Ubuntu 22.04 (EndOfLife)",
descr: "Reached end of life in June 2025",
group: "Main",
},
[UBUNTU2404_DEV]: {
title: "Ubuntu 24.04 (Testing)",
short: "Ubuntu 24.04 (Testing)",
Expand Down Expand Up @@ -123,13 +132,19 @@ const COMPUTE_IMAGES: { [key: string]: ComputeImageProd } = {
group: "Main",
hidden: true, // any project that is set to "ubuntu2004" will be shown a banner → either update to ubuntu2204 or keep ubuntu2004-eol
},
"ubuntu2404-2025-08-27": {
title: "Ubuntu 24.04 (2025-08-27)",
short: "2025-08-27",
descr: "Frozen on 2025-08-27 and no longer updated",
group: "Ubuntu 24.04",
},
"ubuntu2404-2025-06-26": {
title: "Ubuntu 24.04 (2025-06-26)",
short: "2025-06-26",
descr: "Frozen on 2025-06-26 and no longer updated",
group: "Ubuntu 24.04",
},
"ubuntu2204-previous": {
[UBUNTU2204_PREVIOUS]: {
title: "Ubuntu 22.04 (Previous)",
short: "Previous",
descr: "Slightly behind 22.04 (Current)",
Expand Down