Skip to content

Commit e07ea46

Browse files
committed
project runner: start/config of mutagen in sidecar
1 parent c8d8465 commit e07ea46

File tree

5 files changed

+97
-30
lines changed

5 files changed

+97
-30
lines changed

src/packages/file-server/ssh/auth.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ export async function init({
6969
authorizedKeys,
7070
};
7171

72-
// HIGHLY SENSITVE!!!
73-
// console.log("sending", resp);
72+
//console.log("USING", { ...resp, privateKey: "xxx" });
7473

7574
res.json(resp);
7675
} catch (err) {

src/packages/file-server/ssh/container.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ export const start = reuseInFlight(
5050
}): Promise<{ sshPort: number }> => {
5151
let child = children[volume];
5252
if (child != null && child.exitCode == null) {
53-
console.log("already running", {
54-
publicKey,
55-
curPublicKey: child.publicKey,
56-
});
5753
// already running
5854
if (
5955
child.publicKey != publicKey ||
@@ -128,14 +124,13 @@ export const start = reuseInFlight(
128124
return true;
129125
}
130126
const ports = await getPorts({ volume });
131-
console.log("got ports", ports);
132127
if (ports[22]) {
133128
// @ts-ignore
134129
child.sshPort = ports[22];
135130
return true;
136131
}
137-
} catch {
138-
console.log("got ports error");
132+
} catch (err) {
133+
console.log("got ports error", err);
139134
}
140135
return false;
141136
},

src/packages/project-runner/run/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,6 @@ export async function getEnvironment({
9191
CONAT_SERVER: conatServer.replace("localhost", "host.containers.internal"),
9292
COCALC_SECRET_TOKEN: secretTokenPath(HOME),
9393
BASE_PATH: base_path,
94+
DEBIAN_FRONTEND: "noninteractive",
9495
};
9596
}

src/packages/project-runner/run/overlay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function getMergedPath(project_id) {
9393
return join(PROJECT_ROOTS, project_id);
9494
}
9595

96-
function getPaths({ home, image, project_id }) {
96+
export function getPaths({ home, image, project_id }) {
9797
const userOverlays = join(home, PROJECT_IMAGE_PATH, image);
9898
const upperdir = join(userOverlays, "upperdir");
9999
const workdir = join(userOverlays, "workdir");

src/packages/project-runner/run/podman.ts

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { nodePath } from "./mounts";
2020
import { isValidUUID } from "@cocalc/util/misc";
2121
import { ensureConfFilesExists, setupDataPath, writeSecretToken } from "./util";
2222
import { getEnvironment } from "./env";
23-
import { mkdir, readFile } from "node:fs/promises";
23+
import { mkdir, readFile, rm } from "node:fs/promises";
2424
import { spawn } from "node:child_process";
2525
import { getCoCalcMounts, COCALC_SRC } from "./mounts";
2626
import { setQuota } from "./filesystem";
@@ -36,8 +36,8 @@ import {
3636
type SshServersFunction,
3737
type LocalPathFunction,
3838
} from "@cocalc/conat/project/runner/types";
39-
import { write as writeMutagenConfig } from "@cocalc/backend/mutagen/config";
4039
import { initSshKeys } from "@cocalc/backend/mutagen/ssh-keys";
40+
import { PROJECT_IMAGE_PATH } from "@cocalc/util/db-schema/defaults";
4141

4242
const logger = getLogger("project-runner:podman");
4343
const children: { [project_id: string]: any } = {};
@@ -78,15 +78,24 @@ export async function start({
7878
logger.debug("start: got home", { project_id, home });
7979
const mounts = getCoCalcMounts();
8080
const image = getImage(config);
81-
await initSshKeys({ home, sshServers: await sshServers?.({ project_id }) });
81+
const servers = await sshServers?.({ project_id });
82+
await initSshKeys({ home, sshServers: servers });
8283

8384
const env = await getEnvironment({
8485
project_id,
8586
env: config?.env,
8687
HOME: "/root",
8788
image,
8889
});
89-
await startSidecar({ project_id, home, mounts, env, pod });
90+
const initMutagen = await startSidecar({
91+
image,
92+
project_id,
93+
home,
94+
mounts,
95+
env,
96+
pod,
97+
servers,
98+
});
9099

91100
const rootfs = await rootFilesystem.mount({ project_id, home, config });
92101
logger.debug("start: got rootfs", { project_id, rootfs });
@@ -95,11 +104,11 @@ export async function start({
95104
await ensureConfFilesExists(home);
96105
logger.debug("start: created conf files", { project_id });
97106

98-
await writeMutagenConfig({
99-
home,
100-
sync: config?.sync,
101-
forward: config?.forward,
102-
});
107+
// await writeMutagenConfig({
108+
// home,
109+
// sync: config?.sync,
110+
// forward: config?.forward,
111+
// });
103112

104113
await setupDataPath(home);
105114
logger.debug("start: setup data path", { project_id });
@@ -119,6 +128,7 @@ export async function start({
119128
const args: string[] = [];
120129
args.push("run");
121130
args.push("--rm");
131+
args.push("--replace");
122132
args.push("--user=0:0");
123133
args.push("--pod", pod);
124134

@@ -157,16 +167,27 @@ export async function start({
157167
child.stderr.on("data", (chunk: Buffer) => {
158168
logger.debug(`project_id=${project_id}.stderr: `, chunk.toString());
159169
});
170+
171+
await initMutagen?.();
160172
}
161173

162-
async function startSidecar({ project_id, mounts, env, pod, home }) {
174+
async function startSidecar({
175+
image,
176+
project_id,
177+
mounts,
178+
env,
179+
pod,
180+
home,
181+
servers,
182+
}) {
163183
// sidecar: refactor
164184
const sidecarPodName = `sidecar-${project_id}`;
165185
const args2 = [
166186
"run",
167187
`--name=${sidecarPodName}`,
168188
"--detach",
169189
"--rm",
190+
"--replace",
170191
"--pod",
171192
pod,
172193
"--init",
@@ -178,22 +199,72 @@ async function startSidecar({ project_id, mounts, env, pod, home }) {
178199
for (const name in env) {
179200
args2.push("-e", `${name}=${env[name]}`);
180201
}
202+
181203
args2.push(sidecarImageName, "mutagen", "daemon", "run");
204+
205+
// always start with fresh .mutagen
206+
await rm(join(home, ".mutagen-dev"), { force: true, recursive: true });
207+
182208
await podman(args2);
209+
210+
if (servers.length == 0) {
211+
return;
212+
}
213+
214+
const upperdir = join(PROJECT_IMAGE_PATH, image, "upperdir");
183215
try {
216+
await podman(
217+
[
218+
"exec",
219+
sidecarPodName,
220+
"rsync",
221+
"--relative",
222+
"-axH",
223+
`${servers[0].name}:${upperdir}/`,
224+
"/root/",
225+
],
226+
10 * 60,
227+
);
228+
} catch (err) {
229+
console.log(err);
230+
}
231+
232+
return async () => {
184233
await podman([
185234
"exec",
186235
sidecarPodName,
187-
"rsync",
188-
"-axH",
189-
"--exclude=.mutagen",
190-
"--delete",
191-
"file-server:/root/",
192-
"/root/",
236+
"mutagen",
237+
"sync",
238+
"create",
239+
"--name=upperdir",
240+
"--mode=one-way-replica",
241+
"--symlink-mode=posix-raw",
242+
join("/root", upperdir),
243+
`${servers[0].name}:${upperdir}`,
193244
]);
194-
} catch (err) {
195-
console.log(err);
196-
}
245+
246+
await podman([
247+
"exec",
248+
sidecarPodName,
249+
"mutagen",
250+
"sync",
251+
"create",
252+
"--name=root",
253+
"--symlink-mode=posix-raw",
254+
"--ignore",
255+
".local/share/overlay/**",
256+
"--ignore",
257+
".cache/cocalc/**",
258+
"--ignore",
259+
".mutagen-dev/**",
260+
"--ignore",
261+
".ssh/**",
262+
"--ignore",
263+
".snapshots/**",
264+
"/root",
265+
`${servers[0].name}:/root`,
266+
]);
267+
};
197268
}
198269

199270
export async function stop({
@@ -249,13 +320,14 @@ export async function stop({
249320
}
250321
}
251322

252-
async function podman(args: string[]) {
323+
async function podman(args: string[], timeout?) {
253324
logger.debug("podman ", args.join(" "));
254325
return await executeCode({
255326
verbose: true,
256327
command: "podman",
257328
args,
258329
err_on_exit: true,
330+
timeout,
259331
});
260332
}
261333

0 commit comments

Comments
 (0)