dokku-compose 0.3.5 → 0.3.6

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.
Files changed (2) hide show
  1. package/dist/index.js +63 -25
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { Command } from "commander";
5
5
  import * as fs3 from "fs";
6
6
  import * as yaml3 from "js-yaml";
7
+ import { createRequire } from "module";
7
8
 
8
9
  // src/core/config.ts
9
10
  import * as fs from "fs";
@@ -99,12 +100,17 @@ function loadConfig(filePath) {
99
100
 
100
101
  // src/core/dokku.ts
101
102
  import { execa } from "execa";
103
+ import { createHash } from "crypto";
104
+ import * as os from "os";
105
+ import * as path from "path";
102
106
  function createRunner(opts = {}) {
103
107
  const log = [];
108
+ const controlPath = opts.host ? path.join(os.tmpdir(), `dc-${createHash("sha1").update(opts.host).digest("hex").slice(0, 16)}.sock`) : null;
109
+ const sshControlFlags = controlPath ? ["-o", "ControlMaster=auto", "-o", `ControlPath=${controlPath}`, "-o", "ControlPersist=60"] : [];
104
110
  async function execDokku(args) {
105
111
  if (opts.host) {
106
112
  try {
107
- const result = await execa("ssh", [`dokku@${opts.host}`, ...args]);
113
+ const result = await execa("ssh", [...sshControlFlags, `dokku@${opts.host}`, ...args]);
108
114
  return { stdout: result.stdout, ok: true };
109
115
  } catch (e) {
110
116
  return { stdout: e.stdout ?? "", ok: false };
@@ -136,6 +142,13 @@ function createRunner(opts = {}) {
136
142
  if (opts.dryRun) return false;
137
143
  const { ok } = await execDokku(args);
138
144
  return ok;
145
+ },
146
+ async close() {
147
+ if (!opts.host || !controlPath) return;
148
+ try {
149
+ await execa("ssh", ["-O", "exit", "-o", `ControlPath=${controlPath}`, `dokku@${opts.host}`]);
150
+ } catch {
151
+ }
139
152
  }
140
153
  };
141
154
  }
@@ -694,6 +707,9 @@ async function runDown(runner, config, appFilter, opts) {
694
707
  // src/commands/export.ts
695
708
  async function runExport(runner, opts) {
696
709
  const config = { apps: {} };
710
+ const versionOutput = await runner.query("version");
711
+ const versionMatch = versionOutput.match(/(\d+\.\d+\.\d+)/);
712
+ if (versionMatch) config.dokku = { version: versionMatch[1] };
697
713
  const apps = opts.appFilter?.length ? opts.appFilter : await exportApps(runner);
698
714
  const networks = await exportNetworks(runner);
699
715
  if (networks.length > 0) config.networks = networks;
@@ -893,7 +909,9 @@ function validate(filePath) {
893
909
  }
894
910
 
895
911
  // src/index.ts
896
- var program = new Command().name("dokku-compose").version("0.3.0");
912
+ var require2 = createRequire(import.meta.url);
913
+ var { version } = require2("../package.json");
914
+ var program = new Command().name("dokku-compose").version(version);
897
915
  function makeRunner(opts) {
898
916
  return createRunner({
899
917
  host: process.env.DOKKU_HOST,
@@ -903,10 +921,14 @@ function makeRunner(opts) {
903
921
  program.command("up [apps...]").description("Create/update apps and services to match config").option("-f, --file <path>", "Config file", "dokku-compose.yml").option("--dry-run", "Print commands without executing").option("--fail-fast", "Stop on first error").action(async (apps, opts) => {
904
922
  const config = loadConfig(opts.file);
905
923
  const runner = makeRunner(opts);
906
- await runUp(runner, config, apps);
907
- if (opts.dryRun) {
908
- console.log("\n# Commands that would run:");
909
- for (const cmd of runner.dryRunLog) console.log(`dokku ${cmd}`);
924
+ try {
925
+ await runUp(runner, config, apps);
926
+ if (opts.dryRun) {
927
+ console.log("\n# Commands that would run:");
928
+ for (const cmd of runner.dryRunLog) console.log(`dokku ${cmd}`);
929
+ }
930
+ } finally {
931
+ await runner.close();
910
932
  }
911
933
  });
912
934
  program.command("down [apps...]").description("Destroy apps and services (requires --force)").option("-f, --file <path>", "Config file", "dokku-compose.yml").option("--force", "Required to destroy apps").action(async (apps, opts) => {
@@ -916,7 +938,11 @@ program.command("down [apps...]").description("Destroy apps and services (requir
916
938
  }
917
939
  const config = loadConfig(opts.file);
918
940
  const runner = makeRunner({});
919
- await runDown(runner, config, apps, { force: true });
941
+ try {
942
+ await runDown(runner, config, apps, { force: true });
943
+ } finally {
944
+ await runner.close();
945
+ }
920
946
  });
921
947
  program.command("validate [file]").description("Validate dokku-compose.yml without touching the server").action((file = "dokku-compose.yml") => {
922
948
  const result = validate(file);
@@ -936,33 +962,45 @@ ${result.errors.length} error(s), ${result.warnings.length} warning(s)`);
936
962
  });
937
963
  program.command("export").description("Export server state to dokku-compose.yml format").option("--app <app>", "Export only a specific app").option("-o, --output <path>", "Write to file instead of stdout").action(async (opts) => {
938
964
  const runner = makeRunner({});
939
- const result = await runExport(runner, {
940
- appFilter: opts.app ? [opts.app] : void 0
941
- });
942
- const out = yaml3.dump(result, { lineWidth: 120 });
943
- if (opts.output) {
944
- fs3.writeFileSync(opts.output, out);
945
- console.error(`Written to ${opts.output}`);
946
- } else {
947
- process.stdout.write(out);
965
+ try {
966
+ const result = await runExport(runner, {
967
+ appFilter: opts.app ? [opts.app] : void 0
968
+ });
969
+ const out = yaml3.dump(result, { lineWidth: 120 });
970
+ if (opts.output) {
971
+ fs3.writeFileSync(opts.output, out);
972
+ console.error(`Written to ${opts.output}`);
973
+ } else {
974
+ process.stdout.write(out);
975
+ }
976
+ } finally {
977
+ await runner.close();
948
978
  }
949
979
  });
950
980
  program.command("diff").description("Show what is out of sync between config and server").option("-f, --file <path>", "Config file", "dokku-compose.yml").option("--verbose", "Show git-style +/- diff").action(async (opts) => {
951
981
  const desired = loadConfig(opts.file);
952
982
  const runner = makeRunner({});
953
- const current = await runExport(runner, {
954
- appFilter: Object.keys(desired.apps)
955
- });
956
- const diff = computeDiff(desired, current);
957
- const output = opts.verbose ? formatVerbose(diff) : formatSummary(diff);
958
- process.stdout.write(output);
959
- process.exit(diff.inSync ? 0 : 1);
983
+ try {
984
+ const current = await runExport(runner, {
985
+ appFilter: Object.keys(desired.apps)
986
+ });
987
+ const diff = computeDiff(desired, current);
988
+ const output = opts.verbose ? formatVerbose(diff) : formatSummary(diff);
989
+ process.stdout.write(output);
990
+ process.exit(diff.inSync ? 0 : 1);
991
+ } finally {
992
+ await runner.close();
993
+ }
960
994
  });
961
995
  program.command("ps [apps...]").description("Show status of configured apps").option("-f, --file <path>", "Config file", "dokku-compose.yml").action(async (apps, opts) => {
962
996
  const config = loadConfig(opts.file);
963
997
  const runner = makeRunner({});
964
- const { runPs } = await import("./ps-33II4UU3.js");
965
- await runPs(runner, config, apps);
998
+ try {
999
+ const { runPs } = await import("./ps-33II4UU3.js");
1000
+ await runPs(runner, config, apps);
1001
+ } finally {
1002
+ await runner.close();
1003
+ }
966
1004
  });
967
1005
  program.command("init [apps...]").description("Create a starter dokku-compose.yml").option("-f, --file <path>", "Config file", "dokku-compose.yml").action(async (apps, opts) => {
968
1006
  const { runInit } = await import("./init-GIXEVLNW.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dokku-compose",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Docker Compose for Dokku — declare your entire server in a single YAML file.",
5
5
  "main": "dist/index.js",
6
6
  "exports": "./dist/index.js",