diff --git a/roles/github_runner_macos_host/README.md b/roles/github_runner_macos_host/README.md index add92179..314013ca 100644 --- a/roles/github_runner_macos_host/README.md +++ b/roles/github_runner_macos_host/README.md @@ -33,7 +33,7 @@ A MacBook with its lid closed still sleeps with `sleep 0`, because that setting ## Tailscale -The role installs the Homebrew formula `tailscale` and runs `tailscaled install-system-daemon`, which copies `tailscaled` to `/usr/local/bin`, writes the launchd daemon `/Library/LaunchDaemons/com.tailscale.tailscaled.plist` and starts it, so the daemon runs from boot, before anyone logs in. A host that already has that file is not installed on again, whether this role or a person installed it, and neither is a host that has Tailscale's standalone app (`/Applications/Tailscale.app`), which is its own Tailscale client in a system network extension and would conflict with a second daemon; and a daemon without the Homebrew formula behind it (one built by hand) is never replaced; what the role does for a host that has the formula is in Keeping Tailscale current below. +The role installs the Homebrew formula `tailscale` and runs `tailscaled install-system-daemon`, which copies `tailscaled` to `/usr/local/bin`, writes the launchd daemon `/Library/LaunchDaemons/com.tailscale.tailscaled.plist` and starts it, so the daemon runs from boot, before anyone logs in. The standalone Tailscale app and this daemon are meant to run side by side on a Mac (the app's network extension and the daemon are both connected on the fleet's Macs), so the app being installed never skips the daemon. A host that already has that file is not installed on again, whether this role or a person installed it, and a daemon without the Homebrew formula behind it (one built by hand) is never replaced; what the role does for a host that has the formula is in Keeping Tailscale current below. The role never joins or re-authenticates a tailnet on its own, because joining needs an auth key, a secret only the tailnet's owner can create. With `github_runner_macos_host_tailscale_auth_key` set, the role reads the daemon's login state and, for a daemon that needs a login, runs `tailscale up` with the key on standard input (so it is in no process listing and, with `no_log`, in no output), plus `github_runner_macos_host_tailscale_up_args`. A daemon that is already logged in is not touched, and a join that failed is retried by the next run. It applies only to a host whose Homebrew formula the role installed (the formula's `tailscale` is in the Homebrew prefix), so a hand-built daemon is never joined or logged in again. @@ -57,7 +57,6 @@ Replacing the daemon restarts it, so connections over the host's tailnet, an SSH - `github_runner_macos_host_tailscale_auth_key` (default empty), `github_runner_macos_host_tailscale_up_args` (default empty list): see Tailscale above. - `github_runner_macos_host_tailscale_plist`: the launchd definition `tailscaled install-system-daemon` writes. Not a setting; a variable only so the tests can point it at a stand-in. - `github_runner_macos_host_tailscale_update` (default true): keep the formula, its daemon and the standalone app current, as under Keeping Tailscale current above. Part of the Tailscale part, so `github_runner_macos_host_tailscale` false skips it too. -- `github_runner_macos_host_tailscale_app_bundle`: where Tailscale's standalone app lives. A host that has it gets no daemon installed beside it. Not a setting; a variable only so the tests can point it at a stand-in. - `github_runner_macos_host_tailscale_daemon_binary`, `github_runner_macos_host_tailscale_app_cask`: where `tailscaled install-system-daemon` puts the daemon the launchd definition starts, and the Homebrew cask of the standalone app. Not settings; variables only so the tests can point them at stand-ins. - `github_runner_macos_host_path`: the `PATH` the Homebrew tasks run with, both Homebrew prefixes and the system directories. diff --git a/roles/github_runner_macos_host/defaults/main.yml b/roles/github_runner_macos_host/defaults/main.yml index 983b8572..afebf696 100644 --- a/roles/github_runner_macos_host/defaults/main.yml +++ b/roles/github_runner_macos_host/defaults/main.yml @@ -39,8 +39,6 @@ github_runner_macos_host_tailscale_update: true # Not settings: where tailscaled install-system-daemon puts the daemon that the launchd definition starts, and the Homebrew cask of Tailscale's standalone app. Variables only so the tests can point them at stand-ins. github_runner_macos_host_tailscale_daemon_binary: /usr/local/bin/tailscaled github_runner_macos_host_tailscale_app_cask: tailscale-app -# Where the standalone Tailscale app lives. A host that has it is its own Tailscale client (a system network extension), so the role installs no daemon beside it. Not a setting: a variable only so the tests can point it at a stand-in. -github_runner_macos_host_tailscale_app_bundle: /Applications/Tailscale.app # A Tailscale auth key (a secret only the tailnet's owner can create, from any source Ansible reads), empty by default. Set, the role runs tailscale up with it on a host whose daemon the role manages (the Homebrew formula's tailscale is installed) and whose tailnet login is still needed; empty, the role never joins or re-authenticates a tailnet. github_runner_macos_host_tailscale_auth_key: "" # Further arguments for tailscale up, such as --hostname=example or --advertise-tags=tag:example. Used only when the auth key is set. diff --git a/roles/github_runner_macos_host/meta/argument_specs.yml b/roles/github_runner_macos_host/meta/argument_specs.yml index 9bb941f8..78be1ff5 100644 --- a/roles/github_runner_macos_host/meta/argument_specs.yml +++ b/roles/github_runner_macos_host/meta/argument_specs.yml @@ -82,10 +82,6 @@ argument_specs: type: str default: tailscale-app description: "The Homebrew cask of Tailscale's standalone app, kept current only when it is installed. Not a setting, and a variable only so the tests can point it at a stand-in." - github_runner_macos_host_tailscale_app_bundle: - type: path - default: /Applications/Tailscale.app - description: "Where Tailscale's standalone app lives. A host that has it is its own Tailscale client, so the role installs no daemon beside it. Not a setting, and a variable only so the tests can point it at a stand-in." github_runner_macos_host_tailscale_auth_key: type: str default: "" diff --git a/roles/github_runner_macos_host/tasks/tailscale.yml b/roles/github_runner_macos_host/tasks/tailscale.yml index 4196ab8a..00b63a0a 100644 --- a/roles/github_runner_macos_host/tasks/tailscale.yml +++ b/roles/github_runner_macos_host/tasks/tailscale.yml @@ -13,18 +13,9 @@ path: "{{ github_runner_macos_host_tailscale_plist }}" register: github_runner_macos_host_tailscale_daemon -- name: Look for the standalone Tailscale app - # The app carries its own client in a system network extension, which the formula's daemon would conflict with (both want the host's one tailnet connection), so a host that has the app is its own Tailscale client already. - ansible.builtin.stat: - path: "{{ github_runner_macos_host_tailscale_app_bundle }}" - get_checksum: false - register: github_runner_macos_host_tailscale_app_bundle_stat - -# A host that already has the definition, installed by this role earlier or by hand, or the standalone app, is left alone: nothing below runs, so a hand-built daemon is never replaced by the formula's and the app is never given a second client. +# A host that already has the definition, installed by this role earlier or by hand, is left alone: nothing below runs, so a hand-built daemon is never replaced by the formula's. - name: Install the daemon - when: - - not github_runner_macos_host_tailscale_daemon.stat.exists - - not github_runner_macos_host_tailscale_app_bundle_stat.stat.exists + when: not github_runner_macos_host_tailscale_daemon.stat.exists block: - name: Install the Tailscale Homebrew formula community.general.homebrew: diff --git a/tests/unit/test_macos_host.py b/tests/unit/test_macos_host.py index 8211f3b4..7f65a274 100644 --- a/tests/unit/test_macos_host.py +++ b/tests/unit/test_macos_host.py @@ -436,8 +436,6 @@ def setUp(self) -> None: self.plist = self.stub / "LaunchDaemons" / PLIST_NAME # Where tailscaled install-system-daemon puts the daemon it installs. self.daemon_binary = self.stub / "usr-local-bin" / "tailscaled" - # Where the standalone app would be; absent unless a test creates it. - self.app_bundle = self.stub / "Applications" / "Tailscale.app" self.set_power(sleepdisabled="0", sleep="1", displaysleep="10", disksleep="10") def set_power(self, sleepdisabled: str | None = "1", **overrides: str) -> None: @@ -495,7 +493,6 @@ def run_role(self, *extra: str, system: str = "Darwin", machine: str = "arm64", "github_runner_macos_host_homebrew_prefix": str(self.prefix), "github_runner_macos_host_tailscale_plist": str(self.plist), "github_runner_macos_host_tailscale_daemon_binary": str(self.daemon_binary), - "github_runner_macos_host_tailscale_app_bundle": str(self.app_bundle), # The install and join tests are about those, and a stand-in formula that is installed would otherwise be upgraded on their second runs: the update has tests of its own, which turn it on. "github_runner_macos_host_tailscale_update": False, **variables, @@ -741,15 +738,6 @@ def test_a_host_that_already_has_the_daemon_is_left_entirely_alone(self) -> None self.assertEqual(self.calls(), READS) self.assertEqual(self.recap(result)["changed"], 0) - def test_a_host_running_the_standalone_app_gets_no_daemon_beside_it(self) -> None: - self.set_power() - self.app_bundle.mkdir(parents=True) - result = self.run_role() - self.ok(result) - self.assertEqual(self.calls(), READS) - self.assertFalse(self.plist.exists()) - self.assertEqual(self.recap(result)["changed"], 0) - def test_a_hand_built_daemon_stays_alone_even_with_an_auth_key_and_no_formula(self) -> None: self.set_power() self.hand_built_daemon()