mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 18:31:52 +00:00
Feature/disk usage (#2637)
* feat: Add disk usage * Fixed: let the set config work with nesting. * chore: Changes * chore: Add default route * fix: Tor only config * chore
This commit is contained in:
@@ -2,7 +2,7 @@ import { types as T, utils, EmVer } from "@start9labs/start-sdk"
|
||||
import * as fs from "fs/promises"
|
||||
|
||||
import { PolyfillEffects } from "./polyfillEffects"
|
||||
import { Duration, duration } from "../../../Models/Duration"
|
||||
import { Duration, duration, fromDuration } from "../../../Models/Duration"
|
||||
import { System } from "../../../Interfaces/System"
|
||||
import { matchManifest, Manifest, Procedure } from "./matchManifest"
|
||||
import * as childProcess from "node:child_process"
|
||||
@@ -478,10 +478,13 @@ export class SystemForEmbassy implements System {
|
||||
delete this.currentRunning
|
||||
if (currentRunning) {
|
||||
await currentRunning.clean({
|
||||
timeout: this.manifest.main["sigterm-timeout"],
|
||||
timeout: fromDuration(this.manifest.main["sigterm-timeout"]),
|
||||
})
|
||||
}
|
||||
const durationValue = duration(this.manifest.main["sigterm-timeout"], "s")
|
||||
const durationValue = duration(
|
||||
fromDuration(this.manifest.main["sigterm-timeout"]),
|
||||
"s",
|
||||
)
|
||||
return durationValue
|
||||
}
|
||||
private async createBackup(
|
||||
@@ -967,7 +970,7 @@ async function updateConfig(
|
||||
|
||||
const newConfigValue = mutConfigValue[key]
|
||||
if (matchSpec.test(specValue)) {
|
||||
const updateObject = { spec: null }
|
||||
const updateObject = { spec: newConfigValue }
|
||||
await updateConfig(
|
||||
effects,
|
||||
manifest,
|
||||
@@ -1001,6 +1004,10 @@ async function updateConfig(
|
||||
manifest,
|
||||
specInterface,
|
||||
)
|
||||
if (!serviceInterfaceId) {
|
||||
mutConfigValue[key] = ""
|
||||
return
|
||||
}
|
||||
const filled = await utils
|
||||
.getServiceInterface(effects, {
|
||||
packageId: specValue["package-id"],
|
||||
@@ -1035,8 +1042,16 @@ async function updateConfig(
|
||||
}
|
||||
}
|
||||
function extractServiceInterfaceId(manifest: Manifest, specInterface: string) {
|
||||
let serviceInterfaceId
|
||||
const lanConfig = manifest.interfaces[specInterface]?.["lan-config"] || {}
|
||||
serviceInterfaceId = `${specInterface}-${Object.entries(lanConfig)[0]?.[1]?.internal}`
|
||||
const internalPort =
|
||||
Object.entries(
|
||||
manifest.interfaces[specInterface]?.["lan-config"] || {},
|
||||
)[0]?.[1]?.internal ||
|
||||
Object.entries(
|
||||
manifest.interfaces[specInterface]?.["tor-config"]?.["port-mapping"] ||
|
||||
{},
|
||||
)?.[0]?.[1]
|
||||
|
||||
if (!internalPort) return null
|
||||
const serviceInterfaceId = `${specInterface}-${internalPort}`
|
||||
return serviceInterfaceId
|
||||
}
|
||||
|
||||
@@ -120,6 +120,10 @@ export type Effects = {
|
||||
/// Returns the body as a json
|
||||
json(): Promise<unknown>
|
||||
}>
|
||||
diskUsage(options?: {
|
||||
volumeId: string
|
||||
path: string
|
||||
}): Promise<{ used: number; total: number }>
|
||||
|
||||
runRsync(options: {
|
||||
srcVolume: string
|
||||
|
||||
@@ -8,7 +8,8 @@ import { HostSystemStartOs } from "../../HostSystemStartOs"
|
||||
import "isomorphic-fetch"
|
||||
import { Manifest } from "./matchManifest"
|
||||
import { DockerProcedureContainer } from "./DockerProcedureContainer"
|
||||
|
||||
import * as cp from "child_process"
|
||||
export const execFile = promisify(cp.execFile)
|
||||
export class PolyfillEffects implements oet.Effects {
|
||||
constructor(
|
||||
readonly effects: HostSystemStartOs,
|
||||
@@ -104,7 +105,9 @@ export class PolyfillEffects implements oet.Effects {
|
||||
stderr: x.stderr.toString(),
|
||||
stdout: x.stdout.toString(),
|
||||
}))
|
||||
.then((x) => (!!x.stderr ? { error: x.stderr } : { result: x.stdout }))
|
||||
.then((x: any) =>
|
||||
!!x.stderr ? { error: x.stderr } : { result: x.stdout },
|
||||
)
|
||||
}
|
||||
runDaemon(input: { command: string; args?: string[] | undefined }): {
|
||||
wait(): Promise<oet.ResultType<string>>
|
||||
@@ -163,7 +166,7 @@ export class PolyfillEffects implements oet.Effects {
|
||||
stderr: x.stderr.toString(),
|
||||
stdout: x.stdout.toString(),
|
||||
}))
|
||||
.then((x) => {
|
||||
.then((x: any) => {
|
||||
if (!!x.stderr) {
|
||||
throw new Error(x.stderr)
|
||||
}
|
||||
@@ -198,7 +201,7 @@ export class PolyfillEffects implements oet.Effects {
|
||||
stderr: x.stderr.toString(),
|
||||
stdout: x.stdout.toString(),
|
||||
}))
|
||||
.then((x) => {
|
||||
.then((x: any) => {
|
||||
if (!!x.stderr) {
|
||||
throw new Error(x.stderr)
|
||||
}
|
||||
@@ -352,7 +355,7 @@ export class PolyfillEffects implements oet.Effects {
|
||||
return String(pid)
|
||||
}
|
||||
const waitPromise = new Promise<null>((resolve, reject) => {
|
||||
spawned.on("exit", (code) => {
|
||||
spawned.on("exit", (code: any) => {
|
||||
if (code === 0) {
|
||||
resolve(null)
|
||||
} else {
|
||||
@@ -364,4 +367,55 @@ export class PolyfillEffects implements oet.Effects {
|
||||
const progress = () => Promise.resolve(percentage)
|
||||
return { id, wait, progress }
|
||||
}
|
||||
async diskUsage(
|
||||
options?: { volumeId: string; path: string } | undefined,
|
||||
): Promise<{ used: number; total: number }> {
|
||||
const output = await execFile("df", ["--block-size=1", "-P", "/"])
|
||||
.then((x: any) => ({
|
||||
stderr: x.stderr.toString(),
|
||||
stdout: x.stdout.toString(),
|
||||
}))
|
||||
.then((x: any) => {
|
||||
if (!!x.stderr) {
|
||||
throw new Error(x.stderr)
|
||||
}
|
||||
return parseDfOutput(x.stdout)
|
||||
})
|
||||
if (!!options) {
|
||||
const used = await execFile("du", [
|
||||
"-s",
|
||||
"--block-size=1",
|
||||
"-P",
|
||||
new Volume(options.volumeId, options.path).path,
|
||||
])
|
||||
.then((x: any) => ({
|
||||
stderr: x.stderr.toString(),
|
||||
stdout: x.stdout.toString(),
|
||||
}))
|
||||
.then((x: any) => {
|
||||
if (!!x.stderr) {
|
||||
throw new Error(x.stderr)
|
||||
}
|
||||
return Number.parseInt(x.stdout.split(/\s+/)[0])
|
||||
})
|
||||
return {
|
||||
...output,
|
||||
used,
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
function parseDfOutput(output: string): { used: number; total: number } {
|
||||
const lines = output
|
||||
.split("\n")
|
||||
.filter((x) => x.length)
|
||||
.map((x) => x.split(/\s+/))
|
||||
const index = lines.splice(0, 1)[0].map((x) => x.toLowerCase())
|
||||
const usedIndex = index.indexOf("used")
|
||||
const availableIndex = index.indexOf("available")
|
||||
const used = lines.map((x) => Number.parseInt(x[usedIndex]))[0] || 0
|
||||
const total = lines.map((x) => Number.parseInt(x[availableIndex]))[0] || 0
|
||||
return { used, total }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user