From 0089ceaf1dc781fb07939ca4dc3cd28efc333b31 Mon Sep 17 00:00:00 2001 From: Philip Henning Date: Thu, 7 Nov 2024 15:56:18 +0100 Subject: [PATCH] Feature tvos documentation (#2226) * Add usage documentation for tvOS * lint and format * Change admonition to mkdocs flavoured style * fix typos * Update hscontrol/templates/apple.go Co-authored-by: Kristoffer Dalby * change outer quoting for where quoting in-text is used --------- Co-authored-by: Kristoffer Dalby --- docs/about/clients.md | 1 + docs/usage/connect/apple.md | 20 ++++ hscontrol/templates/apple.go | 183 ++++++++++++++++++++++++++++------- 3 files changed, 169 insertions(+), 35 deletions(-) diff --git a/docs/about/clients.md b/docs/about/clients.md index eafb2946..cb8e4b6d 100644 --- a/docs/about/clients.md +++ b/docs/about/clients.md @@ -13,3 +13,4 @@ headscale. | Android | Yes (see [docs](../usage/connect/android.md)) | | macOS | Yes (see [docs](../usage/connect/apple.md#macos) and `/apple` on your headscale for more information) | | iOS | Yes (see [docs](../usage/connect/apple.md#ios) and `/apple` on your headscale for more information) | +| tvOS | Yes (see [docs](../usage/connect/apple.md#tvos) and `/apple` on your headscale for more information) | diff --git a/docs/usage/connect/apple.md b/docs/usage/connect/apple.md index 7597c717..5ebecb15 100644 --- a/docs/usage/connect/apple.md +++ b/docs/usage/connect/apple.md @@ -47,3 +47,23 @@ tailscale login --login-server - Under `Custom Login Server`, select `Add Account...` - Enter the URL of your headscale instance (e.g `https://headscale.example.com`) and press `Add Account` - Follow the login procedure in the browser + +## tvOS + +### Installation + +Install the official Tailscale tvOS client from the [App Store](https://apps.apple.com/app/tailscale/id1470499037). + +!!! danger + + **Don't** open the Tailscale App after installation! + +### Configuring the headscale URL + +- Go Settings (the apple tvOS settings) > Apps > Tailscale +- Under `ALTERNATE COORDINATION SERVER URL`, select `URL` +- Enter the URL of your headscale instance (e.g `https://headscale.example.com`) and press `OK` +- Return to the tvOS Home screen +- Open Tailscale +- Click the button `Install VPN configuration` and confirm the appearing popup by clicking the `Allow` button +- Scan the QR code and follow the login procedure diff --git a/hscontrol/templates/apple.go b/hscontrol/templates/apple.go index 93f0034d..8b289d22 100644 --- a/hscontrol/templates/apple.go +++ b/hscontrol/templates/apple.go @@ -17,9 +17,13 @@ func Apple(url string) *elem.Element { headerOne("headscale: iOS configuration"), headerTwo("GUI"), elem.Ol(nil, - elem.Li(nil, + elem.Li( + nil, elem.Text("Install the official Tailscale iOS client from the "), - elem.A(attrs.Props{attrs.Href: "https://apps.apple.com/app/tailscale/id1470499037"}, + elem.A( + attrs.Props{ + attrs.Href: "https://apps.apple.com/app/tailscale/id1470499037", + }, elem.Text("App store"), ), ), @@ -31,27 +35,47 @@ func Apple(url string) *elem.Element { elem.Li(nil, elem.Text("Open Settings on the iOS device"), ), - elem.Li(nil, - elem.Text(`Scroll down to the "third party apps" section, under "Game Center" or "TV Provider"`), + elem.Li( + nil, + elem.Text( + `Scroll down to the "third party apps" section, under "Game Center" or "TV Provider"`, + ), ), elem.Li(nil, elem.Text("Find Tailscale and select it"), elem.Ul(nil, - elem.Li(nil, - elem.Text(`If the iOS device was previously logged into Tailscale, switch the "Reset Keychain" toggle to "on"`), + elem.Li( + nil, + elem.Text( + `If the iOS device was previously logged into Tailscale, switch the "Reset Keychain" toggle to "on"`, + ), ), ), ), - elem.Li(nil, - elem.Text(fmt.Sprintf(`Enter "%s" under "Alternate Coordination Server URL"`,url)), + elem.Li( + nil, + elem.Text( + fmt.Sprintf( + `Enter "%s" under "Alternate Coordination Server URL"`, + url, + ), + ), ), - elem.Li(nil, - elem.Text("Restart the app by closing it from the iOS app switcher, open the app and select the regular sign in option "), + elem.Li( + nil, + elem.Text( + "Restart the app by closing it from the iOS app switcher, open the app and select the regular sign in option ", + ), elem.I(nil, elem.Text("(non-SSO)")), - elem.Text(". It should open up to the headscale authentication page."), + elem.Text( + ". It should open up to the headscale authentication page.", + ), ), - elem.Li(nil, - elem.Text("Enter your credentials and log in. Headscale should now be working on your iOS device"), + elem.Li( + nil, + elem.Text( + "Enter your credentials and log in. Headscale should now be working on your iOS device", + ), ), ), headerOne("headscale: macOS configuration"), @@ -61,39 +85,63 @@ func Apple(url string) *elem.Element { ), elem.Pre(nil, elem.Code(nil, - elem.Text(fmt.Sprintf("tailscale login --login-server %s",url)), + elem.Text(fmt.Sprintf("tailscale login --login-server %s", url)), ), ), headerTwo("GUI"), elem.Ol(nil, - elem.Li(nil, - elem.Text("ALT + Click the Tailscale icon in the menu and hover over the Debug menu"), + elem.Li( + nil, + elem.Text( + "ALT + Click the Tailscale icon in the menu and hover over the Debug menu", + ), ), elem.Li(nil, elem.Text(`Under "Custom Login Server", select "Add Account..."`), ), - elem.Li(nil, - elem.Text(fmt.Sprintf(`Enter "%s" of the headscale instance and press "Add Account"`,url)), + elem.Li( + nil, + elem.Text( + fmt.Sprintf( + `Enter "%s" of the headscale instance and press "Add Account"`, + url, + ), + ), ), elem.Li(nil, elem.Text(`Follow the login procedure in the browser`), ), ), headerTwo("Profiles"), - elem.P(nil, - elem.Text("Headscale can be set to the default server by installing a Headscale configuration profile:"), + elem.P( + nil, + elem.Text( + "Headscale can be set to the default server by installing a Headscale configuration profile:", + ), ), - elem.P(nil, - elem.A(attrs.Props{attrs.Href: "/apple/macos-app-store", attrs.Download: "headscale_macos.mobileconfig"}, + elem.P( + nil, + elem.A( + attrs.Props{ + attrs.Href: "/apple/macos-app-store", + attrs.Download: "headscale_macos.mobileconfig", + }, elem.Text("macOS AppStore profile "), ), - elem.A(attrs.Props{attrs.Href: "/apple/macos-standalone", attrs.Download: "headscale_macos.mobileconfig"}, + elem.A( + attrs.Props{ + attrs.Href: "/apple/macos-standalone", + attrs.Download: "headscale_macos.mobileconfig", + }, elem.Text("macOS Standalone profile"), ), ), elem.Ol(nil, - elem.Li(nil, - elem.Text("Download the profile, then open it. When it has been opened, there should be a notification that a profile can be installed"), + elem.Li( + nil, + elem.Text( + "Download the profile, then open it. When it has been opened, there should be a notification that a profile can be installed", + ), ), elem.Li(nil, elem.Text(`Open System Preferences and go to "Profiles"`), @@ -106,20 +154,35 @@ func Apple(url string) *elem.Element { ), ), elem.P(nil, elem.Text("Or")), - elem.P(nil, - elem.Text("Use your terminal to configure the default setting for Tailscale by issuing:"), + elem.P( + nil, + elem.Text( + "Use your terminal to configure the default setting for Tailscale by issuing:", + ), ), elem.Ul(nil, elem.Li(nil, elem.Text(`for app store client:`), - elem.Code(nil, - elem.Text(fmt.Sprintf(`defaults write io.tailscale.ipn.macos ControlURL %s`,url)), + elem.Code( + nil, + elem.Text( + fmt.Sprintf( + `defaults write io.tailscale.ipn.macos ControlURL %s`, + url, + ), + ), ), ), elem.Li(nil, elem.Text(`for standalone client:`), - elem.Code(nil, - elem.Text(fmt.Sprintf(`defaults write io.tailscale.ipn.macsys ControlURL %s`,url)), + elem.Code( + nil, + elem.Text( + fmt.Sprintf( + `defaults write io.tailscale.ipn.macsys ControlURL %s`, + url, + ), + ), ), ), ), @@ -127,23 +190,73 @@ func Apple(url string) *elem.Element { elem.Text("Restart Tailscale.app and log in."), ), headerThree("Caution"), - elem.P(nil, - elem.Text("You should always download and inspect the profile before installing it:"), + elem.P( + nil, + elem.Text( + "You should always download and inspect the profile before installing it:", + ), ), elem.Ul(nil, elem.Li(nil, elem.Text(`for app store client: `), elem.Code(nil, - elem.Text(fmt.Sprintf(`curl %s/apple/macos-app-store`,url)), + elem.Text(fmt.Sprintf(`curl %s/apple/macos-app-store`, url)), ), ), elem.Li(nil, elem.Text(`for standalone client: `), elem.Code(nil, - elem.Text(fmt.Sprintf(`curl %s/apple/macos-standalone`,url)), + elem.Text(fmt.Sprintf(`curl %s/apple/macos-standalone`, url)), ), ), ), + headerOne("headscale: tvOS configuration"), + headerTwo("GUI"), + elem.Ol(nil, + elem.Li( + nil, + elem.Text("Install the official Tailscale tvOS client from the "), + elem.A( + attrs.Props{ + attrs.Href: "https://apps.apple.com/app/tailscale/id1470499037", + }, + elem.Text("App store"), + ), + ), + elem.Li( + nil, + elem.Text( + "Open Settings (the Apple tvOS settings) > Apps > Tailscale", + ), + ), + elem.Li( + nil, + elem.Text( + fmt.Sprintf( + `Enter "%s" under "ALTERNATE COORDINATION SERVER URL"`, + url, + ), + ), + ), + elem.Li(nil, + elem.Text("Return to the tvOS Home screen"), + ), + elem.Li(nil, + elem.Text("Open Tailscale"), + ), + elem.Li(nil, + elem.Text(`Select "Install VPN configuration"`), + ), + elem.Li(nil, + elem.Text(`Select "Allow"`), + ), + elem.Li(nil, + elem.Text("Scan the QR code and follow the login procedure"), + ), + elem.Li(nil, + elem.Text("Headscale should now be working on your tvOS device"), + ), + ), ), ) }