diff --git a/lib/k8s/server-control.js b/lib/k8s/server-control.js
index 63097e6..bcb5a35 100644
--- a/lib/k8s/server-control.js
+++ b/lib/k8s/server-control.js
@@ -11,7 +11,6 @@ const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sMetrics = new k8s.Metrics(kc);
-const k8sDeps = kc.makeApiClient(k8s.AppsV1Api);
const namespace = process.env.MCL_SERVER_NAMESPACE;
export async function startServerContainer(serverSpec) {
@@ -43,17 +42,26 @@ export async function stopServerContainer(serverSpec) {
export async function getInstances() {
const serverDeployments = await getDeployments();
const podMetricsResponse = await k8sMetrics.getPodMetrics(namespace);
- var name, metrics, started;
+ var name, metrics, services, serverAvailable, ftpAvailable;
const serverInstances = serverDeployments.map((s) => {
name = s.metadata.annotations["minecluster.dunemask.net/server-name"];
metrics = null;
- started = !!s.spec.template.spec.containers.find((c) =>
- c.name.includes(`mcl-${name}-server`),
+ const { containers } = s.spec.template.spec;
+ services = containers.map(({ name }) => name.split("-").pop());
+ const serverStatusList = s.status.conditions.map(
+ ({ type: statusType, status: sts }) => ({ statusType, sts }),
);
+ const deploymentAvailable =
+ serverStatusList.find(
+ (ss) => ss.statusType === "Available" && ss.sts === "True",
+ ) !== undefined;
+ serverAvailable = services.includes(`server`) && deploymentAvailable;
+ ftpAvailable = services.includes("ftp") && deploymentAvailable;
+
const pod = podMetricsResponse.items.find(({ metadata: md }) => {
return md.labels && md.labels.app && md.labels.app === `mcl-${name}-app`;
});
- if (started && pod) {
+ if (serverAvailable && pod) {
const podCpus = pod.containers.map(
({ usage }) => parseInt(usage.cpu) / 1_000_000,
);
@@ -65,7 +73,7 @@ export async function getInstances() {
memory: Math.ceil(podMems.reduce((a, b) => a + b)),
};
}
- return { name, metrics, started };
+ return { name, metrics, services, serverAvailable, ftpAvailable };
});
return serverInstances;
}
diff --git a/src/components/files/MineclusterFiles.jsx b/src/components/files/MineclusterFiles.jsx
index 6c0079d..45bce13 100644
--- a/src/components/files/MineclusterFiles.jsx
+++ b/src/components/files/MineclusterFiles.jsx
@@ -38,26 +38,33 @@ export default function MineclusterFiles(props) {
const [dirStack, setDirStack] = useState(["."]);
const [files, setFiles] = useState([]);
- const updateFiles = () =>
- getServerFiles(serverName, dirStack.join("/")).then((f) =>
- setFiles(f ?? []),
- );
+ const updateFiles = () => {
+ const dir = dirStack.join("/");
+ getServerFiles(serverName, dir).then((f) => {
+ const files = f.map((fi) => ({ ...fi, id: `${dir}/${fi.name}` }));
+ setFiles(files ?? []);
+ });
+ };
useEffect(() => {
updateFiles();
}, [dirStack]);
const getFolderChain = () => {
- if (dirStack.length === 1) return [{ id: "home", name: "/", isDir: true }];
- return dirStack.map((d, i) => ({ id: `${d}-${i}`, name: d, isDir: true }));
+ if (dirStack.length === 1) return [{ id: "./", name: "Home", isDir: true }];
+ return dirStack.map((d, i) => ({
+ id: `${dirStack.slice(0, i + 1).join("/")}`,
+ name: i === 0 ? "Home" : d,
+ isDir: true,
+ }));
};
const openParentFolder = () => setDirStack(dirStack.slice(0, -1));
function openFolder(payload) {
const { targetFile: file } = payload;
- if (!file || !file.isDir) return;
- setDirStack([...dirStack, file.name]);
+ if (file && file.isDir) return setDirStack(file.id.split("/"));
+ if (file && !file.isDir) return downloadFiles([file]);
}
function createFolder() {
@@ -101,13 +108,12 @@ export default function MineclusterFiles(props) {
getServerItem(serverName, f.name, [...dirStack, f.name].join("/")),
),
)
- .then(() => console.log("Done"))
+ .then(() => console.log("Done downloading files!"))
.catch((e) => console.error("Error Downloading files!", e));
}
function fileClick(chonkyEvent) {
const { id: clickEvent, payload } = chonkyEvent;
- console.log(chonkyEvent);
if (clickEvent === "open_parent_folder") return openParentFolder();
if (clickEvent === "create_folder") return createFolder();
if (clickEvent === "upload_files") return inputRef.current.click();
@@ -115,7 +121,7 @@ export default function MineclusterFiles(props) {
return downloadFiles(chonkyEvent.state.selectedFilesForAction);
if (clickEvent === "delete_files")
return deleteItems(chonkyEvent.state.selectedFilesForAction);
- if (clickEvent !== "open_files") return console.log(clickEvent);
+ if (clickEvent !== "open_files") return; // console.log(clickEvent);
openFolder(payload);
}
return (
diff --git a/src/components/servers/ServerCard.jsx b/src/components/servers/ServerCard.jsx
index 4eec631..d3a65e0 100644
--- a/src/components/servers/ServerCard.jsx
+++ b/src/components/servers/ServerCard.jsx
@@ -19,12 +19,12 @@ import { Link } from "react-router-dom";
export default function ServerCard(props) {
const { server, openRcon } = props;
- const { name, metrics, started } = server;
+ const { name, metrics, ftpAvailable, serverAvailable, services } = server;
const startServer = useStartServer(name);
const stopServer = useStopServer(name);
const deleteServer = useDeleteServer(name);
function toggleRcon() {
- if (!started) return;
+ if (!services.includes("server")) return;
openRcon();
}
@@ -60,14 +60,26 @@ export default function ServerCard(props) {
)}