Skip to content

Commit d72b3c7

Browse files
committed
fix: connect to overmind unix domain socket using Deno
1 parent 6c0a418 commit d72b3c7

File tree

8 files changed

+76
-93
lines changed

8 files changed

+76
-93
lines changed

src/cmd/down.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { green, procfile } from "../../deps.ts";
2-
import { getProcfiles } from "../utils.ts";
2+
import { getProcfiles, writeToSocket } from "../utils.ts";
33

44
export default async function down() {
55
const files = await getProcfiles();
@@ -18,16 +18,14 @@ export default async function down() {
1818
for (const service of Object.keys(manifest)) {
1919
const socket = file.replace("Procfile", ".overmind.sock");
2020
infos[service].socket = socket;
21-
const command = new Deno.Command("sh", {
22-
args: ["-c", `echo stop | nc -U -w 1 ${socket}`],
23-
stdout: "piped",
24-
});
25-
const process = await command.spawn();
26-
const { success } = await process.output();
27-
if (!success) {
21+
22+
try {
23+
await writeToSocket(socket, "stop\n");
24+
} catch (_e) {
2825
console.log(`Failed to stop ${green(service)}`);
2926
continue;
3027
}
28+
3129
console.log(`Successfully stopped ${green(service)}`);
3230
}
3331
}

src/cmd/echo.ts

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { green, procfile } from "../../deps.ts";
2-
import { getProcfiles } from "../utils.ts";
2+
import { getProcfiles, writeToSocket } from "../utils.ts";
33

44
export default async function echo(name: string) {
55
const files = await getProcfiles();
@@ -27,14 +27,9 @@ export default async function echo(name: string) {
2727
}
2828

2929
const socket = infos[name].socket;
30-
const command = new Deno.Command("sh", {
31-
args: ["-c", `echo echo | nc -U ${socket}`],
32-
stdout: "inherit",
33-
stderr: "inherit",
34-
});
35-
const process = await command.spawn();
36-
const { success } = await process.output();
37-
if (!success) {
30+
try {
31+
await writeToSocket(socket, "echo\n", true);
32+
} catch (_e) {
3833
console.log(`Failed to stream logs for ${green(name)}`);
3934
Deno.exit(1);
4035
}

src/cmd/ps.ts

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { procfile, Table } from "../../deps.ts";
2+
import { writeToSocket } from "../utils.ts";
23
import { getProcfiles, getServicePid } from "../utils.ts";
34

45
export default async function listServices() {
@@ -18,20 +19,12 @@ export default async function listServices() {
1819
for (const service of Object.keys(manifest)) {
1920
const socket = file.replace("Procfile", ".overmind.sock");
2021
infos[service].socket = socket;
21-
const command = new Deno.Command("sh", {
22-
args: ["-c", `echo status | nc -U -w 1 ${socket}`],
23-
stdout: "piped",
24-
});
25-
const process = await command.spawn();
26-
const { stdout, success } = await process.output();
27-
if (!success) {
22+
try {
23+
const response = await writeToSocket(socket, "status\n");
24+
infos[service].status = response.includes("running") ? "Up" : "Stopped";
25+
} catch (_e) {
2826
infos[service].status = "Stopped";
29-
continue;
3027
}
31-
const decoder = new TextDecoder();
32-
infos[service].status = decoder.decode(stdout).includes("running")
33-
? "Up"
34-
: "Stopped";
3528
}
3629
}
3730

src/cmd/restart.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { green, procfile } from "../../deps.ts";
2-
import { getProcfiles } from "../utils.ts";
2+
import { getProcfiles, writeToSocket } from "../utils.ts";
33

44
export default async function restart(name: string) {
55
const files = await getProcfiles();
@@ -27,13 +27,9 @@ export default async function restart(name: string) {
2727
}
2828

2929
const socket = infos[name].socket;
30-
const command = new Deno.Command("sh", {
31-
args: ["-c", `echo restart | nc -U -w 1 ${socket}`],
32-
stdout: "piped",
33-
});
34-
const process = await command.spawn();
35-
const { success } = await process.output();
36-
if (!success) {
30+
try {
31+
await writeToSocket(socket, "restart\n");
32+
} catch (_e) {
3733
console.log(`Failed to restart ${green(name)}`);
3834
return;
3935
}

src/cmd/status.ts

+9-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { brightGreen, gray, bold, procfile, Table, Cell } from "../../deps.ts";
2-
import { getServicePid } from "../utils.ts";
2+
import { getServicePid, writeToSocket } from "../utils.ts";
33

44
export default async function status(name: string) {
55
const command = new Deno.Command("bash", {
@@ -30,20 +30,16 @@ export default async function status(name: string) {
3030
infos[service].procfile = file;
3131
const socket = file.replace("Procfile", ".overmind.sock");
3232
infos[service].socket = socket;
33-
const command = new Deno.Command("sh", {
34-
args: ["-c", `echo status | nc -U -w 1 ${socket}`],
35-
stdout: "piped",
36-
});
37-
const process = await command.spawn();
38-
const { stdout, success } = await process.output();
39-
if (!success) {
33+
try {
34+
const response = await writeToSocket(socket, "status\n");
35+
if (!response.includes("running")) {
36+
infos[service].status = "Stopped";
37+
continue;
38+
}
39+
} catch (_e) {
4040
infos[service].status = "Stopped";
41-
continue;
4241
}
43-
const decoder = new TextDecoder();
44-
infos[service].status = decoder.decode(stdout).includes("running")
45-
? "Up"
46-
: "Stopped";
42+
infos[service].status = "Up";
4743
}
4844
}
4945

src/cmd/stop.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { green, procfile } from "../../deps.ts";
2-
import { getProcfiles } from "../utils.ts";
2+
import { getProcfiles, writeToSocket } from "../utils.ts";
33

44
export default async function stop(name: string) {
55
const files = await getProcfiles();
@@ -27,13 +27,9 @@ export default async function stop(name: string) {
2727
}
2828

2929
const socket = infos[name].socket;
30-
const command = new Deno.Command("sh", {
31-
args: ["-c", `echo stop | nc -U -w 1 ${socket}`],
32-
stdout: "piped",
33-
});
34-
const process = await command.spawn();
35-
const { success } = await process.output();
36-
if (!success) {
30+
try {
31+
await writeToSocket(socket, "stop\n");
32+
} catch (_e) {
3733
console.log(`Failed to stop ${green(name)}`);
3834
return;
3935
}

src/cmd/up.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { green, procfile } from "../../deps.ts";
2-
import { getProcfiles } from "../utils.ts";
2+
import { getProcfiles, writeToSocket } from "../utils.ts";
33

44
export default async function up() {
55
const files = await getProcfiles();
@@ -19,13 +19,9 @@ export default async function up() {
1919
const socket = file.replace("Procfile", ".overmind.sock");
2020

2121
infos[service].socket = socket;
22-
const command = new Deno.Command("sh", {
23-
args: ["-c", `echo restart | nc -U -w 1 ${socket}`],
24-
stdout: "piped",
25-
});
26-
const process = await command.spawn();
27-
const { success } = await process.output();
28-
if (!success) {
22+
try {
23+
await writeToSocket(socket, "restart\n");
24+
} catch (_e) {
2925
console.log(`Failed to start ${green(service)}`);
3026
continue;
3127
}

src/utils.ts

+40-27
Original file line numberDiff line numberDiff line change
@@ -421,36 +421,49 @@ export async function getProcfiles() {
421421
}
422422

423423
export async function getServicePid(name: string, socket: string) {
424-
const command = new Deno.Command("sh", {
425-
args: ["-c", `echo status | nc -U -w 1 ${socket}`],
426-
stdout: "piped",
427-
});
428-
const process = await command.spawn();
429-
const { stdout } = await process.output();
430-
const decoder = new TextDecoder();
431-
const lines = decoder.decode(stdout).trim().split("\n");
432-
return lines
433-
.find((line) => line.startsWith(name + " "))
434-
?.split(" ")
435-
?.filter((x) => x)[1];
424+
try {
425+
const response = await writeToSocket(socket, "status\n");
426+
const lines = response.replaceAll("\x00", "").trim().split("\n");
427+
return lines
428+
.find((line) => line.startsWith(name + " "))
429+
?.split(" ")
430+
?.filter((x) => x)[1];
431+
} catch (_e) {
432+
return "";
433+
}
436434
}
437435

438-
export async function startOvermind(cwd: string) {
439-
const command = new Deno.Command("sh", {
440-
args: [
441-
"-c",
442-
`[ -S .overmind.sock ] || overmind start -f Procfile --daemonize`,
443-
],
444-
stdout: "inherit",
445-
stderr: "inherit",
446-
cwd,
447-
});
436+
export async function writeToSocket(
437+
socket: string,
438+
message: string,
439+
stream = false
440+
): Promise<string> {
441+
const conn = await Deno.connect({ transport: "unix", path: socket });
442+
await conn.write(new TextEncoder().encode(message));
443+
444+
if (["stop", "restart"].includes(message.trim())) {
445+
conn.close();
446+
return "";
447+
}
448448

449-
const process = await command.spawn();
450-
const { code } = await process.status;
449+
if (stream) {
450+
while (true) {
451+
const buf = new Uint8Array(1024);
452+
const bytesRead = await conn.read(buf);
453+
if (bytesRead === null) break;
454+
console.log(new TextDecoder().decode(buf));
455+
}
456+
conn.close();
457+
return "";
458+
}
451459

452-
if (code !== 0) {
453-
console.log("Failed to start Overmind.");
454-
Deno.exit(1);
460+
let data = "";
461+
while (true) {
462+
const buf = new Uint8Array(1024);
463+
const bytesRead = await conn.read(buf);
464+
if (bytesRead === null) break;
465+
data += new TextDecoder().decode(buf);
455466
}
467+
conn.close();
468+
return data;
456469
}

0 commit comments

Comments
 (0)