[lxc-devel] [lxd/master] Console on Windows
stgraber on Github
lxc-bot at linuxcontainers.org
Thu Aug 20 18:35:11 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200820/4c663286/attachment.bin>
-------------- next part --------------
From f73f82bc3ce2d25c0bce1b3a657d8255ecff01ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 20 Aug 2020 12:13:43 -0400
Subject: [PATCH 1/2] shared/cert: Fix on Windows
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
shared/cert.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/shared/cert.go b/shared/cert.go
index a1e923e0d8..55e4d4dabf 100644
--- a/shared/cert.go
+++ b/shared/cert.go
@@ -22,7 +22,6 @@ import (
"net/http"
"os"
"os/user"
- "path"
"path/filepath"
"time"
)
@@ -230,12 +229,13 @@ func FindOrGenCert(certf string, keyf string, certtype bool, addHosts bool) erro
// GenCert will create and populate a certificate file and a key file
func GenCert(certf string, keyf string, certtype bool, addHosts bool) error {
/* Create the basenames if needed */
- dir := path.Dir(certf)
+ dir := filepath.Dir(certf)
err := os.MkdirAll(dir, 0750)
if err != nil {
return err
}
- dir = path.Dir(keyf)
+
+ dir = filepath.Dir(keyf)
err = os.MkdirAll(dir, 0750)
if err != nil {
return err
From 37e9f82978aa695af20ee88c99cc600393b986b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 20 Aug 2020 14:34:49 -0400
Subject: [PATCH 2/2] lxc/console: Support remote-viewer on Windows
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/console.go | 65 +++++++++++++++++++++++++++---------------
lxc/console_unix.go | 6 ++++
lxc/console_windows.go | 23 +++++++++++++++
3 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/lxc/console.go b/lxc/console.go
index cfc134311b..02e4ae114e 100644
--- a/lxc/console.go
+++ b/lxc/console.go
@@ -7,6 +7,7 @@ import (
"net"
"os"
"os/exec"
+ "runtime"
"strconv"
"github.com/gorilla/websocket"
@@ -218,6 +219,7 @@ func (c *cmdConsole) console(d lxd.InstanceServer, name string) error {
}
func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error {
+ var err error
conf := c.global.conf
// We currently use the control websocket just to abort in case of errors.
@@ -247,31 +249,48 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error {
close(consoleDisconnect)
}()
- // Create a temporary unix socket mirroring the instance's spice socket.
- if !shared.PathExists(conf.ConfigPath("sockets")) {
- err := os.MkdirAll(conf.ConfigPath("sockets"), 0700)
+ var socket string
+ var listener net.Listener
+ if runtime.GOOS != "windows" {
+ // Create a temporary unix socket mirroring the instance's spice socket.
+ if !shared.PathExists(conf.ConfigPath("sockets")) {
+ err := os.MkdirAll(conf.ConfigPath("sockets"), 0700)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Generate a random file name.
+ path, err := ioutil.TempFile(conf.ConfigPath("sockets"), "*.spice")
if err != nil {
return err
}
- }
+ path.Close()
- path, err := ioutil.TempFile(conf.ConfigPath("sockets"), "*.spice")
- if err != nil {
- return err
- }
- err = os.Remove(path.Name())
- if err != nil {
- return err
- }
- path.Close()
+ err = os.Remove(path.Name())
+ if err != nil {
+ return err
+ }
- socket := path.Name()
- listener, err := net.Listen("unix", socket)
- if err != nil {
- return err
+ // Listen on the socket.
+ listener, err = net.Listen("unix", path.Name())
+ if err != nil {
+ return err
+ }
+ defer listener.Close()
+ defer os.Remove(path.Name())
+
+ socket = fmt.Sprintf("spice+unix://%s", path.Name())
+ } else {
+ listener, err = net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ return err
+ }
+ defer listener.Close()
+
+ addr := listener.Addr().(*net.TCPAddr)
+ socket = fmt.Sprintf("spice://127.0.0.1:%d", addr.Port)
}
- defer listener.Close()
- defer os.Remove(path.Name())
op, connect, err := d.ConsoleInstanceDynamic(name, req, &consoleArgs)
if err != nil {
@@ -304,15 +323,15 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error {
}()
// Use either spicy or remote-viewer if available.
- remoteViewer, _ := exec.LookPath("remote-viewer")
- spicy, _ := exec.LookPath("spicy")
+ remoteViewer := c.findCommand("remote-viewer")
+ spicy := c.findCommand("spicy")
if remoteViewer != "" || spicy != "" {
var cmd *exec.Cmd
if remoteViewer != "" {
- cmd = exec.Command(remoteViewer, fmt.Sprintf("spice+unix://%s", socket))
+ cmd = exec.Command(remoteViewer, socket)
} else {
- cmd = exec.Command(spicy, fmt.Sprintf("--uri=spice+unix://%s", socket))
+ cmd = exec.Command(spicy, fmt.Sprintf("--uri=%s", socket))
}
// Start the command.
diff --git a/lxc/console_unix.go b/lxc/console_unix.go
index 0edba5d521..44c7ee672d 100644
--- a/lxc/console_unix.go
+++ b/lxc/console_unix.go
@@ -4,6 +4,7 @@ package main
import (
"os"
+ "os/exec"
"os/signal"
"github.com/gorilla/websocket"
@@ -29,3 +30,8 @@ func (c *cmdConsole) controlSocketHandler(control *websocket.Conn) {
closeMsg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
control.WriteMessage(websocket.CloseMessage, closeMsg)
}
+
+func (c *cmdConsole) findCommand(name string) string {
+ path, _ := exec.LookPath(name)
+ return path
+}
diff --git a/lxc/console_windows.go b/lxc/console_windows.go
index 74649d6e73..422e6113b2 100644
--- a/lxc/console_windows.go
+++ b/lxc/console_windows.go
@@ -4,6 +4,10 @@ package main
import (
"fmt"
+ "io/ioutil"
+ "os/exec"
+ "path/filepath"
+ "strings"
"github.com/gorilla/websocket"
)
@@ -21,3 +25,22 @@ func (c *cmdConsole) controlSocketHandler(control *websocket.Conn) {
fmt.Printf("error setting term size %s\n", err)
}
}
+
+func (c *cmdConsole) findCommand(name string) string {
+ path, _ := exec.LookPath(name)
+ if path == "" {
+ // Let's see if it's not in the usual location.
+ programs, err := ioutil.ReadDir("\\Program Files")
+ if err != nil {
+ return ""
+ }
+
+ for _, entry := range programs {
+ if strings.HasPrefix(entry.Name(), "VirtViewer") {
+ return filepath.Join("\\Program Files", entry.Name(), "bin", "remote-viewer.exe")
+ }
+ }
+ }
+
+ return path
+}
More information about the lxc-devel
mailing list