Skip to content

Commit

Permalink
shared/cliconfig: Add keepalive proxy support
Browse files Browse the repository at this point in the history
Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
  • Loading branch information
stgraber committed Dec 11, 2023
1 parent 0cbc9cd commit 45d82f9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
60 changes: 60 additions & 0 deletions shared/cliconfig/keepalive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//go:build !windows

package cliconfig

import (
"context"
"fmt"
"os"
"path/filepath"
"time"

"github.com/lxc/incus/client"
"github.com/lxc/incus/shared/subprocess"
"github.com/lxc/incus/shared/util"
)

func (c *Config) handleKeepAlive(remote Remote, name string, args *incus.ConnectionArgs) (incus.InstanceServer, error) {
// Create the socker directory if missing.
socketDir := filepath.Join(c.ConfigDir, "keepalive")
err := os.Mkdir(socketDir, 0700)
if err != nil && !os.IsExist(err) {
return nil, err
}

// Attempt to use the existing socket.
socketPath := filepath.Join(socketDir, fmt.Sprintf("%s.socket", name))
d, err := incus.ConnectIncusUnix(socketPath, args)
if err != nil {
// Delete any existing sockets.
_ = os.Remove(socketPath)

// Spawn the proxy.
proc, err := subprocess.NewProcess("incus", []string{"remote", "proxy", name, socketPath, fmt.Sprintf("--timeout=%d", remote.KeepAlive)}, "", "")
if err != nil {
return nil, err
}

err = proc.Start(context.Background())
if err != nil {
return nil, err
}

// Try up to 10 times over 5s.
for i := 0; i < 10; i++ {
if util.PathExists(socketPath) {
break
}

time.Sleep(500 * time.Millisecond)
}

// Connect to the proxy.
d, err = incus.ConnectIncusUnix(socketPath, args)
if err != nil {
return nil, err
}
}

return d, nil
}
13 changes: 13 additions & 0 deletions shared/cliconfig/keepalive_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//go:build windows

package cliconfig

import (
"fmt"

"github.com/lxc/incus/client"
)

func (c *Config) handleKeepAlive(remote Remote, name string, args *incus.ConnectionArgs) (incus.InstanceServer, error) {
return nil, fmt.Errorf("Keepalive isn't supported on Windows")
}
18 changes: 15 additions & 3 deletions shared/cliconfig/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,21 @@ func (c *Config) GetInstanceServer(name string) (incus.InstanceServer, error) {
return nil, fmt.Errorf("Missing TLS client certificate and key")
}

d, err := incus.ConnectIncus(remote.Addr, args)
if err != nil {
return nil, err
var d incus.InstanceServer
if remote.KeepAlive > 0 {
d, err = c.handleKeepAlive(remote, name, args)
if err != nil {
// On proxy failure, just fallback to regular client.
d, err = incus.ConnectIncus(remote.Addr, args)
if err != nil {
return nil, err
}
}
} else {
d, err = incus.ConnectIncus(remote.Addr, args)
if err != nil {
return nil, err
}
}

if remote.Project != "" && remote.Project != "default" {
Expand Down

0 comments on commit 45d82f9

Please sign in to comment.