From 6ec3442428ea15d7fa77a2f1ed144403c655c17f Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:03:37 -0400 Subject: [PATCH 1/6] add fields for type=direct --- builder/libvirt/network/generate.hcl2spec.go | 34 +++++++++++--------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/builder/libvirt/network/generate.hcl2spec.go b/builder/libvirt/network/generate.hcl2spec.go index 4e88f00..c7f5f22 100644 --- a/builder/libvirt/network/generate.hcl2spec.go +++ b/builder/libvirt/network/generate.hcl2spec.go @@ -10,12 +10,14 @@ import ( // FlatNetworkInterface is an auto-generated flat version of NetworkInterface. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatNetworkInterface struct { - Type *string `mapstructure:"type" required:"true" cty:"type" hcl:"type"` - Mac *string `mapstructure:"mac" required:"false" cty:"mac" hcl:"mac"` - Alias *string `mapstructure:"alias" required:"false" cty:"alias" hcl:"alias"` - Model *string `mapstructure:"model" required:"false" cty:"model" hcl:"model"` - Bridge *string `mapstructure:"bridge" required:"false" cty:"bridge" hcl:"bridge"` - Network *string `mapstructure:"network" required:"false" cty:"network" hcl:"network"` + Type *string `mapstructure:"type" required:"true" cty:"type" hcl:"type"` + Mac *string `mapstructure:"mac" required:"false" cty:"mac" hcl:"mac"` + Alias *string `mapstructure:"alias" required:"false" cty:"alias" hcl:"alias"` + Model *string `mapstructure:"model" required:"false" cty:"model" hcl:"model"` + Bridge *string `mapstructure:"bridge" required:"false" cty:"bridge" hcl:"bridge"` + Network *string `mapstructure:"network" required:"false" cty:"network" hcl:"network"` + Mode *string `mapstructure:"mode" required:"false" cty:"mode" hcl:"mode"` + Dev *string `mapstructure:"dev" required:"false" cty:"dev" hcl:"dev"` } // FlatMapstructure returns a new FlatNetworkInterface. @@ -29,13 +31,15 @@ func (*NetworkInterface) FlatMapstructure() interface{ HCL2Spec() map[string]hcl // This spec is used by HCL to read the fields of NetworkInterface. // The decoded values from this spec will then be applied to a FlatNetworkInterface. func (*FlatNetworkInterface) HCL2Spec() map[string]hcldec.Spec { - s := map[string]hcldec.Spec{ - "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, - "mac": &hcldec.AttrSpec{Name: "mac", Type: cty.String, Required: false}, - "alias": &hcldec.AttrSpec{Name: "alias", Type: cty.String, Required: false}, - "model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false}, - "bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false}, - "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, - } - return s + s := map[string]hcldec.Spec{ + "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, + "mac": &hcldec.AttrSpec{Name: "mac", Type: cty.String, Required: false}, + "alias": &hcldec.AttrSpec{Name: "alias", Type: cty.String, Required: false}, + "model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false}, + "bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false}, + "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, + "mode": &hcldec.AttrSpec{Name: "mode", Type: cty.String, Required: false}, + "dev": &hcldec.AttrSpec{Name: "dev", Type: cty.String, Required: false}, + } + return s } From a218f8151253a7568ab8bbb05822cf1679ab56ba Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:04:44 -0400 Subject: [PATCH 2/6] Create direct.go for type=direct simply a copy of bridge.go with some modification to use dev and mode for the direct network interface --- builder/libvirt/network/direct.go | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 builder/libvirt/network/direct.go diff --git a/builder/libvirt/network/direct.go b/builder/libvirt/network/direct.go new file mode 100644 index 0000000..b081b69 --- /dev/null +++ b/builder/libvirt/network/direct.go @@ -0,0 +1,35 @@ +package network + +import ( + "fmt" + + "github.com/hashicorp/packer-plugin-sdk/template/interpolate" + "libvirt.org/go/libvirtxml" +) + +type DirectNetworkInterface struct { + // For `type = "direct" interfaces, the name of the host direct device which the domain connects to + Dev string `mapstructure:"dev" required:"false"` + Mode string `mapstructure:"mode" required:"false"` +} + +func (ni *DirectNetworkInterface) PrepareConfig(ctx *interpolate.Context) (warnings []string, errs []error) { + errs = []error{} + if ni.Dev == "" { + errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify dev")) + } + if ni.Mode == "" { + errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify mode")) + } + + return +} + +func (ni DirectNetworkInterface) UpdateDomainInterface(domainInterface *libvirtxml.DomainInterface) { + domainInterface.Source = &libvirtxml.DomainInterfaceSource{ + Direct: &libvirtxml.DomainInterfaceSourceDirect{ + Dev: ni.Dev, + Mode: ni.Mode, + }, + } +} From 6a957f6eb712598305ea0cb5887d5f1dfc4cbd6f Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:08:53 -0400 Subject: [PATCH 3/6] ssh agent support for ssh_dialer.go modification of sshDialerSetPrivateKey. ssh agent library imported. private key now can be derived from ssh agent by default. keyfile parameter is no longer required, but if it's present, the keyfile is also added --- libvirt-utils/ssh_dialer.go | 51 ++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/libvirt-utils/ssh_dialer.go b/libvirt-utils/ssh_dialer.go index 439aa99..105fbdd 100644 --- a/libvirt-utils/ssh_dialer.go +++ b/libvirt-utils/ssh_dialer.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/packer-plugin-sdk/pathing" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/knownhosts" + "golang.org/x/crypto/ssh/agent" ) type SshDialer struct { @@ -89,33 +90,47 @@ func sshSetAddress(uri LibvirtUri, dialer *SshDialer) error { } func sshDialerSetPrivateKey(uri LibvirtUri, dialer *SshDialer) (err error) { + sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) + if err != nil { + return err + } - keyPath, ok := uri.GetExtra(LibvirtUriParam_Keyfile) - if !ok { - return fmt.Errorf("ssh transport requires %s parameter", LibvirtUriParam_Keyfile) - } + agent := agent.NewClient(sock) - expandedKeyPath, err := pathing.ExpandUser(keyPath) + signers, err := agent.Signers() + if err != nil { + return err + } - if err != nil { - return err - } + auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)} - key, err := ioutil.ReadFile(expandedKeyPath) + dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, auths...) - if err != nil { - return err - } + keyPath, ok := uri.GetExtra(LibvirtUriParam_Keyfile) + if ok { + expandedKeyPath, err := pathing.ExpandUser(keyPath) - parsedKey, err := ssh.ParsePrivateKey(key) + if err != nil { + return err + } - if err != nil { - return err - } + key, err := ioutil.ReadFile(expandedKeyPath) + + if err != nil { + return err + } + + parsedKey, err := ssh.ParsePrivateKey(key) + + if err != nil { + return err + } + + dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, ssh.PublicKeys(parsedKey)) - dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, ssh.PublicKeys(parsedKey)) + } - return + return } func sshDialerSetVerification(uri LibvirtUri, dialer *SshDialer) error { From bfd31b27de4f3433b1d5a32c7f1f2e1faa58fdef Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:10:29 -0400 Subject: [PATCH 4/6] update to libvirt_uri regex added "." to username group in libvirt_uri regex --- libvirt-utils/libvirt_uri.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvirt-utils/libvirt_uri.go b/libvirt-utils/libvirt_uri.go index 34b8b3f..0d9c76c 100644 --- a/libvirt-utils/libvirt_uri.go +++ b/libvirt-utils/libvirt_uri.go @@ -52,7 +52,7 @@ func (uri *LibvirtUri) GetExtra(p LibvirtUriExtraParam) (string, bool) { } func (uri *LibvirtUri) Unmarshal(s string) error { - uriRegex := `^(?P[a-z]+)(\+(?P[a-z]+))?://(((?P[a-z_][-a-z0-9_]*\$?)@)?(?P[-_.a-z0-9]+)(:(?P[0-9]+)?)?)?(?P/[-_.a-z0-9]+)?(\?(?P.*))?$` + uriRegex := `^(?P[a-z]+)(\+(?P[a-z]+))?://(((?P[a-z_][-a-z0-9_\.]*\$?)@)?(?P[-_.a-z0-9]+)(:(?P[0-9]+)?)?)?(?P/[-_.a-z0-9]+)?(\?(?P.*))?$` re := regexp.MustCompile(uriRegex) matches := allMatchedRegexpGroups(re, s) From 3d8d06bd02fcb44195ce31dc083907a568bfba82 Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:13:26 -0400 Subject: [PATCH 5/6] add case options for direct network type --- builder/libvirt/network/network.go | 127 +++++++++++++++-------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/builder/libvirt/network/network.go b/builder/libvirt/network/network.go index 8a4c239..81bbcf9 100644 --- a/builder/libvirt/network/network.go +++ b/builder/libvirt/network/network.go @@ -3,82 +3,87 @@ package network import ( - "fmt" + "fmt" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - "libvirt.org/go/libvirtxml" + "github.com/hashicorp/packer-plugin-sdk/template/interpolate" + "libvirt.org/go/libvirtxml" ) type NetworkInterface struct { - // [required] Type of attached network interface - Type string `mapstructure:"type" required:"true"` - // [optional] If needed, a MAC address can be specified for the network interface. - // If not specified, Libvirt will generate and assign a random MAC address - Mac string `mapstructure:"mac" required:"false"` - // [optional] To help users identifying devices they care about, every device can have an alias which must be unique within the domain. - // Additionally, the identifier must consist only of the following characters: `[a-zA-Z0-9_-]`. - Alias string `mapstructure:"alias" required:"false"` - // [optional] Defines how the interface should be modeled for the domain. - // Typical values for QEMU and KVM include: `ne2k_isa` `i82551` `i82557b` `i82559er` `ne2k_pci` `pcnet` `rtl8139` `e1000` `virtio`. - // If nothing is specified, `virtio` will be used as a default. - Model string `mapstructure:"model" required:"false"` + // [required] Type of attached network interface + Type string `mapstructure:"type" required:"true"` + // [optional] If needed, a MAC address can be specified for the network interface. + // If not specified, Libvirt will generate and assign a random MAC address + Mac string `mapstructure:"mac" required:"false"` + // [optional] To help users identifying devices they care about, every device can have an alias which must be unique within the domain. + // Additionally, the identifier must consist only of the following characters: `[a-zA-Z0-9_-]`. + Alias string `mapstructure:"alias" required:"false"` + // [optional] Defines how the interface should be modeled for the domain. + // Typical values for QEMU and KVM include: `ne2k_isa` `i82551` `i82557b` `i82559er` `ne2k_pci` `pcnet` `rtl8139` `e1000` `virtio`. + // If nothing is specified, `virtio` will be used as a default. + Model string `mapstructure:"model" required:"false"` - Bridge BridgeNetworkInterface `mapstructure:",squash"` - Managed ManagedNetworkInterface `mapstructure:",squash"` + Bridge BridgeNetworkInterface `mapstructure:",squash"` + Direct DirectNetworkInterface `mapstructure:",squash"` + Managed ManagedNetworkInterface `mapstructure:",squash"` } func (ni *NetworkInterface) PrepareConfig(ctx *interpolate.Context) (warnings []string, errs []error) { - warnings = []string{} - errs = []error{} + warnings = []string{} + errs = []error{} - if ni.Model == "" { - ni.Model = "virtio" - } + if ni.Model == "" { + ni.Model = "virtio" + } - if ni.Alias != "" { - ni.Alias = fmt.Sprintf("ua-%s", ni.Alias) - } + if ni.Alias != "" { + ni.Alias = fmt.Sprintf("ua-%s", ni.Alias) + } - var w []string - var e []error - switch ni.Type { - case "managed", "network": - w, e = ni.Managed.PrepareConfig(ctx) - case "bridge": - w, e = ni.Bridge.PrepareConfig(ctx) - default: - errs = append(errs, fmt.Errorf("unsupported network interface type '%s'", ni.Type)) - return - } - warnings = append(warnings, w...) - errs = append(errs, e...) + var w []string + var e []error + switch ni.Type { + case "managed", "network": + w, e = ni.Managed.PrepareConfig(ctx) + case "direct": + w, e = ni.Direct.PrepareConfig(ctx) + case "bridge": + w, e = ni.Bridge.PrepareConfig(ctx) + default: + errs = append(errs, fmt.Errorf("unsupported network interface type '%s'", ni.Type)) + return + } + warnings = append(warnings, w...) + errs = append(errs, e...) - return + return } func (ni NetworkInterface) DomainInterface() *libvirtxml.DomainInterface { - domainInterface := libvirtxml.DomainInterface{ - Model: &libvirtxml.DomainInterfaceModel{ - Type: ni.Model, - }, - } - if ni.Mac != "" { - domainInterface.MAC = &libvirtxml.DomainInterfaceMAC{ - Address: ni.Mac, - } - } - if ni.Alias != "" { - domainInterface.Alias = &libvirtxml.DomainAlias{ - Name: ni.Alias, - } - } + domainInterface := libvirtxml.DomainInterface{ + Model: &libvirtxml.DomainInterfaceModel{ + Type: ni.Model, + }, + } + if ni.Mac != "" { + domainInterface.MAC = &libvirtxml.DomainInterfaceMAC{ + Address: ni.Mac, + } + } + if ni.Alias != "" { + domainInterface.Alias = &libvirtxml.DomainAlias{ + Name: ni.Alias, + } + } - switch ni.Type { - case "bridge": - ni.Bridge.UpdateDomainInterface(&domainInterface) - case "managed": - ni.Managed.UpdateDomainInterface(&domainInterface) - } + switch ni.Type { + case "direct": + ni.Direct.UpdateDomainInterface(&domainInterface) + case "bridge": + ni.Bridge.UpdateDomainInterface(&domainInterface) + case "managed": + ni.Managed.UpdateDomainInterface(&domainInterface) + } - return &domainInterface + return &domainInterface } From 0f0f8c851a1797eb6ca1106553644ba61fe2f645 Mon Sep 17 00:00:00 2001 From: Jacob Karnes <34970194+JACOB-KARNES@users.noreply.github.com> Date: Mon, 9 Oct 2023 20:21:31 -0400 Subject: [PATCH 6/6] fix spacing and tabs --- builder/libvirt/network/direct.go | 40 +++--- builder/libvirt/network/generate.hcl2spec.go | 38 +++--- builder/libvirt/network/network.go | 132 +++++++++---------- libvirt-utils/ssh_dialer.go | 56 ++++---- 4 files changed, 133 insertions(+), 133 deletions(-) diff --git a/builder/libvirt/network/direct.go b/builder/libvirt/network/direct.go index b081b69..4071724 100644 --- a/builder/libvirt/network/direct.go +++ b/builder/libvirt/network/direct.go @@ -1,35 +1,35 @@ package network import ( - "fmt" + "fmt" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - "libvirt.org/go/libvirtxml" + "github.com/hashicorp/packer-plugin-sdk/template/interpolate" + "libvirt.org/go/libvirtxml" ) type DirectNetworkInterface struct { - // For `type = "direct" interfaces, the name of the host direct device which the domain connects to - Dev string `mapstructure:"dev" required:"false"` - Mode string `mapstructure:"mode" required:"false"` + // For `type = "direct" interfaces, the name of the host direct device which the domain connects to + Dev string `mapstructure:"dev" required:"false"` + Mode string `mapstructure:"mode" required:"false"` } func (ni *DirectNetworkInterface) PrepareConfig(ctx *interpolate.Context) (warnings []string, errs []error) { - errs = []error{} - if ni.Dev == "" { - errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify dev")) - } - if ni.Mode == "" { - errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify mode")) - } + errs = []error{} + if ni.Dev == "" { + errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify dev")) + } + if ni.Mode == "" { + errs = append(errs, fmt.Errorf("network interfaces with type=direct must specify mode")) + } - return + return } func (ni DirectNetworkInterface) UpdateDomainInterface(domainInterface *libvirtxml.DomainInterface) { - domainInterface.Source = &libvirtxml.DomainInterfaceSource{ - Direct: &libvirtxml.DomainInterfaceSourceDirect{ - Dev: ni.Dev, - Mode: ni.Mode, - }, - } + domainInterface.Source = &libvirtxml.DomainInterfaceSource{ + Direct: &libvirtxml.DomainInterfaceSourceDirect{ + Dev: ni.Dev, + Mode: ni.Mode, + }, + } } diff --git a/builder/libvirt/network/generate.hcl2spec.go b/builder/libvirt/network/generate.hcl2spec.go index c7f5f22..313d6b1 100644 --- a/builder/libvirt/network/generate.hcl2spec.go +++ b/builder/libvirt/network/generate.hcl2spec.go @@ -10,14 +10,14 @@ import ( // FlatNetworkInterface is an auto-generated flat version of NetworkInterface. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatNetworkInterface struct { - Type *string `mapstructure:"type" required:"true" cty:"type" hcl:"type"` - Mac *string `mapstructure:"mac" required:"false" cty:"mac" hcl:"mac"` - Alias *string `mapstructure:"alias" required:"false" cty:"alias" hcl:"alias"` - Model *string `mapstructure:"model" required:"false" cty:"model" hcl:"model"` - Bridge *string `mapstructure:"bridge" required:"false" cty:"bridge" hcl:"bridge"` - Network *string `mapstructure:"network" required:"false" cty:"network" hcl:"network"` - Mode *string `mapstructure:"mode" required:"false" cty:"mode" hcl:"mode"` - Dev *string `mapstructure:"dev" required:"false" cty:"dev" hcl:"dev"` + Type *string `mapstructure:"type" required:"true" cty:"type" hcl:"type"` + Mac *string `mapstructure:"mac" required:"false" cty:"mac" hcl:"mac"` + Alias *string `mapstructure:"alias" required:"false" cty:"alias" hcl:"alias"` + Model *string `mapstructure:"model" required:"false" cty:"model" hcl:"model"` + Bridge *string `mapstructure:"bridge" required:"false" cty:"bridge" hcl:"bridge"` + Network *string `mapstructure:"network" required:"false" cty:"network" hcl:"network"` + Mode *string `mapstructure:"mode" required:"false" cty:"mode" hcl:"mode"` + Dev *string `mapstructure:"dev" required:"false" cty:"dev" hcl:"dev"` } // FlatMapstructure returns a new FlatNetworkInterface. @@ -31,15 +31,15 @@ func (*NetworkInterface) FlatMapstructure() interface{ HCL2Spec() map[string]hcl // This spec is used by HCL to read the fields of NetworkInterface. // The decoded values from this spec will then be applied to a FlatNetworkInterface. func (*FlatNetworkInterface) HCL2Spec() map[string]hcldec.Spec { - s := map[string]hcldec.Spec{ - "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, - "mac": &hcldec.AttrSpec{Name: "mac", Type: cty.String, Required: false}, - "alias": &hcldec.AttrSpec{Name: "alias", Type: cty.String, Required: false}, - "model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false}, - "bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false}, - "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, - "mode": &hcldec.AttrSpec{Name: "mode", Type: cty.String, Required: false}, - "dev": &hcldec.AttrSpec{Name: "dev", Type: cty.String, Required: false}, - } - return s + s := map[string]hcldec.Spec{ + "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, + "mac": &hcldec.AttrSpec{Name: "mac", Type: cty.String, Required: false}, + "alias": &hcldec.AttrSpec{Name: "alias", Type: cty.String, Required: false}, + "model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false}, + "bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false}, + "network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false}, + "mode": &hcldec.AttrSpec{Name: "mode", Type: cty.String, Required: false}, + "dev": &hcldec.AttrSpec{Name: "dev", Type: cty.String, Required: false}, + } + return s } diff --git a/builder/libvirt/network/network.go b/builder/libvirt/network/network.go index 81bbcf9..329c191 100644 --- a/builder/libvirt/network/network.go +++ b/builder/libvirt/network/network.go @@ -3,87 +3,87 @@ package network import ( - "fmt" + "fmt" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - "libvirt.org/go/libvirtxml" + "github.com/hashicorp/packer-plugin-sdk/template/interpolate" + "libvirt.org/go/libvirtxml" ) type NetworkInterface struct { - // [required] Type of attached network interface - Type string `mapstructure:"type" required:"true"` - // [optional] If needed, a MAC address can be specified for the network interface. - // If not specified, Libvirt will generate and assign a random MAC address - Mac string `mapstructure:"mac" required:"false"` - // [optional] To help users identifying devices they care about, every device can have an alias which must be unique within the domain. - // Additionally, the identifier must consist only of the following characters: `[a-zA-Z0-9_-]`. - Alias string `mapstructure:"alias" required:"false"` - // [optional] Defines how the interface should be modeled for the domain. - // Typical values for QEMU and KVM include: `ne2k_isa` `i82551` `i82557b` `i82559er` `ne2k_pci` `pcnet` `rtl8139` `e1000` `virtio`. - // If nothing is specified, `virtio` will be used as a default. - Model string `mapstructure:"model" required:"false"` + // [required] Type of attached network interface + Type string `mapstructure:"type" required:"true"` + // [optional] If needed, a MAC address can be specified for the network interface. + // If not specified, Libvirt will generate and assign a random MAC address + Mac string `mapstructure:"mac" required:"false"` + // [optional] To help users identifying devices they care about, every device can have an alias which must be unique within the domain. + // Additionally, the identifier must consist only of the following characters: `[a-zA-Z0-9_-]`. + Alias string `mapstructure:"alias" required:"false"` + // [optional] Defines how the interface should be modeled for the domain. + // Typical values for QEMU and KVM include: `ne2k_isa` `i82551` `i82557b` `i82559er` `ne2k_pci` `pcnet` `rtl8139` `e1000` `virtio`. + // If nothing is specified, `virtio` will be used as a default. + Model string `mapstructure:"model" required:"false"` - Bridge BridgeNetworkInterface `mapstructure:",squash"` - Direct DirectNetworkInterface `mapstructure:",squash"` - Managed ManagedNetworkInterface `mapstructure:",squash"` + Bridge BridgeNetworkInterface `mapstructure:",squash"` + Direct DirectNetworkInterface `mapstructure:",squash"` + Managed ManagedNetworkInterface `mapstructure:",squash"` } func (ni *NetworkInterface) PrepareConfig(ctx *interpolate.Context) (warnings []string, errs []error) { - warnings = []string{} - errs = []error{} + warnings = []string{} + errs = []error{} - if ni.Model == "" { - ni.Model = "virtio" - } + if ni.Model == "" { + ni.Model = "virtio" + } - if ni.Alias != "" { - ni.Alias = fmt.Sprintf("ua-%s", ni.Alias) - } + if ni.Alias != "" { + ni.Alias = fmt.Sprintf("ua-%s", ni.Alias) + } - var w []string - var e []error - switch ni.Type { - case "managed", "network": - w, e = ni.Managed.PrepareConfig(ctx) - case "direct": - w, e = ni.Direct.PrepareConfig(ctx) - case "bridge": - w, e = ni.Bridge.PrepareConfig(ctx) - default: - errs = append(errs, fmt.Errorf("unsupported network interface type '%s'", ni.Type)) - return - } - warnings = append(warnings, w...) - errs = append(errs, e...) + var w []string + var e []error + switch ni.Type { + case "managed", "network": + w, e = ni.Managed.PrepareConfig(ctx) + case "direct": + w, e = ni.Direct.PrepareConfig(ctx) + case "bridge": + w, e = ni.Bridge.PrepareConfig(ctx) + default: + errs = append(errs, fmt.Errorf("unsupported network interface type '%s'", ni.Type)) + return + } + warnings = append(warnings, w...) + errs = append(errs, e...) - return + return } func (ni NetworkInterface) DomainInterface() *libvirtxml.DomainInterface { - domainInterface := libvirtxml.DomainInterface{ - Model: &libvirtxml.DomainInterfaceModel{ - Type: ni.Model, - }, - } - if ni.Mac != "" { - domainInterface.MAC = &libvirtxml.DomainInterfaceMAC{ - Address: ni.Mac, - } - } - if ni.Alias != "" { - domainInterface.Alias = &libvirtxml.DomainAlias{ - Name: ni.Alias, - } - } + domainInterface := libvirtxml.DomainInterface{ + Model: &libvirtxml.DomainInterfaceModel{ + Type: ni.Model, + }, + } + if ni.Mac != "" { + domainInterface.MAC = &libvirtxml.DomainInterfaceMAC{ + Address: ni.Mac, + } + } + if ni.Alias != "" { + domainInterface.Alias = &libvirtxml.DomainAlias{ + Name: ni.Alias, + } + } - switch ni.Type { - case "direct": - ni.Direct.UpdateDomainInterface(&domainInterface) - case "bridge": - ni.Bridge.UpdateDomainInterface(&domainInterface) - case "managed": - ni.Managed.UpdateDomainInterface(&domainInterface) - } + switch ni.Type { + case "direct": + ni.Direct.UpdateDomainInterface(&domainInterface) + case "bridge": + ni.Bridge.UpdateDomainInterface(&domainInterface) + case "managed": + ni.Managed.UpdateDomainInterface(&domainInterface) + } - return &domainInterface + return &domainInterface } diff --git a/libvirt-utils/ssh_dialer.go b/libvirt-utils/ssh_dialer.go index 105fbdd..df9eb14 100644 --- a/libvirt-utils/ssh_dialer.go +++ b/libvirt-utils/ssh_dialer.go @@ -90,47 +90,47 @@ func sshSetAddress(uri LibvirtUri, dialer *SshDialer) error { } func sshDialerSetPrivateKey(uri LibvirtUri, dialer *SshDialer) (err error) { - sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) - if err != nil { - return err - } + sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) + if err != nil { + return err + } - agent := agent.NewClient(sock) + agent := agent.NewClient(sock) - signers, err := agent.Signers() - if err != nil { - return err - } + signers, err := agent.Signers() + if err != nil { + return err + } - auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)} + auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)} - dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, auths...) + dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, auths...) - keyPath, ok := uri.GetExtra(LibvirtUriParam_Keyfile) - if ok { - expandedKeyPath, err := pathing.ExpandUser(keyPath) + keyPath, ok := uri.GetExtra(LibvirtUriParam_Keyfile) + if ok { + expandedKeyPath, err := pathing.ExpandUser(keyPath) - if err != nil { - return err - } + if err != nil { + return err + } - key, err := ioutil.ReadFile(expandedKeyPath) + key, err := ioutil.ReadFile(expandedKeyPath) - if err != nil { - return err - } + if err != nil { + return err + } - parsedKey, err := ssh.ParsePrivateKey(key) + parsedKey, err := ssh.ParsePrivateKey(key) - if err != nil { - return err - } + if err != nil { + return err + } - dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, ssh.PublicKeys(parsedKey)) + dialer.sshConfig.Auth = append(dialer.sshConfig.Auth, ssh.PublicKeys(parsedKey)) - } + } - return + return } func sshDialerSetVerification(uri LibvirtUri, dialer *SshDialer) error {