@procedures/tailscale 0.27.8 → 0.28.1
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/CHANGELOG.md +48 -0
- package/README.md +7 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/module.d.ts +10 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +14 -1
- package/dist/module.js.map +1 -1
- package/dist/procedures.d.ts +18 -2
- package/dist/procedures.d.ts.map +1 -1
- package/dist/procedures.js +77 -38
- package/dist/procedures.js.map +1 -1
- package/package.json +3 -3
- package/src/module.ts +14 -1
- package/src/procedures.ts +85 -37
package/dist/module.d.ts
CHANGED
|
@@ -2,8 +2,18 @@
|
|
|
2
2
|
* The procedures of @procedures/tailscale as data. Importing this file registers nothing.
|
|
3
3
|
*/
|
|
4
4
|
import { type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
|
|
5
|
+
import { type TailscaleProceduresOptions } from "./procedures.js";
|
|
5
6
|
export declare const tailscaleModule: ProcedureModule;
|
|
6
7
|
export default tailscaleModule;
|
|
8
|
+
/**
|
|
9
|
+
* This function gives the module with the settings of the host: the tailscale program. Without
|
|
10
|
+
* options, it gives `tailscaleModule`.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function createTailscaleModule(options?: TailscaleProceduresOptions): ProcedureModule;
|
|
7
17
|
/**
|
|
8
18
|
* This function registers the procedures of @procedures/tailscale in a registry. The default is the
|
|
9
19
|
* global registry.
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqD,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqD,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAkD,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAElH,eAAO,MAAM,eAAe,EAAE,eAA4E,CAAC;eAE5F,eAAe;AAE9B;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,0BAA+B,GAAG,eAAe,CAG/F;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,GAAE,iBAAsC,GAAG,IAAI,CAElG"}
|
package/dist/module.js
CHANGED
|
@@ -2,9 +2,22 @@
|
|
|
2
2
|
* The procedures of @procedures/tailscale as data. Importing this file registers nothing.
|
|
3
3
|
*/
|
|
4
4
|
import { defineModule, registerModules, PROCEDURE_REGISTRY } from "@procedures/client";
|
|
5
|
-
import { tailscaleProcedures } from "./procedures.js";
|
|
5
|
+
import { createTailscaleProcedures, tailscaleProcedures } from "./procedures.js";
|
|
6
6
|
export const tailscaleModule = defineModule("@procedures/tailscale", tailscaleProcedures);
|
|
7
7
|
export default tailscaleModule;
|
|
8
|
+
/**
|
|
9
|
+
* This function gives the module with the settings of the host: the tailscale program. Without
|
|
10
|
+
* options, it gives `tailscaleModule`.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function createTailscaleModule(options = {}) {
|
|
17
|
+
if (options.executable === undefined)
|
|
18
|
+
return tailscaleModule;
|
|
19
|
+
return defineModule("@procedures/tailscale", createTailscaleProcedures(options));
|
|
20
|
+
}
|
|
8
21
|
/**
|
|
9
22
|
* This function registers the procedures of @procedures/tailscale in a registry. The default is the
|
|
10
23
|
* global registry.
|
package/dist/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAgD,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAgD,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAmC,MAAM,iBAAiB,CAAC;AAElH,MAAM,CAAC,MAAM,eAAe,GAAoB,YAAY,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAC;AAE3G,eAAe,eAAe,CAAC;AAE/B;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAO,GAA+B,EAAE;IAC5E,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC7D,OAAO,YAAY,CAAC,uBAAuB,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAQ,GAAsB,kBAAkB;IAC1F,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/procedures.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
|
|
3
3
|
* command (`status`, `ip`, `serve`, `up`, `down`).
|
|
4
|
+
*
|
|
5
|
+
* The program comes from the host (audit pass 2, O55): the `executable` option of
|
|
6
|
+
* `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
|
|
7
|
+
* The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
|
|
8
|
+
* notice. Version 0.30.0 removes it, because it lets the caller start any program.
|
|
4
9
|
*/
|
|
5
10
|
import { type AnyProcedure } from "@procedures/client";
|
|
6
|
-
/** This function gives the tailscale program: the
|
|
11
|
+
/** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
|
|
7
12
|
export declare function tailscaleExecutable(explicit?: string): string;
|
|
8
|
-
|
|
13
|
+
/** The settings of the host for the procedures of this package. The procedure input cannot change them. */
|
|
14
|
+
export interface TailscaleProceduresOptions {
|
|
15
|
+
/** The tailscale program. The default is `TAILSCALE_EXE`, then the Windows install folder, then `tailscale`. */
|
|
16
|
+
readonly executable?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* This function gives the procedures of this package with the settings of the host. The program
|
|
20
|
+
* of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
|
|
21
|
+
* deprecated input `executable` wins over both, with a deprecation notice.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createTailscaleProcedures(options?: TailscaleProceduresOptions): AnyProcedure[];
|
|
9
24
|
export declare const tailscaleProcedures: AnyProcedure[];
|
|
25
|
+
export declare const tailscaleRunProcedure: AnyProcedure;
|
|
10
26
|
//# sourceMappingURL=procedures.d.ts.map
|
package/dist/procedures.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAA+B,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAuB3G,gIAAgI;AAChI,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7D;AA8CD,2GAA2G;AAC3G,MAAM,WAAW,0BAA0B;IACzC,gHAAgH;IAChH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,YAAY,EAAE,CAsClG;AAED,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAAgC,CAAC;AAE/E,eAAO,MAAM,qBAAqB,EAAE,YAAsC,CAAC"}
|
package/dist/procedures.js
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
|
|
3
3
|
* command (`status`, `ip`, `serve`, `up`, `down`).
|
|
4
|
+
*
|
|
5
|
+
* The program comes from the host (audit pass 2, O55): the `executable` option of
|
|
6
|
+
* `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
|
|
7
|
+
* The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
|
|
8
|
+
* notice. Version 0.30.0 removes it, because it lets the caller start any program.
|
|
4
9
|
*/
|
|
5
10
|
import { existsSync } from "node:fs";
|
|
6
11
|
import { createProcedure, zodAdapter } from "@procedures/client";
|
|
7
12
|
import { runCommand } from "@procedures/shell/command";
|
|
8
13
|
import { z } from "zod";
|
|
9
14
|
import { buildArgv, parseJsonOutput } from "./argv.js";
|
|
15
|
+
/** The codes of the deprecation notices that this process emitted. */
|
|
16
|
+
const emitted = new Set();
|
|
17
|
+
/** This function emits a deprecation notice one time in each process. */
|
|
18
|
+
function deprecationNotice(code, message) {
|
|
19
|
+
if (emitted.has(code))
|
|
20
|
+
return;
|
|
21
|
+
emitted.add(code);
|
|
22
|
+
process.emitWarning(message, { type: "DeprecationWarning", code });
|
|
23
|
+
}
|
|
24
|
+
/** The notice of the deprecated input `executable` of `tailscale.run`. */
|
|
25
|
+
const EXECUTABLE_INPUT_NOTICE = "The input executable of tailscale.run is deprecated. @procedures/tailscale 0.30.0 refuses it. " +
|
|
26
|
+
"Give the program to the host: createTailscaleModule({ executable }), or set TAILSCALE_EXE.";
|
|
10
27
|
/** The Windows installer does not put tailscale on the PATH. */
|
|
11
28
|
const WINDOWS_PATH = "C:\\Program Files\\Tailscale\\tailscale.exe";
|
|
12
|
-
/** This function gives the tailscale program: the
|
|
29
|
+
/** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
|
|
13
30
|
export function tailscaleExecutable(explicit) {
|
|
14
31
|
if (explicit !== undefined)
|
|
15
32
|
return explicit;
|
|
@@ -29,7 +46,17 @@ const RunInputSchema = z.object({
|
|
|
29
46
|
.optional()
|
|
30
47
|
.describe('The flags, for example { bg: true }'),
|
|
31
48
|
json: z.boolean().default(false).describe("Ask for JSON output (--json) and read it. Only some commands have it (status, serve status)."),
|
|
32
|
-
|
|
49
|
+
/**
|
|
50
|
+
* The tailscale program.
|
|
51
|
+
*
|
|
52
|
+
* @deprecated Give `executable` to `createTailscaleModule()`, or set `TAILSCALE_EXE`. Version
|
|
53
|
+
* 0.30.0 refuses this input (audit pass 2, O55), because it lets the caller start any program.
|
|
54
|
+
*/
|
|
55
|
+
executable: z
|
|
56
|
+
.string()
|
|
57
|
+
.min(1)
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Deprecated: give executable to createTailscaleModule(), or set TAILSCALE_EXE. The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
|
|
33
60
|
timeout: z.number().int().positive().default(60_000).describe("The time limit, in milliseconds (default: 60000)"),
|
|
34
61
|
});
|
|
35
62
|
const RunOutputSchema = z.object({
|
|
@@ -40,40 +67,52 @@ const RunOutputSchema = z.object({
|
|
|
40
67
|
json: z.unknown().optional(),
|
|
41
68
|
actionUrl: z.string().optional(),
|
|
42
69
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
/**
|
|
71
|
+
* This function gives the procedures of this package with the settings of the host. The program
|
|
72
|
+
* of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
|
|
73
|
+
* deprecated input `executable` wins over both, with a deprecation notice.
|
|
74
|
+
*/
|
|
75
|
+
export function createTailscaleProcedures(options = {}) {
|
|
76
|
+
const run = createProcedure()
|
|
77
|
+
.path(["tailscale", "run"])
|
|
78
|
+
.input(zodAdapter(RunInputSchema))
|
|
79
|
+
.output(zodAdapter(RunOutputSchema))
|
|
80
|
+
.meta({
|
|
81
|
+
description: "Run a tailscale command (status, ip, serve, up, down)",
|
|
82
|
+
args: ["path"],
|
|
83
|
+
shorts: { timeout: "t" },
|
|
84
|
+
output: "json",
|
|
85
|
+
// up, down and serve change the network of the host. ssh starts a program on another host.
|
|
86
|
+
effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
|
|
87
|
+
})
|
|
88
|
+
.handler(async (input, ctx) => {
|
|
89
|
+
const argv = buildArgv({
|
|
90
|
+
path: input.path,
|
|
91
|
+
flags: input.json ? ["--json"] : [],
|
|
92
|
+
args: input.args,
|
|
93
|
+
positional: input.positional,
|
|
94
|
+
});
|
|
95
|
+
// The deprecated input wins over the module, as before (O55: 0.30.0 removes it)
|
|
96
|
+
if (input.executable !== undefined)
|
|
97
|
+
deprecationNotice("PROCEDURES_TAILSCALE_EXECUTABLE_INPUT", EXECUTABLE_INPUT_NOTICE);
|
|
98
|
+
const result = await runCommand(tailscaleExecutable(input.executable ?? options.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
|
|
99
|
+
if (result.error)
|
|
100
|
+
throw new Error(`tailscale did not start: ${result.error}`);
|
|
101
|
+
const json = input.json ? parseJsonOutput(result.stdout) : undefined;
|
|
102
|
+
// tailscale prints an address to open when a login or a feature needs the owner
|
|
103
|
+
const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
|
|
104
|
+
return {
|
|
105
|
+
exitCode: result.exitCode,
|
|
106
|
+
success: result.exitCode === 0,
|
|
107
|
+
stdout: result.stdout,
|
|
108
|
+
stderr: result.stderr,
|
|
109
|
+
...(json !== undefined ? { json } : {}),
|
|
110
|
+
...(actionUrl !== undefined ? { actionUrl } : {}),
|
|
111
|
+
};
|
|
112
|
+
})
|
|
113
|
+
.build();
|
|
114
|
+
return [run];
|
|
115
|
+
}
|
|
116
|
+
export const tailscaleProcedures = createTailscaleProcedures();
|
|
117
|
+
export const tailscaleRunProcedure = tailscaleProcedures[0];
|
|
79
118
|
//# sourceMappingURL=procedures.js.map
|
package/dist/procedures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@procedures/tailscale",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.28.1",
|
|
5
5
|
"description": "The tailscale CLI as one procedure: status, ip, serve, up and down, with JSON output.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tailscale",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"provenance": true
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@procedures/client": "0.
|
|
59
|
+
"@procedures/client": "0.28.1",
|
|
60
60
|
"zod": "^4.6.5",
|
|
61
|
-
"@procedures/shell": "0.
|
|
61
|
+
"@procedures/shell": "0.28.1"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"typescript": "^7.0.2",
|
package/src/module.ts
CHANGED
|
@@ -3,12 +3,25 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { defineModule, registerModules, PROCEDURE_REGISTRY, type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
|
|
6
|
-
import { tailscaleProcedures } from "./procedures.js";
|
|
6
|
+
import { createTailscaleProcedures, tailscaleProcedures, type TailscaleProceduresOptions } from "./procedures.js";
|
|
7
7
|
|
|
8
8
|
export const tailscaleModule: ProcedureModule = defineModule("@procedures/tailscale", tailscaleProcedures);
|
|
9
9
|
|
|
10
10
|
export default tailscaleModule;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* This function gives the module with the settings of the host: the tailscale program. Without
|
|
14
|
+
* options, it gives `tailscaleModule`.
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function createTailscaleModule(options: TailscaleProceduresOptions = {}): ProcedureModule {
|
|
21
|
+
if (options.executable === undefined) return tailscaleModule;
|
|
22
|
+
return defineModule("@procedures/tailscale", createTailscaleProcedures(options));
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
/**
|
|
13
26
|
* This function registers the procedures of @procedures/tailscale in a registry. The default is the
|
|
14
27
|
* global registry.
|
package/src/procedures.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
|
|
3
3
|
* command (`status`, `ip`, `serve`, `up`, `down`).
|
|
4
|
+
*
|
|
5
|
+
* The program comes from the host (audit pass 2, O55): the `executable` option of
|
|
6
|
+
* `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
|
|
7
|
+
* The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
|
|
8
|
+
* notice. Version 0.30.0 removes it, because it lets the caller start any program.
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
11
|
import { existsSync } from "node:fs";
|
|
@@ -9,10 +14,25 @@ import { runCommand } from "@procedures/shell/command";
|
|
|
9
14
|
import { z } from "zod";
|
|
10
15
|
import { buildArgv, parseJsonOutput, type ArgValue } from "./argv.js";
|
|
11
16
|
|
|
17
|
+
/** The codes of the deprecation notices that this process emitted. */
|
|
18
|
+
const emitted = new Set<string>();
|
|
19
|
+
|
|
20
|
+
/** This function emits a deprecation notice one time in each process. */
|
|
21
|
+
function deprecationNotice(code: string, message: string): void {
|
|
22
|
+
if (emitted.has(code)) return;
|
|
23
|
+
emitted.add(code);
|
|
24
|
+
process.emitWarning(message, { type: "DeprecationWarning", code });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The notice of the deprecated input `executable` of `tailscale.run`. */
|
|
28
|
+
const EXECUTABLE_INPUT_NOTICE =
|
|
29
|
+
"The input executable of tailscale.run is deprecated. @procedures/tailscale 0.30.0 refuses it. " +
|
|
30
|
+
"Give the program to the host: createTailscaleModule({ executable }), or set TAILSCALE_EXE.";
|
|
31
|
+
|
|
12
32
|
/** The Windows installer does not put tailscale on the PATH. */
|
|
13
33
|
const WINDOWS_PATH = "C:\\Program Files\\Tailscale\\tailscale.exe";
|
|
14
34
|
|
|
15
|
-
/** This function gives the tailscale program: the
|
|
35
|
+
/** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
|
|
16
36
|
export function tailscaleExecutable(explicit?: string): string {
|
|
17
37
|
if (explicit !== undefined) return explicit;
|
|
18
38
|
const fromEnv = process.env["TAILSCALE_EXE"];
|
|
@@ -31,7 +51,17 @@ const RunInputSchema = z.object({
|
|
|
31
51
|
.optional()
|
|
32
52
|
.describe('The flags, for example { bg: true }'),
|
|
33
53
|
json: z.boolean().default(false).describe("Ask for JSON output (--json) and read it. Only some commands have it (status, serve status)."),
|
|
34
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The tailscale program.
|
|
56
|
+
*
|
|
57
|
+
* @deprecated Give `executable` to `createTailscaleModule()`, or set `TAILSCALE_EXE`. Version
|
|
58
|
+
* 0.30.0 refuses this input (audit pass 2, O55), because it lets the caller start any program.
|
|
59
|
+
*/
|
|
60
|
+
executable: z
|
|
61
|
+
.string()
|
|
62
|
+
.min(1)
|
|
63
|
+
.optional()
|
|
64
|
+
.describe("Deprecated: give executable to createTailscaleModule(), or set TAILSCALE_EXE. The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
|
|
35
65
|
timeout: z.number().int().positive().default(60_000).describe("The time limit, in milliseconds (default: 60000)"),
|
|
36
66
|
});
|
|
37
67
|
type RunInput = z.infer<typeof RunInputSchema>;
|
|
@@ -54,39 +84,57 @@ const RunOutputSchema = z.object({
|
|
|
54
84
|
actionUrl: z.string().optional(),
|
|
55
85
|
});
|
|
56
86
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
/** The settings of the host for the procedures of this package. The procedure input cannot change them. */
|
|
88
|
+
export interface TailscaleProceduresOptions {
|
|
89
|
+
/** The tailscale program. The default is `TAILSCALE_EXE`, then the Windows install folder, then `tailscale`. */
|
|
90
|
+
readonly executable?: string | undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* This function gives the procedures of this package with the settings of the host. The program
|
|
95
|
+
* of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
|
|
96
|
+
* deprecated input `executable` wins over both, with a deprecation notice.
|
|
97
|
+
*/
|
|
98
|
+
export function createTailscaleProcedures(options: TailscaleProceduresOptions = {}): AnyProcedure[] {
|
|
99
|
+
const run = createProcedure()
|
|
100
|
+
.path(["tailscale", "run"])
|
|
101
|
+
.input(zodAdapter<RunInput>(RunInputSchema))
|
|
102
|
+
.output(zodAdapter<RunOutput>(RunOutputSchema))
|
|
103
|
+
.meta({
|
|
104
|
+
description: "Run a tailscale command (status, ip, serve, up, down)",
|
|
105
|
+
args: ["path"],
|
|
106
|
+
shorts: { timeout: "t" },
|
|
107
|
+
output: "json",
|
|
108
|
+
// up, down and serve change the network of the host. ssh starts a program on another host.
|
|
109
|
+
effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
|
|
110
|
+
})
|
|
111
|
+
.handler(async (input: RunInput, ctx?: ProcedureContext): Promise<RunOutput> => {
|
|
112
|
+
const argv = buildArgv({
|
|
113
|
+
path: input.path,
|
|
114
|
+
flags: input.json ? ["--json"] : [],
|
|
115
|
+
args: input.args as Record<string, ArgValue> | undefined,
|
|
116
|
+
positional: input.positional,
|
|
117
|
+
});
|
|
118
|
+
// The deprecated input wins over the module, as before (O55: 0.30.0 removes it)
|
|
119
|
+
if (input.executable !== undefined) deprecationNotice("PROCEDURES_TAILSCALE_EXECUTABLE_INPUT", EXECUTABLE_INPUT_NOTICE);
|
|
120
|
+
const result = await runCommand(tailscaleExecutable(input.executable ?? options.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
|
|
121
|
+
if (result.error) throw new Error(`tailscale did not start: ${result.error}`);
|
|
122
|
+
const json = input.json ? parseJsonOutput(result.stdout) : undefined;
|
|
123
|
+
// tailscale prints an address to open when a login or a feature needs the owner
|
|
124
|
+
const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
|
|
125
|
+
return {
|
|
126
|
+
exitCode: result.exitCode,
|
|
127
|
+
success: result.exitCode === 0,
|
|
128
|
+
stdout: result.stdout,
|
|
129
|
+
stderr: result.stderr,
|
|
130
|
+
...(json !== undefined ? { json } : {}),
|
|
131
|
+
...(actionUrl !== undefined ? { actionUrl } : {}),
|
|
132
|
+
};
|
|
133
|
+
})
|
|
134
|
+
.build() as AnyProcedure;
|
|
135
|
+
return [run];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const tailscaleProcedures: AnyProcedure[] = createTailscaleProcedures();
|
|
91
139
|
|
|
92
|
-
export const
|
|
140
|
+
export const tailscaleRunProcedure: AnyProcedure = tailscaleProcedures[0]!;
|