Skip to content

Commit d2fdb33

Browse files
committed
default to running all commands except tailscale up silently
To avoid leaking any potentially sensitive information, all commands are now run without logging to the console. Logging can be enabled by turning on debug logging as described at https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging. Updates tailscale/corp#33405 Signed-off-by: Percy Wegmann <percy@tailscale.com>
1 parent ac425ca commit d2fdb33

File tree

2 files changed

+249
-94
lines changed

2 files changed

+249
-94
lines changed

dist/index.js

Lines changed: 111 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -41129,26 +41129,17 @@ const cmdTailscale = "tailscale";
4112941129
const cmdTailscaleFullPath = "/usr/local/bin/tailscale";
4113041130
const cmdTailscaled = "tailscaled";
4113141131
const cmdTailscaledFullPath = "/usr/local/bin/tailscaled";
41132-
const platformWin32 = "win32";
41133-
const platformDarwin = "darwin";
4113441132
const runnerLinux = "Linux";
4113541133
const runnerWindows = "Windows";
4113641134
const runnerMacOS = "macOS";
4113741135
const versionLatest = "latest";
4113841136
const versionUnstable = "unstable";
4113941137
// Cross-platform Tailscale local API status check
4114041138
async function getTailscaleStatus() {
41141-
const { exitCode, stdout, stderr } = await exec.getExecOutput(cmdTailscale, ["status", "--json"], {
41142-
silent: true,
41143-
ignoreReturnCode: true,
41144-
});
41145-
if (exitCode !== 0) {
41146-
process.stderr.write(stderr);
41147-
throw new Error(`tailscale status failed with exit code ${exitCode}`);
41148-
}
41149-
if (core.isDebug()) {
41150-
process.stdout.write(stdout);
41151-
}
41139+
const { stdout } = await execSilent("get tailscale status", cmdTailscale, [
41140+
"status",
41141+
"--json",
41142+
]);
4115241143
return JSON.parse(stdout);
4115341144
}
4115441145
async function run() {
@@ -41236,15 +41227,23 @@ async function pingHost(host) {
4123641227
core.debug(`Waiting ${waitTime} milliseconds before pinging`);
4123741228
await (0, promises_1.setTimeout)(waitTime);
4123841229
}
41239-
let result = await exec.getExecOutput(cmdTailscale, ["ping", "-c", "1", host], { ignoreReturnCode: true });
41240-
if (result.exitCode === 0) {
41230+
try {
41231+
let result = await execSilent("ping host", cmdTailscale, [
41232+
"ping",
41233+
"-c",
41234+
"1",
41235+
host,
41236+
]);
4124141237
core.info(`✅ Ping host ${host} reachable via direct connection!`);
4124241238
return;
4124341239
}
41244-
else if (result.stderr.includes("direct connection not established")) {
41245-
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
41246-
core.info(`✅ Ping host ${host} reachable via DERP!`);
41247-
return;
41240+
catch (err) {
41241+
if (err instanceof execError &&
41242+
err.stderr.includes("direct connection not established")) {
41243+
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
41244+
core.info(`✅ Ping host ${host} reachable via DERP!`);
41245+
return;
41246+
}
4124841247
}
4124941248
i++;
4125041249
}
@@ -41284,7 +41283,8 @@ async function resolveVersion(version, runnerOS) {
4128441283
}
4128541284
if (version === versionLatest || version === versionUnstable) {
4128641285
let path = version === versionUnstable ? versionUnstable : "stable";
41287-
const { stdout } = await exec.getExecOutput("curl", [
41286+
let pkg = `https://pkgs.tailscale.com/${path}/?mode=json`;
41287+
const { stdout } = await execSilent(`curl ${pkg}`, "curl", [
4128841288
"-H",
4128941289
"user-agent:action-setup-tailscale",
4129041290
"-s",
@@ -41389,7 +41389,7 @@ async function installTailscaleLinux(config, toolPath) {
4138941389
// Get SHA256 if not provided
4139041390
if (!config.sha256Sum) {
4139141391
const shaUrl = `${baseUrl}/tailscale_${config.resolvedVersion}_${config.arch}.tgz.sha256`;
41392-
const { stdout } = await exec.getExecOutput("curl", [
41392+
const { stdout } = await execSilent(`curl ${shaUrl}`, "curl", [
4139341393
"-H",
4139441394
"user-agent:action-setup-tailscale",
4139541395
"-L",
@@ -41418,15 +41418,23 @@ async function installTailscaleLinux(config, toolPath) {
4141841418
fs.copyFileSync(path.join(extractedDir, cmdTailscale), path.join(toolPath, cmdTailscale));
4141941419
fs.copyFileSync(path.join(extractedDir, cmdTailscaled), path.join(toolPath, cmdTailscaled));
4142041420
// Install binaries to /usr/local/bin
41421-
await exec.exec("sudo", [
41421+
await execSilent("copy tailscale binaries to /usr/local/bin", "sudo", [
4142241422
"cp",
4142341423
path.join(toolPath, cmdTailscale),
4142441424
path.join(toolPath, cmdTailscaled),
4142541425
"/usr/local/bin",
4142641426
]);
4142741427
// Make sure they're executable
41428-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41429-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41428+
await execSilent("chmod tailscale binary", "sudo", [
41429+
"chmod",
41430+
"+x",
41431+
cmdTailscaleFullPath,
41432+
]);
41433+
await execSilent("chmod tailscaled binary", "sudo", [
41434+
"chmod",
41435+
"+x",
41436+
cmdTailscaledFullPath,
41437+
]);
4143041438
}
4143141439
async function installTailscaleWindows(config, toolPath, fromCache = false) {
4143241440
// Create tool directory
@@ -41450,7 +41458,7 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4145041458
// Get SHA256 if not provided
4145141459
if (!config.sha256Sum) {
4145241460
const shaUrl = `${baseUrl}/tailscale-setup-${config.resolvedVersion}-${config.arch}.msi.sha256`;
41453-
const { stdout } = await exec.getExecOutput("curl", [
41461+
const { stdout } = await execSilent(`curl ${shaUrl}`, "curl", [
4145441462
"-H",
4145541463
"user-agent:action-setup-tailscale",
4145641464
"-L",
@@ -41478,7 +41486,7 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4147841486
}
4147941487
}
4148041488
// Install MSI (same for both fresh and cached)
41481-
await exec.exec("msiexec.exe", [
41489+
await execSilent("install msi", "msiexec.exe", [
4148241490
"/quiet",
4148341491
`/l*v`,
4148441492
path.join(process.env.RUNNER_TEMP || "", "tailscale.log"),
@@ -41491,16 +41499,16 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4149141499
async function installTailscaleMacOS(config, toolPath) {
4149241500
core.info("Building tailscale from src on macOS...");
4149341501
// Clone the repo
41494-
await exec.exec("git clone https://github.com/tailscale/tailscale.git tailscale");
41502+
await execSilent("glone tailscale repo", "git clone https://github.com/tailscale/tailscale.git tailscale");
4149541503
// Checkout the resolved version
41496-
await exec.exec(`git checkout v${config.resolvedVersion}`, [], {
41504+
await execSilent("checkout resolved version", `git checkout v${config.resolvedVersion}`, [], {
4149741505
cwd: cmdTailscale,
4149841506
});
4149941507
// Create tool directory and copy binaries there for caching
4150041508
fs.mkdirSync(toolPath, { recursive: true });
4150141509
// Build tailscale and tailscaled into tool directory
4150241510
for (const binary of [cmdTailscale, cmdTailscaled]) {
41503-
await exec.exec(`./build_dist.sh -o ${path.join(toolPath, binary)} ./cmd/${binary}`, [], {
41511+
await execSilent(`build ${binary}`, `./build_dist.sh -o ${path.join(toolPath, binary)} ./cmd/${binary}`, [], {
4150441512
cwd: cmdTailscale,
4150541513
env: {
4150641514
...process.env,
@@ -41509,15 +41517,23 @@ async function installTailscaleMacOS(config, toolPath) {
4150941517
});
4151041518
}
4151141519
// Install binaries to /usr/local/bin
41512-
await exec.exec("sudo", [
41520+
await execSilent("copy binaries to /usr/local/bin", "sudo", [
4151341521
"cp",
4151441522
path.join(toolPath, cmdTailscale),
4151541523
path.join(toolPath, cmdTailscaled),
4151641524
"/usr/local/bin",
4151741525
]);
4151841526
// Make sure they're executable
41519-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41520-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41527+
await execSilent("chmod tailscale", "sudo", [
41528+
"chmod",
41529+
"+x",
41530+
cmdTailscaleFullPath,
41531+
]);
41532+
await execSilent("chmod tailscaled", "sudo", [
41533+
"chmod",
41534+
"+x",
41535+
cmdTailscaledFullPath,
41536+
]);
4152141537
core.info("✅ Tailscale installed successfully on macOS from source");
4152241538
}
4152341539
async function startTailscaleDaemon(config) {
@@ -41588,7 +41604,7 @@ async function connectToTailscale(config, runnerOS) {
4158841604
hostname = `github-${process.env.COMPUTERNAME}`;
4158941605
}
4159041606
else {
41591-
const { stdout } = await exec.getExecOutput("hostname");
41607+
const { stdout } = await execSilent("hostname", "hostname");
4159241608
hostname = `github-${stdout.trim()}`;
4159341609
}
4159441610
}
@@ -41631,9 +41647,8 @@ async function connectToTailscale(config, runnerOS) {
4163141647
execArgs = ["sudo", "-E", cmdTailscale, ...upArgs];
4163241648
}
4163341649
const timeoutMs = parseTimeout(config.timeout);
41634-
core.info(`Running: ${execArgs.join(" ")} (timeout: ${timeoutMs}ms)`);
4163541650
await Promise.race([
41636-
exec.exec(execArgs[0], execArgs.slice(1)),
41651+
execSilent("tailscale up", execArgs[0], execArgs.slice(1)),
4163741652
new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), timeoutMs)),
4163841653
]);
4163941654
// Success
@@ -41690,10 +41705,26 @@ async function installCachedBinaries(toolPath, runnerOS) {
4169041705
const tailscaleBin = path.join(toolPath, cmdTailscale);
4169141706
const tailscaledBin = path.join(toolPath, cmdTailscaled);
4169241707
if (fs.existsSync(tailscaleBin) && fs.existsSync(tailscaledBin)) {
41693-
await exec.exec("sudo", ["cp", tailscaleBin, cmdTailscaleFullPath]);
41694-
await exec.exec("sudo", ["cp", tailscaledBin, cmdTailscaledFullPath]);
41695-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41696-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41708+
await execSilent("copy tailscale from cache", "sudo", [
41709+
"cp",
41710+
tailscaleBin,
41711+
cmdTailscaleFullPath,
41712+
]);
41713+
await execSilent("copy tailscaled from cache", "sudo", [
41714+
"cp",
41715+
tailscaledBin,
41716+
cmdTailscaledFullPath,
41717+
]);
41718+
await execSilent("chmod tailscale", "sudo", [
41719+
"chmod",
41720+
"+x",
41721+
cmdTailscaleFullPath,
41722+
]);
41723+
await execSilent("chmod tailscaled", "sudo", [
41724+
"chmod",
41725+
"+x",
41726+
cmdTailscaledFullPath,
41727+
]);
4169741728
}
4169841729
else {
4169941730
throw new Error(`Cached binaries not found in ${toolPath}`);
@@ -41707,12 +41738,12 @@ async function configureDNSOnMacOS(status) {
4170741738
}
4170841739
core.info(`Setting system DNS server to 100.100.100.100 and searchdomains to ${status.CurrentTailnet.MagicDNSSuffix}`);
4170941740
try {
41710-
await exec.exec("networksetup", [
41741+
await execSilent("set dns servers", "networksetup", [
4171141742
"-setdnsservers",
4171241743
"Ethernet",
4171341744
"100.100.100.100",
4171441745
]);
41715-
await exec.exec("networksetup", [
41746+
await execSilent("set search domains", "networksetup", [
4171641747
"-setsearchdomains",
4171741748
"Ethernet",
4171841749
status.CurrentTailnet.MagicDNSSuffix,
@@ -41723,6 +41754,45 @@ async function configureDNSOnMacOS(status) {
4172341754
}
4172441755
}
4172541756
run();
41757+
/**
41758+
* Executes the given command, logging the given label as info, but suppressing
41759+
* all other output including the command line itself (unless debug logging is enabled,
41760+
* see https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging).
41761+
*
41762+
* If the command fails, stderr is written to the console.
41763+
*
41764+
* @param label a label to use for info logging what's happening
41765+
* @param cmd the command to run
41766+
* @param args arguments to the command
41767+
* @returns stdout (if command was successful)
41768+
* @throws execError if exec returned a non-zero status code
41769+
*/
41770+
async function execSilent(label, cmd, args, opts) {
41771+
core.info(`▶️ ${label}`);
41772+
const out = await exec.getExecOutput(cmd, args, {
41773+
...opts,
41774+
silent: !core.isDebug(),
41775+
ignoreReturnCode: true,
41776+
});
41777+
if (out.exitCode !== 0) {
41778+
if (!core.isDebug) {
41779+
// When debug logging is off, stderr won't have been written to console, write it now.
41780+
process.stderr.write(out.stderr);
41781+
}
41782+
throw new execError(`${cmd} failed with exit code ${out.exitCode}`, out.exitCode, out.stderr);
41783+
}
41784+
return out;
41785+
}
41786+
class execError {
41787+
constructor(msg, exitCode, stderr) {
41788+
this.msg = msg;
41789+
this.exitCode = exitCode;
41790+
this.stderr = stderr;
41791+
}
41792+
toString() {
41793+
return this.msg;
41794+
}
41795+
}
4172641796

4172741797

4172841798
/***/ }),

0 commit comments

Comments
 (0)