diff --git a/go.mod b/go.mod index 97d7be1d..95ff90b2 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/crc-org/machine-driver-libvirt require ( - github.com/crc-org/machine v0.0.0-20240926103419-a943b47fd48b + github.com/crc-org/machine v0.0.0-20260721135927-5bcb8a00e0f1 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 libvirt.org/go/libvirt v1.8000.0 diff --git a/go.sum b/go.sum index be6cebfd..bfb96edc 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/crc-org/machine v0.0.0-20240926103419-a943b47fd48b h1:5577tKzQcPfd/i0dCekY32R9DUi677sNfhVLYKulBGM= -github.com/crc-org/machine v0.0.0-20240926103419-a943b47fd48b/go.mod h1:trWeQimjfE3dJ8qWOxI4ePtYm13aecK42bf01s6h/Nc= +github.com/crc-org/machine v0.0.0-20260721135927-5bcb8a00e0f1 h1:F+m/3LuzDqnGa9z+m8juGb1epcWAfUNsAoODfzIJkDI= +github.com/crc-org/machine v0.0.0-20260721135927-5bcb8a00e0f1/go.mod h1:trWeQimjfE3dJ8qWOxI4ePtYm13aecK42bf01s6h/Nc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/vendor/github.com/crc-org/machine/libmachine/drivers/base.go b/vendor/github.com/crc-org/machine/libmachine/drivers/base.go index 4300c889..7c64cdb7 100644 --- a/vendor/github.com/crc-org/machine/libmachine/drivers/base.go +++ b/vendor/github.com/crc-org/machine/libmachine/drivers/base.go @@ -75,7 +75,7 @@ func (d *BaseDriver) GetBundleName() (string, error) { return d.BundleName, nil } -func (d *BaseDriver) UpdateConfigRaw(rawData []byte) error { +func (d *BaseDriver) UpdateConfigRaw(_ []byte) error { return ErrNotImplemented } diff --git a/vendor/github.com/crc-org/machine/libmachine/drivers/plugin/register_driver.go b/vendor/github.com/crc-org/machine/libmachine/drivers/plugin/register_driver.go index 34da3972..b3bc0c60 100644 --- a/vendor/github.com/crc-org/machine/libmachine/drivers/plugin/register_driver.go +++ b/vendor/github.com/crc-org/machine/libmachine/drivers/plugin/register_driver.go @@ -6,6 +6,7 @@ import ( "net/http" "net/rpc" "os" + "path/filepath" "time" "github.com/crc-org/machine/libmachine/drivers" @@ -19,6 +20,32 @@ var ( heartbeatTimeout = 10 * time.Second ) +type loggingListener struct { + net.Listener +} + +func (l *loggingListener) Accept() (net.Conn, error) { + conn, err := l.Listener.Accept() + if err != nil { + return nil, err + } + log.WithField("remote", conn.RemoteAddr().String()).Info("RPC connection accepted") + return &loggingConn{Conn: conn, start: time.Now()}, nil +} + +type loggingConn struct { + net.Conn + start time.Time +} + +func (c *loggingConn) Close() error { + log.WithFields(log.Fields{ + "remote": c.RemoteAddr().String(), + "duration": time.Since(c.start), + }).Info("RPC connection closed") + return c.Conn.Close() +} + func RegisterDriver(d drivers.Driver) { if os.Getenv(localbinary.PluginEnvKey) != localbinary.PluginEnvVal { fmt.Fprintf(os.Stderr, `This is a hypervisor plugin binary for CodeReady Containers. @@ -41,17 +68,44 @@ Please use this plugin through the main 'crc' binary. } rpc.HandleHTTP() - listener, err := net.Listen("tcp", "127.0.0.1:0") + socketDir := os.Getenv("CRC_SOCKET_DIR") + if socketDir == "" { + socketDir = filepath.Join(os.TempDir(), "crc-machine") + } + + if err := os.MkdirAll(socketDir, 0700); err != nil { + fmt.Fprintf(os.Stderr, "Error creating socket directory: %s\n", err) + os.Exit(1) + } + socketDirInfo, err := os.Stat(socketDir) + if err != nil { + fmt.Fprintf(os.Stderr, "Error checking socket directory: %s\n", err) + os.Exit(1) + } + if !socketDirInfo.IsDir() || socketDirInfo.Mode().Perm()&0077 != 0 { + fmt.Fprintf(os.Stderr, "Socket directory must be owner-only: %s\n", socketDir) + os.Exit(1) + } + + socketPath := filepath.Join(socketDir, "plugin.sock") + os.Remove(socketPath) + listener, err := net.Listen("unix", socketPath) if err != nil { fmt.Fprintf(os.Stderr, "Error loading RPC server: %s\n", err) os.Exit(1) } defer listener.Close() + if err := os.Chmod(socketPath, 0600); err != nil { + _ = listener.Close() + fmt.Fprintf(os.Stderr, "Error setting socket permissions: %s\n", err) + os.Exit(1) + } fmt.Println(listener.Addr()) go func() { - _ = http.Serve(listener, nil) + //#nosec G114 localhost-only RPC server + _ = http.Serve(&loggingListener{Listener: listener}, nil) }() for { diff --git a/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/client_driver.go b/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/client_driver.go index 15a04f1a..e3e7e7ad 100644 --- a/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/client_driver.go +++ b/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/client_driver.go @@ -128,7 +128,7 @@ func (f *DefaultRPCClientDriverFactory) NewRPCClientDriver(driverName string, dr return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err) } - rpcclient, err := rpc.DialHTTP("tcp", addr) + rpcclient, err := rpc.DialHTTP("unix", addr) if err != nil { return nil, err } diff --git a/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/server_driver.go b/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/server_driver.go index 19ef19d7..3ea1c35a 100644 --- a/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/server_driver.go +++ b/vendor/github.com/crc-org/machine/libmachine/drivers/rpc/server_driver.go @@ -8,6 +8,7 @@ import ( "github.com/crc-org/machine/libmachine/drivers" "github.com/crc-org/machine/libmachine/state" "github.com/crc-org/machine/libmachine/version" + log "github.com/sirupsen/logrus" ) type Stacker interface { @@ -38,12 +39,30 @@ func NewRPCServerDriver(d drivers.Driver) *RPCServerDriver { } } +func (r *RPCServerDriver) logRPC(op string, level log.Level, extra log.Fields) { + fields := log.Fields{"operation": op} + if r.ActualDriver != nil { + func() { + defer func() { _ = recover() }() + if name := r.ActualDriver.GetMachineName(); name != "" { + fields["machine"] = name + } + }() + } + for k, v := range extra { + fields[k] = v + } + log.WithFields(fields).Log(level, "RPC server invocation") +} + func (r *RPCServerDriver) Close(_, _ *struct{}) error { + r.logRPC("Close", log.InfoLevel, nil) r.CloseCh <- true return nil } func (r *RPCServerDriver) GetVersion(_ *struct{}, reply *int) error { + r.logRPC("GetVersion", log.InfoLevel, nil) *reply = version.APIVersion return nil } @@ -55,15 +74,18 @@ func (r *RPCServerDriver) GetConfigRaw(_ *struct{}, reply *[]byte) error { } *reply = driverData + r.logRPC("GetConfigRaw", log.InfoLevel, log.Fields{"config_bytes": len(driverData)}) return nil } func (r *RPCServerDriver) UpdateConfigRaw(data []byte, _ *struct{}) error { + r.logRPC("UpdateConfigRaw", log.InfoLevel, log.Fields{"config_bytes": len(data)}) return r.ActualDriver.UpdateConfigRaw(data) } func (r *RPCServerDriver) SetConfigRaw(data []byte, _ *struct{}) error { + r.logRPC("SetConfigRaw", log.InfoLevel, log.Fields{"config_bytes": len(data)}) return json.Unmarshal(data, &r.ActualDriver) } @@ -74,6 +96,7 @@ func trapPanic(err *error) { } func (r *RPCServerDriver) Create(_, _ *struct{}) (err error) { + r.logRPC("Create", log.InfoLevel, nil) // In an ideal world, plugins wouldn't ever panic. However, panics // have been known to happen and cause issues. Therefore, we recover // and do not crash the RPC server completely in the case of a panic @@ -86,50 +109,60 @@ func (r *RPCServerDriver) Create(_, _ *struct{}) (err error) { } func (r *RPCServerDriver) DriverName(_ *struct{}, reply *string) error { + r.logRPC("DriverName", log.InfoLevel, nil) *reply = r.ActualDriver.DriverName() return nil } func (r *RPCServerDriver) GetIP(_ *struct{}, reply *string) error { + r.logRPC("GetIP", log.InfoLevel, nil) ip, err := r.ActualDriver.GetIP() *reply = ip return err } func (r *RPCServerDriver) GetMachineName(_ *struct{}, reply *string) error { + r.logRPC("GetMachineName", log.InfoLevel, nil) *reply = r.ActualDriver.GetMachineName() return nil } func (r *RPCServerDriver) GetBundleName(_ *struct{}, reply *string) error { + r.logRPC("GetBundleName", log.InfoLevel, nil) path, err := r.ActualDriver.GetBundleName() *reply = path return err } func (r *RPCServerDriver) GetState(_ *struct{}, reply *state.State) error { + r.logRPC("GetState", log.InfoLevel, nil) s, err := r.ActualDriver.GetState() *reply = s return err } func (r *RPCServerDriver) Kill(_ *struct{}, _ *struct{}) error { + r.logRPC("Kill", log.InfoLevel, nil) return r.ActualDriver.Kill() } func (r *RPCServerDriver) PreCreateCheck(_ *struct{}, _ *struct{}) error { + r.logRPC("PreCreateCheck", log.InfoLevel, nil) return r.ActualDriver.PreCreateCheck() } func (r *RPCServerDriver) Remove(_ *struct{}, _ *struct{}) error { + r.logRPC("Remove", log.InfoLevel, nil) return r.ActualDriver.Remove() } func (r *RPCServerDriver) Start(_ *struct{}, _ *struct{}) error { + r.logRPC("Start", log.InfoLevel, nil) return r.ActualDriver.Start() } func (r *RPCServerDriver) Stop(_ *struct{}, _ *struct{}) error { + r.logRPC("Stop", log.InfoLevel, nil) return r.ActualDriver.Stop() } @@ -141,5 +174,8 @@ func (r *RPCServerDriver) Heartbeat(_ *struct{}, _ *struct{}) error { func (r *RPCServerDriver) GetSharedDirs(_ *struct{}, reply *[]drivers.SharedDir) error { sharedDirs, err := r.ActualDriver.GetSharedDirs() *reply = sharedDirs + if err == nil { + r.logRPC("GetSharedDirs", log.InfoLevel, log.Fields{"shared_dirs": len(sharedDirs)}) + } return err } diff --git a/vendor/modules.txt b/vendor/modules.txt index d43bac65..92a9e1e8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/crc-org/machine v0.0.0-20240926103419-a943b47fd48b +# github.com/crc-org/machine v0.0.0-20260721135927-5bcb8a00e0f1 ## explicit; go 1.17 github.com/crc-org/machine/drivers/libvirt github.com/crc-org/machine/libmachine/drivers