@tyevco/homelab-lxc-agent 1.9.5 → 1.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lxc.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.joinExecTerminal = exports.getDistributions = exports.createContainer = exports.saveConfig = exports.deleteContainer = exports.unfreezeContainer = exports.freezeContainer = exports.restartContainer = exports.stopContainer = exports.startContainer = exports.getContainer = exports.getContainerList = exports.STACK_TYPE_LXC = exports.FROZEN = exports.EXITED = exports.RUNNING = exports.UNKNOWN = void 0;
26
+ exports.joinExecTerminal = exports.getDistributions = exports.cloneContainer = exports.createContainer = exports.saveConfig = exports.deleteContainer = exports.unfreezeContainer = exports.freezeContainer = exports.restartContainer = exports.stopContainer = exports.startContainer = exports.getContainer = exports.getContainerList = exports.STACK_TYPE_LXC = exports.FROZEN = exports.EXITED = exports.RUNNING = exports.UNKNOWN = void 0;
27
27
  const promisify_child_process_1 = require("promisify-child-process");
28
28
  const fs = __importStar(require("fs"));
29
29
  const path = __importStar(require("path"));
@@ -241,7 +241,7 @@ async function saveConfig(name, config) {
241
241
  console.log(`[lxc] Config saved for: ${name}`);
242
242
  }
243
243
  exports.saveConfig = saveConfig;
244
- async function createContainer(socket, endpoint, name, dist, release, arch) {
244
+ async function createContainer(socket, endpoint, name, dist, release, arch, initialConfig) {
245
245
  if (!/^[a-z0-9_.-]+$/.test(name)) {
246
246
  throw new Error("Invalid container name");
247
247
  }
@@ -259,9 +259,36 @@ async function createContainer(socket, endpoint, name, dist, release, arch) {
259
259
  if (code !== 0) {
260
260
  throw new Error("Failed to create LXC container");
261
261
  }
262
+ if (initialConfig) {
263
+ await appendConfig(name, initialConfig);
264
+ }
262
265
  console.log(`[lxc] Created: ${name}`);
263
266
  }
264
267
  exports.createContainer = createContainer;
268
+ async function cloneContainer(socket, endpoint, sourceName, destName, initialConfig) {
269
+ if (!/^[a-z0-9_.-]+$/.test(sourceName)) {
270
+ throw new Error("Invalid source container name");
271
+ }
272
+ if (!/^[a-z0-9_.-]+$/.test(destName)) {
273
+ throw new Error("Invalid destination container name");
274
+ }
275
+ console.log(`[lxc] Cloning container: ${sourceName} → ${destName}`);
276
+ const code = await terminal_1.AgentTerminal.exec(socket, getLxcTerminalName(endpoint, destName), "lxc-copy", ["-n", sourceName, "-N", destName], LXC_PATH);
277
+ if (code !== 0) {
278
+ throw new Error("Failed to clone LXC container");
279
+ }
280
+ if (initialConfig) {
281
+ await appendConfig(destName, initialConfig);
282
+ }
283
+ console.log(`[lxc] Cloned: ${sourceName} → ${destName}`);
284
+ }
285
+ exports.cloneContainer = cloneContainer;
286
+ async function appendConfig(name, extra) {
287
+ const configPath = path.join(LXC_PATH, name, "config");
288
+ const existing = await fs.promises.readFile(configPath, "utf-8").catch(() => "");
289
+ const separator = existing.endsWith("\n") ? "" : "\n";
290
+ await fs.promises.writeFile(configPath, existing + separator + "\n" + extra.trimEnd() + "\n");
291
+ }
265
292
  async function getDistributions() {
266
293
  const distributions = [];
267
294
  try {
package/dist/server.js CHANGED
@@ -256,12 +256,25 @@ async function dispatch(socket, endpoint, eventName, args) {
256
256
  break;
257
257
  }
258
258
  case "createLxcContainer": {
259
- const [name, dist, release, arch] = args;
260
- await lxc.createContainer(socket, endpoint, name, dist, release, arch);
259
+ const [name, dist, release, arch, initialConfig] = args;
260
+ await lxc.createContainer(socket, endpoint, name, dist, release, arch, initialConfig || undefined);
261
261
  await pushList();
262
262
  ok("Created");
263
263
  break;
264
264
  }
265
+ case "cloneLxcContainer": {
266
+ const [sourceName, destName, initialConfig] = args;
267
+ if (typeof sourceName !== "string") {
268
+ throw new Error("Source name must be a string");
269
+ }
270
+ if (typeof destName !== "string") {
271
+ throw new Error("Destination name must be a string");
272
+ }
273
+ await lxc.cloneContainer(socket, endpoint, sourceName, destName, initialConfig || undefined);
274
+ await pushList();
275
+ ok("Cloned");
276
+ break;
277
+ }
265
278
  case "getLxcDistributions": {
266
279
  const distributions = await lxc.getDistributions();
267
280
  callback?.({ ok: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyevco/homelab-lxc-agent",
3
- "version": "1.9.5",
3
+ "version": "1.9.7",
4
4
  "description": "Lightweight LXC agent for Homelab",
5
5
  "bin": {
6
6
  "homelab-lxc-agent": "bin/homelab-lxc-agent.js"