Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into npm-ts-5.7.3
Browse files Browse the repository at this point in the history
  • Loading branch information
haraldschilly committed Jan 13, 2025
2 parents d5c6872 + f695624 commit ad6395b
Show file tree
Hide file tree
Showing 73 changed files with 1,807 additions and 520 deletions.
14 changes: 8 additions & 6 deletions src/packages/database/postgres-blobs.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ LICENSE : MS-RSL
# If this env variable begins with a / it is assumed to be a path in the file system,
# e.g., a remote mount (in practice, we are using gcsfuse to mount gcloud buckets).
# If it is gs:// then it is a google cloud storage bucket.
COCALC_BLOB_STORE = process.env.COCALC_BLOB_STORE
# 2025-01-10: noticed rarely this variable is not set, at least not initially after startup.
# Hardcoding the path, which has never changed anyways.
# Maybe https://github.com/nodejs/help/issues/3618
COCALC_BLOB_STORE_FALLBACK = "/blobs"
COCALC_BLOB_STORE = String(process.env.COCALC_BLOB_STORE ? COCALC_BLOB_STORE_FALLBACK)

async = require('async')
zlib = require('zlib')
Expand Down Expand Up @@ -211,8 +215,8 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
cb()
else if x.gcloud
if not COCALC_BLOB_STORE?
cb("no blob store configured -- set the COCALC_BLOB_STORE env variable")
return
# see comment https://github.com/sagemathinc/cocalc/pull/8110
COCALC_BLOB_STORE = COCALC_BLOB_STORE_FALLBACK
# blob not available locally, but should be in a Google cloud storage bucket -- try to get it
# NOTE: we now ignore the actual content of x.gcloud -- we don't support spreading blobs
# across multiple buckets... as it isn't needed because buckets are infinite, and it
Expand Down Expand Up @@ -291,9 +295,7 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
opts.cb?("uuid is invalid")
return
if not opts.bucket
dbg("invalid bucket")
opts.cb?("no blob store configured -- set the COCALC_BLOB_STORE env variable")
return
opts.bucket = COCALC_BLOB_STORE_FALLBACK
locals =
x: undefined
async.series([
Expand Down
2 changes: 1 addition & 1 deletion src/packages/frontend/app/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export class PageActions extends Actions<PageState> {
if (change_history) {
set_url("/notifications");
}
set_window_title("Messages, Mentions and News");
set_window_title(intl.formatMessage(labels.messages_title));
return;
case undefined:
return;
Expand Down
7 changes: 7 additions & 0 deletions src/packages/frontend/compute/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ export async function setServerCloud(opts: { id: number; cloud: string }) {
return await api("compute/set-server-cloud", opts);
}

export async function setServerOwner(opts: {
id: number;
new_account_id: string;
}) {
return await api("compute/set-server-owner", opts);
}

// Cache for 12 hours
let googleCloudPriceData: GoogleCloudData | null = null;
let googleCloudPriceDataExpire: number = 0;
Expand Down
35 changes: 18 additions & 17 deletions src/packages/frontend/compute/automatic-shutdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Inline from "./inline";
import { IdleTimeout } from "./idle-timeout";
import { SpendLimit } from "./spend-limit";
import { HealthCheck } from "./health-check";
import { ShutdownTime } from "./shutdown-time";
import ShowError from "@cocalc/frontend/components/error";
import { Icon } from "@cocalc/frontend/components";

Expand Down Expand Up @@ -116,21 +117,11 @@ function CardTitle({
{saveButton}
</Space>
<div style={{ flex: 1 }} />
{savedEnabled ? (
<Alert
style={{ marginLeft: "15px" }}
type="success"
showIcon
message={"Enabled"}
/>
) : (
<Alert
style={{ marginLeft: "15px" }}
type="info"
showIcon
message={"Disabled"}
/>
)}
<div style={{ marginLeft: "15px", width: "105px" }}>
{savedEnabled ? (
<Alert type="success" showIcon message={"Enabled"} />
) : undefined}
</div>
</Flex>
);
}
Expand All @@ -139,7 +130,7 @@ export function AutomaticShutdownModal({ id, project_id, close }) {
const [help, setHelp] = useState<boolean>(false);
return (
<Modal
width={800}
width={900}
open
onCancel={close}
onOk={close}
Expand All @@ -157,7 +148,7 @@ export function AutomaticShutdownModal({ id, project_id, close }) {
/>
<Flex style={{ marginRight: "20px", alignItems: "center" }}>
<div style={{ fontSize: "18px", margin: "15px 0" }}>
Configure Automatic Shutdown Strategies
Configure Automatic Shutdown and Health Check Strategies
</div>
<div style={{ flex: 1 }} />
<Switch
Expand All @@ -169,6 +160,14 @@ export function AutomaticShutdownModal({ id, project_id, close }) {
</Flex>
{help && (
<div style={{ fontSize: "14px", fontWeight: "normal" }}>
<Button
href="https://youtu.be/Kx_47fs_xcI"
target="_blank"
style={{ float: "right" }}
>
<Icon name="youtube" style={{ color: "red" }} />
YouTube Video
</Button>
Each strategy automatically turns this compute server off when a
condition is met. This can save you money keeping spending under
control. When the server is shutdown, a message is also sent and a
Expand All @@ -180,6 +179,8 @@ export function AutomaticShutdownModal({ id, project_id, close }) {
>
<IdleTimeout id={id} project_id={project_id} help={help} />
<div style={{ height: "15px" }} />
<ShutdownTime id={id} project_id={project_id} help={help} />
<div style={{ height: "15px" }} />
<SpendLimit id={id} project_id={project_id} help={help} />
<div style={{ height: "15px" }} />
<HealthCheck id={id} project_id={project_id} help={help} />
Expand Down
51 changes: 36 additions & 15 deletions src/packages/frontend/compute/compute-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import SerialPortOutput from "./serial-port-output";
import State from "./state";
import Title from "./title";
import { IdleTimeoutMessage } from "./idle-timeout";
import { ShutdownTimeMessage } from "./shutdown-time";
import { RunningProgress } from "@cocalc/frontend/compute/doc-status";
import { SpendLimitStatus } from "./spend-limit";

Expand Down Expand Up @@ -392,20 +393,40 @@ export default function ComputeServer({
/>
)}
</div>
{cloud != "onprem" &&
server.configuration?.idleTimeoutMinutes &&
state == "running" &&
id && (
<div
style={{
display: "flex",
marginLeft: "-10px",
color: "#666",
}}
>
<IdleTimeoutMessage id={id} project_id={project_id} minimal />
</div>
)}
{cloud != "onprem" && state == "running" && id && (
<>
{!!server.configuration?.idleTimeoutMinutes && (
<div
style={{
display: "flex",
marginLeft: "-10px",
color: "#666",
}}
>
<IdleTimeoutMessage
id={id}
project_id={project_id}
minimal
/>
</div>
)}
{!!server.configuration?.shutdownTime?.enabled && (
<div
style={{
display: "flex",
marginLeft: "-15px",
color: "#666",
}}
>
<ShutdownTimeMessage
id={id}
project_id={project_id}
minimal
/>
</div>
)}
</>
)}
{id != null && (
<div style={{ marginLeft: "-15px" }}>
<CurrentCost state={state} cost_per_hour={cost_per_hour} />
Expand All @@ -420,7 +441,7 @@ export default function ComputeServer({
project_id={project_id}
/>
)}
<SpendLimitStatus server={server} />
{server?.id != null && <SpendLimitStatus server={server} />}
</div>
}
title={
Expand Down
49 changes: 30 additions & 19 deletions src/packages/frontend/compute/health-check.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, Flex, Input, InputNumber, Radio, Space } from "antd";
import { useEffect, useState } from "react";
import { Button, Input, InputNumber, Radio, Space } from "antd";
import { useState } from "react";
import ShowError from "@cocalc/frontend/components/error";
import { useServer } from "./compute-server";
import { webapp_client } from "@cocalc/frontend/webapp-client";
Expand Down Expand Up @@ -27,14 +27,6 @@ export function HealthCheck({ id, project_id, help }) {
)!,
);

useEffect(() => {
setHealthCheck(
validatedHealthCheck(
server?.configuration?.healthCheck ?? HEALTH_CHECK_DEFAULTS,
)!,
);
}, [server?.configuration?.healthCheck]);

const doTest = async () => {
try {
setSaving(true);
Expand All @@ -59,6 +51,9 @@ export function HealthCheck({ id, project_id, help }) {
healthCheck.periodSeconds ?? HEALTH_CHECK_DEFAULTS.periodSeconds;
const failureThreshold =
healthCheck.failureThreshold ?? HEALTH_CHECK_DEFAULTS.failureThreshold;
const initialDelaySeconds =
healthCheck.initialDelaySeconds ??
HEALTH_CHECK_DEFAULTS.initialDelaySeconds;

return (
<AutomaticShutdownCard
Expand All @@ -82,7 +77,8 @@ export function HealthCheck({ id, project_id, help }) {
) &&
healthCheck.failureThreshold != null &&
healthCheck.periodSeconds != null &&
healthCheck.timeoutSeconds != null
healthCheck.timeoutSeconds != null &&
healthCheck.initialDelaySeconds != null
}
savedEnabled={!!server.configuration?.healthCheck?.enabled}
enabled={healthCheck.enabled}
Expand Down Expand Up @@ -116,9 +112,9 @@ export function HealthCheck({ id, project_id, help }) {
</div>
)}
<Space direction="vertical" size="large">
<Flex>
<Space style={{ width: "100%" }} wrap>
<Input
style={{ flex: 1, marginRight: "15px" }}
style={{ width: "508px" }}
allowClear
disabled={saving}
value={healthCheck.command}
Expand All @@ -128,7 +124,7 @@ export function HealthCheck({ id, project_id, help }) {
placeholder={`Shell Command (bash) -- ${healthCheck.action} when this fails ${failureThreshold} times...`}
/>
<InputNumber
style={{ flex: 0.5, marginRight: "15px" }}
style={{ width: "250px" }}
disabled={saving}
min={1}
step={1}
Expand All @@ -142,10 +138,10 @@ export function HealthCheck({ id, project_id, help }) {
addonAfter="seconds timeout"
placeholder="Command timeout..."
/>
</Flex>
<Flex>
</Space>
<Space style={{ width: "100%" }} wrap>
<InputNumber
style={{ flex: 1, marginRight: "15px" }}
style={{ width: "250px" }}
disabled={saving}
min={1}
step={1}
Expand All @@ -160,7 +156,7 @@ export function HealthCheck({ id, project_id, help }) {
placeholder="Failure threshold..."
/>
<InputNumber
style={{ flex: 1 }}
style={{ width: "250px" }}
disabled={saving}
min={60}
step={30}
Expand All @@ -174,7 +170,22 @@ export function HealthCheck({ id, project_id, help }) {
addonAfter="seconds between checks"
placeholder="Interval..."
/>
</Flex>
<InputNumber
style={{ width: "250px" }}
disabled={saving}
min={60}
step={30}
value={initialDelaySeconds}
onChange={(initialDelaySeconds) =>
setHealthCheck({
...healthCheck,
initialDelaySeconds: initialDelaySeconds ?? undefined,
})
}
addonAfter="seconds initial delay"
placeholder="Initial delay..."
/>
</Space>
<Space style={{ width: "100%" }}>
<div style={{ marginRight: "15px" }}>
Action when health check fails:
Expand Down
6 changes: 1 addition & 5 deletions src/packages/frontend/compute/idle-timeout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useState } from "react";
import { useServer } from "./compute-server";
import { TimeAgo } from "@cocalc/frontend/components/time-ago";
import dayjs from "dayjs";
Expand Down Expand Up @@ -28,10 +28,6 @@ export function IdleTimeout({
const [idleTimeoutMinutes, setIdleTimeoutMinutes] = useState<number | null>(
server.configuration?.idleTimeoutMinutes ?? null,
);
useEffect(() => {
setIdleTimeoutMinutes(server.configuration?.idleTimeoutMinutes ?? null);
setEnabled(!!server.configuration?.idleTimeoutMinutes);
}, [server.configuration?.idleTimeoutMinutes]);

return (
<AutomaticShutdownCard
Expand Down
8 changes: 8 additions & 0 deletions src/packages/frontend/compute/log-entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ export default function LogEntry({
{event.idle_timeout} {plural(event.idle_timeout, "minute")}) {tag}
</>
);

case "shutdown-time":
return (
<>
{cs} - Schedule Shutdown -- shutting down due to a prescheduled daily
shutdown time {tag}
</>
);
case "spend-limit":
return (
<>
Expand Down
3 changes: 1 addition & 2 deletions src/packages/frontend/compute/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function getItems({
key: "automatic-shutdown",
icon: <Icon name="stopwatch" />,
disabled: server.cloud == "onprem",
label: "Automatic Shutdown",
label: "Automatic Shutdown & Health Check",
};
const jupyterlab = {
key: "top-jupyterlab",
Expand Down Expand Up @@ -448,7 +448,6 @@ export default function Menu({
return {
items: getItems({ id, project_id, account_id, isAdmin }),
onClick: async (obj) => {
console.log("obj = ", obj);
setOpen(false);
let cmd = obj.key.startsWith("top-") ? obj.key.slice(4) : obj.key;
switch (cmd) {
Expand Down
Loading

0 comments on commit ad6395b

Please sign in to comment.