Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix - Fix Env. Vars Bug + Cron Job to Refresh Statuses #18

Merged
merged 3 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions client/src/components/dashboard/table/DashboardTableRowEditable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function DashboardTableRowEditable({
saveClicked,
cancelClicked,
}: Props) {
const [tag, setTag] = useState("");
const [name, setName] = useState("");
const [imageIdentifier, setImageIdentifier] = useState<string>("");
const [hosts, setHosts] = useState<string[]>([]);
const [possibleHost, setPossibleHost] = useState("");
Expand All @@ -26,7 +26,7 @@ function DashboardTableRowEditable({
service.image.repository != "_"
? `${service.image.repository}/${service.image.name}:${service.image.tag}`
: `${service.image.name}:${service.image.tag}`;
setTag(service.name);
setName(service.name);
setImageIdentifier(imageIdentifier);
setHosts(service.hosts);
}
Expand Down Expand Up @@ -54,9 +54,9 @@ function DashboardTableRowEditable({
type="text"
className="w-full bg-transparent text-center outline-none "
placeholder="Service name.."
value={tag}
value={name}
onChange={(e) => {
setTag(e.target.value);
setName(e.target.value);
}}
/>
</span>
Expand Down Expand Up @@ -165,17 +165,20 @@ function DashboardTableRowEditable({
<button
className="text-indigo-600 hover:text-indigo-900"
onClick={() => {
if (!imageIdentifier?.includes(":")) {
const regex =
/^(.+)\/(.+):(.+)$|^(.+):(.+)$|^(.+)\/(.+)|^(.+)$/;
const match = regex.exec(imageIdentifier);
if (!match) {
alert("Please provide a valid image identifier");
return;
}
const imageRepository = imageIdentifier.includes("/")
? imageIdentifier.split("/")[0]
: "_";
const imageName = imageIdentifier.split(":")[0];
const imageTag = imageIdentifier.split(":")[1];
const imageRepository = match[1] ?? match[6] ?? "_";
const imageName =
match[2] ?? match[4] ?? match[7] ?? match[8];
const imageTag = match[3] ?? match[5] ?? "latest";

saveClicked({
name: service?.name ?? tag,
name: service?.name ?? name,
image: {
repository: imageRepository,
name: imageName,
Expand Down
4 changes: 4 additions & 0 deletions server/libs/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export const stopContainer = async (service: Service) => {
throw new Error("Container id is not set");
}
const container = docker.getContainer(service.containerId);
const containerInfo = await container.inspect();
if (!containerInfo.State.Running) {
return;
}
return container.stop();
};

Expand Down
2 changes: 2 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"express": "^4.18.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.3.2",
"node-cron": "^3.0.0",
"passport": "^0.5.2",
"passport-jwt": "^4.0.0",
"pino": "^7.11.0",
Expand All @@ -41,6 +42,7 @@
"@types/express": "^4.17.13",
"@types/jest": "^27.5.0",
"@types/node": "^17.0.31",
"@types/node-cron": "^3.0.1",
"@types/passport": "^1.0.7",
"@types/passport-jwt": "^3.0.6",
"@types/supertest": "^2.0.12",
Expand Down
9 changes: 8 additions & 1 deletion server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
useDBAsSourceOfTruth,
useDockerAsSourceOfTruth,
} from "./utils/startup";
import cron from "node-cron";
import { refreshServicesStatuses } from "./utils/refresh";

const app = createServer();
const httpServer = http.createServer(app);
Expand All @@ -25,7 +27,6 @@ const port =
httpServer.listen(port, async () => {
logger.info(`Express server started on port ${port}`);
await connectDB();

if (config.get<boolean>("DOCKER_SOURCE_OF_TRUTH")) {
logger.info("Using Docker as source of truth");
await useDockerAsSourceOfTruth();
Expand All @@ -34,4 +35,10 @@ httpServer.listen(port, async () => {
await useDBAsSourceOfTruth();
}
swaggerDocs(app, port);
const task = cron.schedule("* * * * *", async () => {
logger.info("Refreshing services statuses");
await refreshServicesStatuses();
logger.info("Services statuses refreshed");
});
task.start();
});
7 changes: 5 additions & 2 deletions server/src/controllers/services.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,12 @@ export const attachContainerToService = async (
const containerInfo = await container.inspect();
service.network = containerInfo.HostConfig.NetworkMode;
service.environmentVariables = containerInfo.Config.Env.map((envString) => {
// TODO: split on first equal BUT NOT ALWAYS CORRECT
const i = envString.indexOf("=");
const [key, value] = [envString.slice(0, i), envString.slice(i + 1)];
return {
key: envString.split("=")[0].trim(),
value: envString.split("=")[1].trim(),
key,
value,
};
});
service.containerId = container.id;
Expand Down
36 changes: 36 additions & 0 deletions server/src/utils/refresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { inspectContainerById } from "../../libs/docker";
import { findAllServices, saveService } from "../services/services.service";
import { ServiceStatus } from "../types/enums/ServiceStatus";
import logger from "./logger";

export const refreshServicesStatuses = async () => {
const services = await findAllServices();
for (const service of services) {
const containerId = service.containerId ?? undefined;
if (!containerId) {
continue;
}
try {
const containerInfo = await inspectContainerById(containerId);

const containerState = containerInfo.State;
if (containerState.Running) {
service.status = ServiceStatus.RUNNING;
} else if (containerState.Paused) {
service.status = ServiceStatus.STOPPED;
} else if (containerState.Restarting) {
service.status = ServiceStatus.CREATED;
} else if (containerState.Dead || containerState.Error) {
service.status = ServiceStatus.ERROR;
} else {
service.status = ServiceStatus.CREATED;
}
await saveService(service);
} catch (e) {
logger.error(`Failed refreshing service ${service.name} status`);
service.status = ServiceStatus.ERROR;
await saveService(service);
continue;
}
}
};
24 changes: 24 additions & 0 deletions server/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,11 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==

"@types/node-cron@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/node-cron/-/node-cron-3.0.1.tgz#e01a874d4c2aa1a02ebc64cfd1cd8ebdbad7a996"
integrity sha512-BkMHHonDT8NJUE/pQ3kr5v2GLDKm5or9btLBoBx4F2MB2cuqYC748LYMDC55VlrLI5qZZv+Qgc3m4P3dBPcmeg==

"@types/node@*", "@types/node@^17.0.31":
version "17.0.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d"
Expand Down Expand Up @@ -3399,6 +3404,18 @@ mkdirp-classic@^0.5.2:
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==

moment-timezone@^0.5.31:
version "0.5.34"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c"
integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==
dependencies:
moment ">= 2.9.0"

"moment@>= 2.9.0":
version "2.29.3"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3"
integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==

mongodb-connection-string-url@^2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz#f075c8d529e8d3916386018b8a396aed4f16e5ed"
Expand Down Expand Up @@ -3479,6 +3496,13 @@ negotiator@0.6.3:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==

node-cron@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/node-cron/-/node-cron-3.0.0.tgz#b33252803e430f9cd8590cf85738efa1497a9522"
integrity sha512-DDwIvvuCwrNiaU7HEivFDULcaQualDv7KoNlB/UU1wPW0n1tDEmBJKhEIE6DlF2FuoOHcNbLJ8ITL2Iv/3AWmA==
dependencies:
moment-timezone "^0.5.31"

node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
Expand Down