Skip to content

Commit

Permalink
Merge pull request #18 from fluentci-io/feat/flu-28-agent-list-subcom…
Browse files Browse the repository at this point in the history
…mand

feat: add `agent list` subcommand
  • Loading branch information
tsirysndr authored Jan 11, 2024
2 parents 8dfe85b + 330cc6b commit d8f5ffa
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fluentci # Run the pipeline
fluentci --help

Usage: fluentci [pipeline] [jobs...]
Version: 0.10.6
Version: 0.10.7

Description:

Expand Down
136 changes: 136 additions & 0 deletions deno.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ import Logger from "https://deno.land/x/[email protected]/logger.ts";
export { Logger };
export { generateName } from "https://deno.land/x/[email protected]/mod.ts";
import dayjs from "npm:dayjs";
import relativeTime from "npm:dayjs/plugin/relativeTime.js";
dayjs.extend(relativeTime);
export { dayjs };
import { Buffer } from "npm:buffer";
export { Buffer };
export { mergeReadableStreams } from "https://deno.land/[email protected]/streams/merge_readable_streams.ts";
export {
Cell,
Table,
} from "https://deno.land/x/[email protected]/table/mod.ts";
15 changes: 12 additions & 3 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import doctor from "./src/cmd/doctor.ts";
import showEnvs from "./src/cmd/env.ts";
import login from "./src/cmd/login.ts";
import publish from "./src/cmd/publish.ts";
import startAgent from "./src/cmd/agent.ts";
import startAgent, { listAgents } from "./src/cmd/agent.ts";
import whoami from "./src/cmd/whoami.ts";
import { brightGreen } from "./deps.ts";

export async function main() {
await new Command()
.name("fluentci")
.version("0.10.6")
.version("0.10.7")
.description(
`
.
Expand Down Expand Up @@ -201,7 +201,16 @@ export async function main() {
.action(async function () {
await publish();
})
.command("agent", "Start FluentCI Runner Agent")
.command(
"agent",
new Command()
.command("list", "List all agents")
.alias("ls")
.action(async function () {
await listAgents();
})
)
.description("Start FluentCI Runner Agent")
.action(async function () {
await startAgent();
})
Expand Down
60 changes: 53 additions & 7 deletions src/cmd/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import {
generateName,
ZipReader,
BlobReader,
Table,
dayjs,
} from "../../deps.ts";
import {
FLUENTCI_WS_URL,
RUNNER_URL,
FLUENTCI_EVENTS_URL,
BUILD_DIR,
} from "../consts.ts";
import { getAccessToken, isLogged } from "../utils.ts";
import { formatBytes, getAccessToken, isLogged } from "../utils.ts";
import { hostname, release, cpus, arch, totalmem, platform } from "node:os";
import { Agent } from "../types.ts";

async function startAgent() {
console.log(`
Expand Down Expand Up @@ -197,12 +201,54 @@ async function spawnFluentCI(

async function getWebSocketUuid(agentId: string) {
const accessToken = await getAccessToken();
const uuid = await fetch(`${FLUENTCI_EVENTS_URL}/auth?agent_id=${agentId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
}).then((res) => res.text());
const uuid = await fetch(
`${FLUENTCI_EVENTS_URL}/auth?agent_id=${agentId}&hostname=${hostname()}&release=${release()}&cpus=${
cpus().length
}&arch=${arch()}&totalmem=${totalmem()}&platform=${platform()}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
).then((res) => res.text());
return uuid;
}

export async function listAgents() {
const accessToken = await getAccessToken();
const userId = await fetch(
`https://api.fluentci.io/validate?token=${accessToken}`
).then((res) => res.text());
const agents: Agent[] = await fetch(
`${FLUENTCI_EVENTS_URL}?id=${userId}`
).then((res) => res.json());

if (!agents.length) {
console.log("No agents found");
return;
}

const table = new Table();
table.header([
"NAME",
"HOSTNAME",
"RELEASE",
"CPUs",
"ARCH",
"RAM",
"OS",
"STARTED AT",
]);

for (const agent of agents) {
const rows = Object.values(agent);
rows[5] = formatBytes(rows[5] as number);
rows[7] = dayjs(rows[7]).fromNow();
table.push(rows.map((x) => (x === 0 || x === "0 Bytes" ? "" : x)));
}

table.render();
}

export default startAgent;
13 changes: 13 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@ export const LogEventSchema = z.object({
}),
});

export const AgentSchema = z.object({
agent_id: z.string(),
hostname: z.string(),
release: z.string(),
cpus: z.number(),
arch: z.string(),
totalmem: z.number(),
platform: z.string(),
startedAt: z.string(),
});

export type Pipeline = z.infer<typeof PipelineSchema>;

export type Label = z.infer<typeof LabelSchema>;

export type LogEvent = z.infer<typeof LogEventSchema>;

export type Agent = z.infer<typeof AgentSchema>;
13 changes: 13 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,16 @@ export function getAccessToken(): string | undefined {
return undefined;
}
}

export function formatBytes(bytes: number, decimals = 2) {
if (bytes === 0) return "0 Bytes";

const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];

const i = Math.floor(Math.log(bytes) / Math.log(k));

return (
parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i]
);
}

0 comments on commit d8f5ffa

Please sign in to comment.