CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/compute/clone.tsx
Views: 687
1
/*
2
Clone compute server config. Entirely done client side.
3
4
Main issue is DNS can't be the same.
5
6
In the future we will ALSO support a checkbox to clone the data too, but not yet.
7
*/
8
9
import { Alert, Modal } from "antd";
10
import { useState } from "react";
11
import ShowError from "@cocalc/frontend/components/error";
12
import Inline from "./inline";
13
import { createServer, getServers } from "./api";
14
15
export default function Clone({ id, project_id, close }) {
16
const [error, setError] = useState<string>("");
17
const [loading, setLoading] = useState<boolean>(false);
18
19
return (
20
<Modal
21
open
22
confirmLoading={loading}
23
onCancel={close}
24
onOk={async () => {
25
try {
26
setLoading(true);
27
await createClone({ id, project_id });
28
close();
29
} catch (err) {
30
setError(`${err}`);
31
} finally {
32
setLoading(false);
33
}
34
}}
35
title={
36
<>
37
Clone Compute Server <Inline id={id} />
38
</>
39
}
40
okText={
41
<>
42
Clon{loading ? "ing" : "e"} <Inline id={id} />
43
</>
44
}
45
>
46
<ShowError
47
error={error}
48
setError={setError}
49
style={{ marginBottom: "15px" }}
50
/>
51
This makes a new deprovisioned compute server that is configured as close
52
as possibleto this this compute server.{" "}
53
<Alert
54
showIcon
55
style={{ margin: "15px" }}
56
type="warning"
57
message="The underlying disk is not copied."
58
/>
59
After cloning the compute server, you can edit anything about its
60
configuration before starting it.
61
</Modal>
62
);
63
}
64
65
async function createClone({
66
id,
67
project_id,
68
}: {
69
id: number;
70
project_id: string;
71
}) {
72
const servers = await getServers({ project_id });
73
const titles = new Set(servers.map((x) => x.title));
74
const allDns = new Set(
75
servers.filter((x) => x.configuration.dns).map((x) => x.configuration.dns),
76
);
77
let server;
78
let done = false;
79
for (const s of servers) {
80
if (s.id == id) {
81
server = s;
82
done = true;
83
break;
84
}
85
}
86
if (!done) {
87
throw Error(`no such compute server ${id}`);
88
}
89
let n = 1;
90
let title = `Clone of ${server.title}`;
91
if (titles.has(title)) {
92
while (titles.has(title + ` (${n})`)) {
93
n += 1;
94
}
95
title = title + ` (${n})`;
96
}
97
server.title = title;
98
99
delete server.configuration.authToken;
100
101
if (server.configuration.dns) {
102
n = 1;
103
while (allDns.has(server.configuration.dns + `-${n}`)) {
104
n += 1;
105
}
106
server.configuration.dns = server.configuration.dns + `-${n}`;
107
}
108
109
await createServer({ ...server });
110
}
111
112