Skip to content

Commit

Permalink
Run flatpak-spawn when pkexec is needed (#86)
Browse files Browse the repository at this point in the history
This PR checks the env vars to see if we're running inside of flatpak,
and if saw prepends the pkexec with flatpak-spawn in order rerun tsrelay
as sudo.

We also run `flatpak override` so the user doesn't have to. 

Fixes #76
  • Loading branch information
marwan-at-work committed Jun 28, 2023
1 parent cf36726 commit cf322bb
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 8 deletions.
16 changes: 11 additions & 5 deletions src/tailscale/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,17 @@ export class Tailscale {
Logger.info(`path: ${binPath}`, LOG_COMPONENT);
this.notifyExit = () => {
Logger.info('starting sudo tsrelay');
const childProcess = cp.spawn(`/usr/bin/pkexec`, [
'--disable-internal-agent',
binPath,
...args,
]);
let authCmd = `/usr/bin/pkexec`;
let authArgs = ['--disable-internal-agent', binPath, ...args];
if (
process.env['container'] === 'flatpak' &&
process.env['FLATPAK_ID'] &&
process.env['FLATPAK_ID'].startsWith('com.visualstudio.code')
) {
authCmd = 'flatpak-spawn';
authArgs = ['--host', 'pkexec', '--disable-internal-agent', binPath, ...args];
}
const childProcess = cp.spawn(authCmd, authArgs);
childProcess.on('exit', async (code) => {
Logger.warn(`sudo child process exited with code ${code}`, LOG_COMPONENT);
if (code === 0) {
Expand Down
5 changes: 5 additions & 0 deletions src/tailscale/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export function errorForType(type: string): TailscaleError {
},
],
};
case 'FLATPAK_REQUIRES_RESTART':
return {
title: 'Restart Flatpak Container',
message: 'Please quit VSCode and restart the container to finish setting up Tailscale',
};
default:
return {
title: 'Unknown error',
Expand Down
10 changes: 8 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ export interface WithErrors {
Errors?: RelayError[];
}

interface RelayError {
Type: 'FUNNEL_OFF' | 'HTTPS_OFF' | 'OFFLINE' | 'REQUIRES_SUDO' | 'NOT_RUNNING';
export interface RelayError {
Type:
| 'FUNNEL_OFF'
| 'HTTPS_OFF'
| 'OFFLINE'
| 'REQUIRES_SUDO'
| 'NOT_RUNNING'
| 'FLATPAK_REQUIRES_RESTART';
}

interface PeerStatus {
Expand Down
52 changes: 51 additions & 1 deletion tsrelay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"os/signal"
"strconv"
"strings"
Expand Down Expand Up @@ -56,8 +57,13 @@ const (
// NotRunning indicates tailscaled is
// not running
NotRunning = "NOT_RUNNING"
// FlatpakRequiresRestart indicates that the flatpak
// container needs to be fully restarted
FlatpakRequiresRestart = "FLATPAK_REQUIRES_RESTART"
)

var requiresRestart bool

func main() {
must(run())
}
Expand All @@ -78,12 +84,50 @@ func run() error {
Logger: log.New(logOut, "", 0),
}

flatpakID := os.Getenv("FLATPAK_ID")
isFlatpak := os.Getenv("container") == "flatpak" && strings.HasPrefix(flatpakID, "com.visualstudio.code")
if isFlatpak {
lggr.Println("running inside flatpak")
var err error
requiresRestart, err = ensureTailscaledAccessible(lggr, flatpakID)
if err != nil {
return err
}
lggr.Printf("requires restart: %v", requiresRestart)
}

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

return runHTTPServer(ctx, lggr, *port, *nonce)
}

func ensureTailscaledAccessible(lggr *logger, flatpakID string) (bool, error) {
_, err := os.Stat("/run/tailscale")
if err == nil {
lggr.Println("tailscaled is accessible")
return false, nil
}
if !errors.Is(err, os.ErrNotExist) {
return false, fmt.Errorf("error checking /run/tailscale: %w", err)
}
lggr.Println("running flatpak override")
cmd := exec.Command(
"flatpak-spawn",
"--host",
"flatpak",
"override",
"--user",
flatpakID,
"--filesystem=/run/tailscale",
)
output, err := cmd.Output()
if err != nil {
return false, fmt.Errorf("error running flatpak override: %s - %w", output, err)
}
return true, nil
}

type serverDetails struct {
Address string `json:"address,omitempty"`
Nonce string `json:"nonce,omitempty"`
Expand Down Expand Up @@ -252,6 +296,12 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
w.Write([]byte(`{}`))
case http.MethodGet:
if requiresRestart {
json.NewEncoder(w).Encode(RelayError{
Errors: []Error{{Type: FlatpakRequiresRestart}},
})
return
}
var wg sync.WaitGroup
wg.Add(1)
portMap := map[uint16]string{}
Expand Down Expand Up @@ -414,8 +464,8 @@ func (h *httpHandler) getConfigs(ctx context.Context) (*ipnstate.Status, *ipn.Se
var (
st *ipnstate.Status
sc *ipn.ServeConfig
g errgroup.Group
)
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
var err error
sc, err = h.lc.GetServeConfig(ctx)
Expand Down

0 comments on commit cf322bb

Please sign in to comment.