working on multiple nics
This commit is contained in:
parent
c0cabf5c57
commit
b437caaf57
2
go.mod
2
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fatih/structs v1.1.0 // indirect
|
github.com/fatih/structs v1.1.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
@ -25,4 +26,5 @@ require (
|
|||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
golang.org/x/crypto v0.6.0 // indirect
|
golang.org/x/crypto v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.20.0 // indirect
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
5
go.sum
5
go.sum
@ -1,6 +1,8 @@
|
|||||||
github.com/abdfnx/gosh v0.4.0 h1:cBvmHw8yV3oXiAcORpi7Oip+MT6/5HBMOrvpn0cZNYM=
|
github.com/abdfnx/gosh v0.4.0 h1:cBvmHw8yV3oXiAcORpi7Oip+MT6/5HBMOrvpn0cZNYM=
|
||||||
github.com/abdfnx/gosh v0.4.0/go.mod h1:MUTJRMc7FpBb/bFnZ2U0hj48zj8284J1cS3AUiIRZ/o=
|
github.com/abdfnx/gosh v0.4.0/go.mod h1:MUTJRMc7FpBb/bFnZ2U0hj48zj8284J1cS3AUiIRZ/o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
@ -8,6 +10,7 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
|
|||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||||
@ -81,3 +84,5 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
|
|||||||
19
machine.yaml
Normal file
19
machine.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Arch: x86_64
|
||||||
|
accel:
|
||||||
|
accel: "whpx\r"
|
||||||
|
boot:
|
||||||
|
menu: false
|
||||||
|
order:
|
||||||
|
- c
|
||||||
|
hda: ./imgs/UbuntuTest.img
|
||||||
|
m:
|
||||||
|
size: 4096
|
||||||
|
nic:
|
||||||
|
options:
|
||||||
|
tap:
|
||||||
|
ifname: qemu-tap
|
||||||
|
type: tap
|
||||||
|
nographic: flag-on
|
||||||
|
numa: {}
|
||||||
|
smp:
|
||||||
|
cpus: 4
|
||||||
34
main.go
34
main.go
@ -28,6 +28,8 @@ import (
|
|||||||
"github.com/rayaman/go-qemu/pkg/v1/types/smp"
|
"github.com/rayaman/go-qemu/pkg/v1/types/smp"
|
||||||
"github.com/shirou/gopsutil/v3/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Credentials struct {
|
type Credentials struct {
|
||||||
@ -78,7 +80,6 @@ func StartMachine(machine system.Machine) *Controller {
|
|||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd := exec.Command(fmt.Sprintf("qemu-system-%v", machine.Arch), machine.Expand()...)
|
cmd := exec.Command(fmt.Sprintf("qemu-system-%v", machine.Arch), machine.Expand()...)
|
||||||
fmt.Println(cmd.String())
|
|
||||||
cmd.Stdout = &stderr
|
cmd.Stdout = &stderr
|
||||||
cmd.Stderr = &stdout
|
cmd.Stderr = &stdout
|
||||||
ctrl.cmd = cmd
|
ctrl.cmd = cmd
|
||||||
@ -137,17 +138,44 @@ func main() {
|
|||||||
Size: 4096,
|
Size: 4096,
|
||||||
},
|
},
|
||||||
Accel: accel.Accel{
|
Accel: accel.Accel{
|
||||||
Accelerator: accel.WHPX,
|
Accelerator: accel.GetAccelerator(arch.X86_64),
|
||||||
},
|
},
|
||||||
Nic: nic.NIC{
|
Nic: nic.NIC{
|
||||||
Type: nic.TAP,
|
Type: nic.TAP,
|
||||||
Options: &nic.TapOptions{
|
Options: nic.Options{
|
||||||
|
Tap: &nic.TapOptions{
|
||||||
IFName: "qemu-tap",
|
IFName: "qemu-tap",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
NoGraphic: types.Set,
|
NoGraphic: types.Set,
|
||||||
HardDiskA: `./imgs/UbuntuTest.img`,
|
HardDiskA: `./imgs/UbuntuTest.img`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := yaml.Marshal(machine)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// Write data to a file
|
||||||
|
err = os.WriteFile("machine.yaml", data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err = os.ReadFile("machine.yaml")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
mac := system.Machine{}
|
||||||
|
err = yaml.Unmarshal(data, &mac)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(machine.Expand())
|
||||||
|
// fmt.Println(mac.Expand())
|
||||||
|
|
||||||
|
fmt.Println(accel.GetAccelerator(arch.X86_64))
|
||||||
|
os.Exit(0)
|
||||||
ctrl := StartMachine(machine)
|
ctrl := StartMachine(machine)
|
||||||
|
|
||||||
fmt.Println("Press enter to stop machine")
|
fmt.Println("Press enter to stop machine")
|
||||||
|
|||||||
23
pkg/utils/utils.go
Normal file
23
pkg/utils/utils.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
func GetFreePort() (int, error) {
|
||||||
|
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := net.ListenTCP("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer l.Close()
|
||||||
|
return l.Addr().(*net.TCPAddr).Port, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts bool to on/off format
|
||||||
|
var SW = map[bool]string{
|
||||||
|
true: "on",
|
||||||
|
false: "off",
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -8,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/abdfnx/gosh"
|
"github.com/abdfnx/gosh"
|
||||||
|
"github.com/rayaman/go-qemu/pkg/v1/types"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/disk"
|
"github.com/rayaman/go-qemu/pkg/v1/types/disk"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,3 +61,54 @@ func Create(i Image, size disk.Size, opts ...Options) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loads a saved image structure into memory
|
||||||
|
func LoadImage(path string) (Image, error) {
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var h = &holder{}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, h)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err = json.Marshal(h.Image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := reflect.New(reflect.TypeOf(types.GetTypes()[h.Format])).Interface()
|
||||||
|
err = json.Unmarshal(data, t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saves an image structure to disk
|
||||||
|
func SaveImage(path string, img Image) error {
|
||||||
|
|
||||||
|
data, err := json.MarshalIndent(holder{
|
||||||
|
Format: strings.ReplaceAll(strings.ToLower(reflect.TypeOf(img).String()), "*formats.", ""),
|
||||||
|
Image: img,
|
||||||
|
}, "", "\t")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = file.Write(data)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package image
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Loads a saved image structure into memory
|
|
||||||
func LoadImage(path string) (Image, error) {
|
|
||||||
data, err := os.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var h = &holder{}
|
|
||||||
|
|
||||||
err = json.Unmarshal(data, h)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err = json.Marshal(h.Image)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t := reflect.New(reflect.TypeOf(types.GetTypes()[h.Format])).Interface()
|
|
||||||
err = json.Unmarshal(data, t)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package image
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Saves an image structure to disk
|
|
||||||
func SaveImage(path string, img Image) error {
|
|
||||||
|
|
||||||
data, err := json.MarshalIndent(holder{
|
|
||||||
Format: strings.ReplaceAll(strings.ToLower(reflect.TypeOf(img).String()), "*formats.", ""),
|
|
||||||
Image: img,
|
|
||||||
}, "", "\t")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Create(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = file.Write(data)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/utils"
|
"github.com/rayaman/go-qemu/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getOptions(m map[string]string) string {
|
func getOptions(m map[string]string) string {
|
||||||
@ -11,11 +11,12 @@ import (
|
|||||||
"github.com/rayaman/go-qemu/pkg/v1/types/arch"
|
"github.com/rayaman/go-qemu/pkg/v1/types/arch"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/boot"
|
"github.com/rayaman/go-qemu/pkg/v1/types/boot"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/chip"
|
"github.com/rayaman/go-qemu/pkg/v1/types/chip"
|
||||||
|
"github.com/rayaman/go-qemu/pkg/v1/types/helpers"
|
||||||
|
"github.com/rayaman/go-qemu/pkg/v1/types/keyboard"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/memory"
|
"github.com/rayaman/go-qemu/pkg/v1/types/memory"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/nic"
|
"github.com/rayaman/go-qemu/pkg/v1/types/nic"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/numa"
|
"github.com/rayaman/go-qemu/pkg/v1/types/numa"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/smp"
|
"github.com/rayaman/go-qemu/pkg/v1/types/smp"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -43,10 +44,11 @@ type Machine struct {
|
|||||||
Cpu chip.CHIP `json:"cpu,omitempty"`
|
Cpu chip.CHIP `json:"cpu,omitempty"`
|
||||||
Accel accel.Accel `json:"accel,omitempty"`
|
Accel accel.Accel `json:"accel,omitempty"`
|
||||||
Boot boot.Boot `json:"boot,omitempty"`
|
Boot boot.Boot `json:"boot,omitempty"`
|
||||||
Numa numa.Numa `json:"numa,omitempty" omit:"true"`
|
Numa numa.Numa `json:"numa,omitempty" omit:"true"` // omit tells the Expand function to leave out the tag name
|
||||||
MemoryPath string `json:"memory-path,omitempty"`
|
MemoryPath string `json:"memory-path,omitempty"`
|
||||||
MemoryPrealloc types.Flag `json:"memory-prealloc,omitempty"`
|
MemoryPrealloc types.Flag `json:"memory-prealloc,omitempty"`
|
||||||
Nic nic.NIC `json:"nic,omitempty"`
|
Nic nic.NIC `json:"nic,omitempty"`
|
||||||
|
KeyboardLayout keyboard.Keyboard `json:"k,omitempty"`
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
NoGraphic types.Flag `json:"nographic,omitempty"`
|
NoGraphic types.Flag `json:"nographic,omitempty"`
|
||||||
@ -70,9 +72,9 @@ func (m *Machine) Expand() []string {
|
|||||||
if tag != "" {
|
if tag != "" {
|
||||||
if field.Kind() == reflect.Struct || field.Kind() == reflect.Interface && !field.IsZero() {
|
if field.Kind() == reflect.Struct || field.Kind() == reflect.Interface && !field.IsZero() {
|
||||||
if omit != "" {
|
if omit != "" {
|
||||||
exp = append(exp, utils.Expand(field.Value())...)
|
exp = append(exp, helpers.Expand(field.Value())...)
|
||||||
} else {
|
} else {
|
||||||
exp = append(exp, utils.Expand(field.Value(), tag)...)
|
exp = append(exp, helpers.Expand(field.Value(), tag)...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !field.IsZero() {
|
if !field.IsZero() {
|
||||||
@ -85,6 +87,6 @@ func (m *Machine) Expand() []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exp = utils.Remove(exp, "")
|
exp = helpers.Remove(exp, "")
|
||||||
return exp
|
return exp
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
package accel
|
package accel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rayaman/go-qemu/pkg/v1/types/arch"
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
VMExit string
|
VMExit string
|
||||||
Accelerator string
|
Accelerator string
|
||||||
@ -12,7 +21,6 @@ const (
|
|||||||
XEN Accelerator = "xen"
|
XEN Accelerator = "xen"
|
||||||
HVF Accelerator = "hvf"
|
HVF Accelerator = "hvf"
|
||||||
NVMM Accelerator = "nvmm"
|
NVMM Accelerator = "nvmm"
|
||||||
// Windows
|
|
||||||
WHPX Accelerator = "whpx"
|
WHPX Accelerator = "whpx"
|
||||||
TCG Accelerator = "tcg"
|
TCG Accelerator = "tcg"
|
||||||
|
|
||||||
@ -55,3 +63,32 @@ type Accel struct {
|
|||||||
// KVM device path, default /dev/kvm
|
// KVM device path, default /dev/kvm
|
||||||
Device string `json:"device,omitempty"`
|
Device string `json:"device,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAccelerator returns an accelerator for the given architecture, if it cannot be found, TCG will be returned
|
||||||
|
func GetAccelerator(a arch.System) Accelerator {
|
||||||
|
cmd := exec.Command(fmt.Sprintf("qemu-system-%v", a), "-accel", "help")
|
||||||
|
|
||||||
|
var stdout bytes.Buffer
|
||||||
|
var stdin bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stdin = &stdin
|
||||||
|
|
||||||
|
err := cmd.Run()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return TCG
|
||||||
|
}
|
||||||
|
|
||||||
|
data := string(stdout.Bytes())
|
||||||
|
|
||||||
|
list := strings.Split(data, "\n")
|
||||||
|
|
||||||
|
for i := 1; i < len(list); i++ {
|
||||||
|
if strings.Contains(list[i], "tcg") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return Accelerator(list[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCG
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package utils
|
package helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -6,17 +6,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
|
"github.com/rayaman/go-qemu/pkg/utils"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/boot"
|
"github.com/rayaman/go-qemu/pkg/v1/types/boot"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/nic"
|
"github.com/rayaman/go-qemu/pkg/v1/types/nic"
|
||||||
"github.com/rayaman/go-qemu/pkg/v1/types/numa"
|
"github.com/rayaman/go-qemu/pkg/v1/types/numa"
|
||||||
)
|
)
|
||||||
|
|
||||||
// converts bool to on/off format
|
|
||||||
var SW = map[bool]string{
|
|
||||||
true: "on",
|
|
||||||
false: "off",
|
|
||||||
}
|
|
||||||
|
|
||||||
func Remove(s []string, r string) []string {
|
func Remove(s []string, r string) []string {
|
||||||
for i, v := range s {
|
for i, v := range s {
|
||||||
if v == r {
|
if v == r {
|
||||||
@ -33,13 +28,14 @@ func Expand(obj any, tag ...string) []string {
|
|||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
opt := strings.ReplaceAll(field.Tag("json"), ",omitempty", "")
|
opt := strings.ReplaceAll(field.Tag("json"), ",omitempty", "")
|
||||||
opt = strings.ReplaceAll(opt, "omitempty", "")
|
opt = strings.ReplaceAll(opt, "omitempty", "")
|
||||||
|
opt = strings.ReplaceAll(opt, ",inline", "")
|
||||||
omit := field.Tag("omit")
|
omit := field.Tag("omit")
|
||||||
if !field.IsZero() || field.Kind() == reflect.Bool || strings.Contains(opt, "id") && field.Kind() != reflect.String {
|
if !field.IsZero() || field.Kind() == reflect.Bool || strings.Contains(opt, "id") && field.Kind() != reflect.String {
|
||||||
switch value := field.Value().(type) {
|
switch value := field.Value().(type) {
|
||||||
case bool:
|
case bool:
|
||||||
opts = append(opts, fmt.Sprintf("%v=%v", opt, SW[value]))
|
opts = append(opts, fmt.Sprintf("%v=%v", opt, utils.SW[value]))
|
||||||
case *bool:
|
case *bool:
|
||||||
opts = append(opts, fmt.Sprintf("%v=%v", opt, SW[*value]))
|
opts = append(opts, fmt.Sprintf("%v=%v", opt, utils.SW[*value]))
|
||||||
case []string:
|
case []string:
|
||||||
opts = append(opts, fmt.Sprintf("%v=%v", opt, strings.Join(value, "")))
|
opts = append(opts, fmt.Sprintf("%v=%v", opt, strings.Join(value, "")))
|
||||||
case numa.CPUS:
|
case numa.CPUS:
|
||||||
35
pkg/v1/types/keyboard/keyboard.go
Normal file
35
pkg/v1/types/keyboard/keyboard.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package keyboard
|
||||||
|
|
||||||
|
type (
|
||||||
|
Keyboard string
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
En_US Keyboard = "en-us"
|
||||||
|
Fr Keyboard = "fr"
|
||||||
|
Da Keyboard = "da"
|
||||||
|
De Keyboard = "de"
|
||||||
|
It Keyboard = "it"
|
||||||
|
Nl Keyboard = "nl"
|
||||||
|
No Keyboard = "no"
|
||||||
|
Pt Keyboard = "pt"
|
||||||
|
Es Keyboard = "es"
|
||||||
|
Fr_ch Keyboard = "fr-ch"
|
||||||
|
De_ch Keyboard = "de-ch"
|
||||||
|
En_gb Keyboard = "en-gb"
|
||||||
|
Ko Keyboard = "ko"
|
||||||
|
Tw Keyboard = "tw"
|
||||||
|
Ja Keyboard = "ja"
|
||||||
|
Fr_ca Keyboard = "fr-ca"
|
||||||
|
Hu Keyboard = "hu"
|
||||||
|
Pl Keyboard = "pl"
|
||||||
|
Cz Keyboard = "cz"
|
||||||
|
Ru Keyboard = "ru"
|
||||||
|
Lv Keyboard = "lv"
|
||||||
|
Tr Keyboard = "tr"
|
||||||
|
Gr Keyboard = "gr"
|
||||||
|
Ar Keyboard = "ar"
|
||||||
|
Lt Keyboard = "lt"
|
||||||
|
Nl_be Keyboard = "nl-be"
|
||||||
|
Be Keyboard = "be"
|
||||||
|
)
|
||||||
@ -1,7 +1,12 @@
|
|||||||
package nic
|
package nic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/structs"
|
||||||
|
"github.com/rayaman/go-qemu/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -23,28 +28,21 @@ type TapOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TapOptions) ExpandOptions() []string {
|
func (t *TapOptions) ExpandOptions() []string {
|
||||||
opts := []string{}
|
return []string{"tap," + strings.Join(expand(t), ",")}
|
||||||
if t.ID != "" {
|
|
||||||
opts = append(opts, "id="+t.ID)
|
|
||||||
}
|
|
||||||
if t.IFName != "" {
|
|
||||||
opts = append(opts, "ifname="+t.IFName)
|
|
||||||
}
|
|
||||||
return []string{"tap," + strings.Join(opts, ",")}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BridgeOptions struct {
|
type BridgeOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BridgeOptions) ExpandOptions() []string {
|
func (b *BridgeOptions) ExpandOptions() []string {
|
||||||
return []string{}
|
return []string{"bridge," + strings.Join(expand(b), ",")}
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserOptions struct {
|
type UserOptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserOptions) ExpandOptions() []string {
|
func (u *UserOptions) ExpandOptions() []string {
|
||||||
return []string{}
|
return []string{"user," + strings.Join(expand(u), ",")}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SocketOptions struct {
|
type SocketOptions struct {
|
||||||
@ -52,17 +50,36 @@ type SocketOptions struct {
|
|||||||
FD string `json:"fd,omitempty"`
|
FD string `json:"fd,omitempty"`
|
||||||
MCast string `json:"mcast,omitempty"`
|
MCast string `json:"mcast,omitempty"`
|
||||||
UDP string `json:"udp,omitempty"`
|
UDP string `json:"udp,omitempty"`
|
||||||
LocalAddress string `json:"localaddr,omitempty"`
|
|
||||||
Listen string `json:"listen,omitempty"`
|
Listen string `json:"listen,omitempty"`
|
||||||
|
LocalAddress string `json:"localaddr,omitempty"`
|
||||||
Connect string `json:"connect,omitempty"`
|
Connect string `json:"connect,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SocketOptions) ExpandOptions() []string {
|
func (s *SocketOptions) ExpandOptions() []string {
|
||||||
return []string{}
|
return []string{"socket," + strings.Join(expand(s), ",")}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options interface {
|
type Options struct {
|
||||||
ExpandOptions() []string
|
Tap *TapOptions `json:"tap,omitempty"`
|
||||||
|
Bridge *BridgeOptions `json:"bridge,omitempty"`
|
||||||
|
User *UserOptions `json:"user,omitempty"`
|
||||||
|
Socket *SocketOptions `json:"socket,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Options) ExpandOptions() []string {
|
||||||
|
if o.Tap != nil {
|
||||||
|
return o.Tap.ExpandOptions()
|
||||||
|
}
|
||||||
|
if o.Bridge != nil {
|
||||||
|
return o.Bridge.ExpandOptions()
|
||||||
|
}
|
||||||
|
if o.User != nil {
|
||||||
|
return o.User.ExpandOptions()
|
||||||
|
}
|
||||||
|
if o.Socket != nil {
|
||||||
|
return o.Socket.ExpandOptions()
|
||||||
|
}
|
||||||
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type NIC struct {
|
type NIC struct {
|
||||||
@ -70,3 +87,31 @@ type NIC struct {
|
|||||||
MacAddress string `json:"mac,omitempty"`
|
MacAddress string `json:"mac,omitempty"`
|
||||||
Options Options `json:"options,omitempty"`
|
Options Options `json:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expand(obj any, tag ...string) []string {
|
||||||
|
opts := []string{}
|
||||||
|
fields := structs.Fields(obj)
|
||||||
|
for _, field := range fields {
|
||||||
|
opt := strings.ReplaceAll(field.Tag("json"), ",omitempty", "")
|
||||||
|
opt = strings.ReplaceAll(opt, "omitempty", "")
|
||||||
|
opt = strings.ReplaceAll(opt, ",inline", "")
|
||||||
|
omit := field.Tag("omit")
|
||||||
|
if !field.IsZero() || field.Kind() == reflect.Bool || strings.Contains(opt, "id") && field.Kind() != reflect.String {
|
||||||
|
switch value := field.Value().(type) {
|
||||||
|
case *bool:
|
||||||
|
opts = append(opts, fmt.Sprintf("%v=%v", opt, utils.SW[*value]))
|
||||||
|
default:
|
||||||
|
if omit == "" {
|
||||||
|
opts = append(opts, fmt.Sprintf("%v=%v", opt, value))
|
||||||
|
} else if omit == "tag" {
|
||||||
|
opts = append(opts, fmt.Sprintf("%v", value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(tag) > 0 {
|
||||||
|
return []string{"-" + tag[0], strings.Join(opts, ",")}
|
||||||
|
} else {
|
||||||
|
return []string{strings.Join(opts, ",")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user