From 2e72ce282d2e2cba763ef32372fe426b6a5e7af3 Mon Sep 17 00:00:00 2001 From: Gerard Braad Date: Wed, 30 Aug 2023 05:02:32 +0000 Subject: [PATCH] Use libhvee instead of the current PowerShell cmdlet implementation This replaces the interaction of Hyper-V from our machine-drivers based driver as used in Minikube/minishift to the libhvee library as used by podman machine. --- go.mod | 3 +- go.sum | 45 ++ pkg/crc/machine/driver_windows.go | 18 +- pkg/crc/machine/hyperv/constants_windows.go | 6 - .../{hyperv => libhvee}/driver_windows.go | 26 +- .../driver_windows_test.go | 2 +- pkg/crc/preflight/preflight_checks_windows.go | 14 - pkg/crc/preflight/preflight_windows.go | 8 - pkg/drivers/hyperv/hyperv_windows.go | 416 ------------ pkg/drivers/libhvee/libhvee_windows.go | 309 +++++++++ .../{hyperv => libhvee}/powershell_windows.go | 6 +- pkg/libmachine/load_windows.go | 6 +- vendor/github.com/containers/libhvee/LICENSE | 201 ++++++ .../pkg/hypervctl/diskdrive_settings.go | 72 ++ .../pkg/hypervctl/drive_settings_builder.go | 186 +++++ .../pkg/hypervctl/dvddrive_settings.go | 24 + .../containers/libhvee/pkg/hypervctl/error.go | 157 +++++ .../pkg/hypervctl/ethernet_alloc_settings.go | 50 ++ .../pkg/hypervctl/ethernet_port_settings.go | 109 +++ .../containers/libhvee/pkg/hypervctl/kvp.go | 138 ++++ .../libhvee/pkg/hypervctl/memory_settings.go | 56 ++ .../pkg/hypervctl/network_settings_builder.go | 86 +++ .../pkg/hypervctl/processor_settings.go | 98 +++ .../pkg/hypervctl/resources_settings.go | 135 ++++ .../libhvee/pkg/hypervctl/scsi_controller.go | 69 ++ .../pkg/hypervctl/storage_alloc_settings.go | 61 ++ .../libhvee/pkg/hypervctl/summary.go | 202 ++++++ .../libhvee/pkg/hypervctl/system_settings.go | 207 ++++++ .../pkg/hypervctl/system_settings_builder.go | 161 +++++ .../pkg/hypervctl/vdvd_storage_settings.go | 13 + .../libhvee/pkg/hypervctl/vhd_settings.go | 28 + .../pkg/hypervctl/vhd_storage_settings.go | 13 + .../containers/libhvee/pkg/hypervctl/vm.go | 601 +++++++++++++++++ .../libhvee/pkg/hypervctl/vm_config.go | 117 ++++ .../containers/libhvee/pkg/hypervctl/vmm.go | 184 +++++ .../containers/libhvee/pkg/kvp/ginsu/util.go | 46 ++ .../containers/libhvee/pkg/wmiext/array.go | 202 ++++++ .../libhvee/pkg/wmiext/conversion.go | 474 +++++++++++++ .../containers/libhvee/pkg/wmiext/enum.go | 94 +++ .../containers/libhvee/pkg/wmiext/init.go | 113 ++++ .../containers/libhvee/pkg/wmiext/instance.go | 634 ++++++++++++++++++ .../containers/libhvee/pkg/wmiext/invoke.go | 125 ++++ .../containers/libhvee/pkg/wmiext/job.go | 53 ++ .../containers/libhvee/pkg/wmiext/service.go | 416 ++++++++++++ vendor/golang.org/x/sys/unix/mkerrors.sh | 2 +- vendor/golang.org/x/sys/unix/mmap_nomremap.go | 14 + vendor/golang.org/x/sys/unix/mremap.go | 21 +- vendor/golang.org/x/sys/unix/syscall_aix.go | 15 - vendor/golang.org/x/sys/unix/syscall_bsd.go | 14 - .../golang.org/x/sys/unix/syscall_darwin.go | 50 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 63 +- .../x/sys/unix/syscall_linux_amd64.go | 2 +- .../x/sys/unix/syscall_linux_arm64.go | 2 +- .../x/sys/unix/syscall_linux_loong64.go | 2 +- .../x/sys/unix/syscall_linux_mips64x.go | 2 +- .../x/sys/unix/syscall_linux_riscv64.go | 13 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 13 +- .../golang.org/x/sys/unix/syscall_solaris.go | 14 - vendor/golang.org/x/sys/unix/syscall_unix.go | 8 + .../x/sys/unix/syscall_zos_s390x.go | 14 - .../x/sys/unix/zerrors_linux_386.go | 9 + .../x/sys/unix/zerrors_linux_amd64.go | 9 + .../x/sys/unix/zerrors_linux_arm.go | 9 + .../x/sys/unix/zerrors_linux_arm64.go | 9 + .../x/sys/unix/zerrors_linux_loong64.go | 9 + .../x/sys/unix/zerrors_linux_mips.go | 9 + .../x/sys/unix/zerrors_linux_mips64.go | 9 + .../x/sys/unix/zerrors_linux_mips64le.go | 9 + .../x/sys/unix/zerrors_linux_mipsle.go | 9 + .../x/sys/unix/zerrors_linux_ppc.go | 9 + .../x/sys/unix/zerrors_linux_ppc64.go | 9 + .../x/sys/unix/zerrors_linux_ppc64le.go | 9 + .../x/sys/unix/zerrors_linux_riscv64.go | 9 + .../x/sys/unix/zerrors_linux_s390x.go | 9 + .../x/sys/unix/zerrors_linux_sparc64.go | 9 + .../golang.org/x/sys/unix/zsyscall_linux.go | 2 +- .../x/sys/unix/zsyscall_linux_riscv64.go | 16 + .../x/sys/unix/zsyscall_netbsd_386.go | 11 + .../x/sys/unix/zsyscall_netbsd_amd64.go | 11 + .../x/sys/unix/zsyscall_netbsd_arm.go | 11 + .../x/sys/unix/zsyscall_netbsd_arm64.go | 11 + .../x/sys/unix/zsysnum_linux_riscv64.go | 2 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 5 + .../x/sys/unix/ztypes_linux_riscv64.go | 23 + .../x/sys/windows/syscall_windows.go | 4 +- vendor/modules.txt | 7 +- 86 files changed, 5872 insertions(+), 599 deletions(-) delete mode 100644 pkg/crc/machine/hyperv/constants_windows.go rename pkg/crc/machine/{hyperv => libhvee}/driver_windows.go (61%) rename pkg/crc/machine/{hyperv => libhvee}/driver_windows_test.go (94%) delete mode 100644 pkg/drivers/hyperv/hyperv_windows.go create mode 100644 pkg/drivers/libhvee/libhvee_windows.go rename pkg/drivers/{hyperv => libhvee}/powershell_windows.go (96%) create mode 100644 vendor/github.com/containers/libhvee/LICENSE create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/diskdrive_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/drive_settings_builder.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/dvddrive_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/error.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_alloc_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_port_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/kvp.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/memory_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/network_settings_builder.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/processor_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/resources_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/scsi_controller.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/storage_alloc_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/summary.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings_builder.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vdvd_storage_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_storage_settings.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vm.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vm_config.go create mode 100644 vendor/github.com/containers/libhvee/pkg/hypervctl/vmm.go create mode 100644 vendor/github.com/containers/libhvee/pkg/kvp/ginsu/util.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/array.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/conversion.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/enum.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/init.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/instance.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/invoke.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/job.go create mode 100644 vendor/github.com/containers/libhvee/pkg/wmiext/service.go create mode 100644 vendor/golang.org/x/sys/unix/mmap_nomremap.go diff --git a/go.mod b/go.mod index 6fbb482a43..6c61189681 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( golang.org/x/crypto v0.11.0 golang.org/x/net v0.12.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.10.0 + golang.org/x/sys v0.11.0 golang.org/x/term v0.10.0 golang.org/x/text v0.11.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -78,6 +78,7 @@ require ( github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/cloudflare/circl v1.3.3 // indirect + github.com/containers/libhvee v0.4.1-0.20230901182836-fcf1478fdd75 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.1.7 // indirect github.com/containers/storage v1.45.3 // indirect diff --git a/go.sum b/go.sum index 44d1e1089f..ed75ac771d 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,9 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkk github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -76,6 +79,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -83,8 +87,10 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= @@ -108,10 +114,19 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/containers/gvisor-tap-vsock v0.6.2 h1:wc/me5SXVlF2iOv5gjmjZARsJTggzpVoNO9dgC+2uRA= github.com/containers/gvisor-tap-vsock v0.6.2/go.mod h1:vyqP7jqNzPudoYhnvj3Dw2lhsjQ3kf1/PyXLEaZsvb0= github.com/containers/image/v5 v5.24.1 h1:XaRw3FJmvZtI297uBVTJluUVH4AQJ//YpHviaOw0C4M= github.com/containers/image/v5 v5.24.1/go.mod h1:oss5F6ssGQz8ZtC79oY+fuzYA3m3zBek9tq9gmhuvHc= +github.com/containers/libhvee v0.4.0 h1:HGHIIExgP2PjwjHKKoQM3B+3qakNIZcmmkiAO4luAZE= +github.com/containers/libhvee v0.4.0/go.mod h1:fyWDxNQccveTdE3Oe+QRuLbwF/iyV0hDxXqRX5Svlic= +github.com/containers/libhvee v0.4.1-0.20230901182836-fcf1478fdd75 h1:zrZ+yh2wI3zOKC9OC63OxdSoS/jOzamnDmRVbDvr0Ws= +github.com/containers/libhvee v0.4.1-0.20230901182836-fcf1478fdd75/go.mod h1:I30im5oKCYBJMEa+r0jffZn+Yb5/8CnYeAJy+vb77Mg= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.1.7 h1:thhNr4fu2ltyGz8aMx8u48Ae0Pnbip3ePP9/mzkZ/3U= @@ -169,6 +184,7 @@ github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryef github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -195,6 +211,7 @@ github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBD github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -251,6 +268,7 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y= github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -305,6 +323,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -324,6 +343,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/goodhosts/hostsfile v0.1.1 h1:SqRUTFOshOCon0ZSXDrW1bkKZvs4+5pRgYFWySdaLno= github.com/goodhosts/hostsfile v0.1.1/go.mod h1:lXcUP8xO4WR5vvuQ3F/N0bMQoclOtYKEEUnyY2jTusY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -347,6 +367,7 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.12.1 h1:W1mzdNUTx4Zla4JaixCRLhORcR7G6KxE5hHl5fkPsp8= github.com/google/go-containerregistry v0.12.1/go.mod h1:sdIK+oHQO7B93xI8UweYdl887YhuIwg9vz8BSLH3+8k= +github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -383,9 +404,11 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -405,6 +428,7 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -428,6 +452,7 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc= github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -441,6 +466,7 @@ github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f h1:l1QCwn715k8nY github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -489,6 +515,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf h1:ndns1qx/5dL43g16EQkPV/i8+b3l5bYQwLeoSBe7tS8= github.com/letsencrypt/boulder v0.0.0-20221109233200-85aa52084eaf/go.mod h1:aGkAgvWY/IUcVFfuly53REpfv5edu25oij+qHRFaraA= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/linuxkit/virtsock v0.0.0-20220523201153-1a23e78aa7a2 h1:DZMFueDbfz6PNc1GwDRA8+6lBx1TB9UnxDQliCqR73Y= github.com/linuxkit/virtsock v0.0.0-20220523201153-1a23e78aa7a2/go.mod h1:SWzULI85WerrFt3u+nIm5F9l7EvxZTKQvd0InF3nmgM= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -515,6 +542,7 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 h1:lez6TS6aAau+8wXUP3G9I3TGlmPFEq2CTxBaRqY6AGE= @@ -563,14 +591,18 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= @@ -609,6 +641,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -648,6 +681,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -728,6 +762,7 @@ github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5 h1:s+Yvt6bzRwHljSE7j6DLBDcfpZEdBhrvLgOUmd8f7ZM= github.com/theupdateframework/go-tuf v0.5.2-0.20221207161717-9cb61d6e65f5/go.mod h1:Le8NAjvDJK1vmLgpVYr4AR1Tqam/b/mTdQyTy37UJDA= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -760,7 +795,9 @@ github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6 github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -1009,6 +1046,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1211,7 +1250,9 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1224,6 +1265,8 @@ gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1239,6 +1282,7 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gvisor.dev/gvisor v0.0.0-20221216231429-a78e892a26d2 h1:QN+Xh63jThYFN4CrcD4KXj+rUhevlb0LXEAlZ4m+qXQ= @@ -1258,6 +1302,7 @@ k8s.io/apimachinery v0.26.6 h1:OT04J9US8G+AqfqvcJZZ8s3WUQkWbc3t6ePPWieDN6I= k8s.io/apimachinery v0.26.6/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0= k8s.io/client-go v0.26.6 h1:CtC0wOxkAwjYyG2URGzdEKo0nLILopSDYn5AmzOkdi4= k8s.io/client-go v0.26.6/go.mod h1:HDjbQGY7XzFYFUWOPAfAsIYhvFXyc9l6Ne0pO0bOQ7o= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= diff --git a/pkg/crc/machine/driver_windows.go b/pkg/crc/machine/driver_windows.go index 148bb1f637..c0125a58f1 100644 --- a/pkg/crc/machine/driver_windows.go +++ b/pkg/crc/machine/driver_windows.go @@ -5,28 +5,28 @@ import ( "errors" "github.com/crc-org/crc/pkg/crc/machine/config" - "github.com/crc-org/crc/pkg/crc/machine/hyperv" - machineHyperv "github.com/crc-org/crc/pkg/drivers/hyperv" + "github.com/crc-org/crc/pkg/crc/machine/libhvee" + machineLibhvee "github.com/crc-org/crc/pkg/drivers/libhvee" "github.com/crc-org/crc/pkg/libmachine" "github.com/crc-org/crc/pkg/libmachine/host" ) func newHost(api libmachine.API, machineConfig config.MachineConfig) (*host.Host, error) { - json, err := json.Marshal(hyperv.CreateHost(machineConfig)) + json, err := json.Marshal(libhvee.CreateHost(machineConfig)) if err != nil { return nil, errors.New("Failed to marshal driver options") } return api.NewHost("hyperv", "", json) } -func loadDriverConfig(host *host.Host) (*machineHyperv.Driver, error) { - var hypervDriver machineHyperv.Driver - err := json.Unmarshal(host.RawDriver, &hypervDriver) +func loadDriverConfig(host *host.Host) (*machineLibhvee.Driver, error) { + var libhveeDriver machineLibhvee.Driver + err := json.Unmarshal(host.RawDriver, &libhveeDriver) - return &hypervDriver, err + return &libhveeDriver, err } -func updateDriverConfig(host *host.Host, driver *machineHyperv.Driver) error { +func updateDriverConfig(host *host.Host, driver *machineLibhvee.Driver) error { driverData, err := json.Marshal(driver) if err != nil { return err @@ -38,7 +38,7 @@ func updateKernelArgs(_ *virtualMachine) error { return nil } -func updateDriverStruct(host *host.Host, driver *machineHyperv.Driver) error { +func updateDriverStruct(host *host.Host, driver *machineLibhvee.Driver) error { host.Driver = driver return nil } diff --git a/pkg/crc/machine/hyperv/constants_windows.go b/pkg/crc/machine/hyperv/constants_windows.go deleted file mode 100644 index ec04f1b6ac..0000000000 --- a/pkg/crc/machine/hyperv/constants_windows.go +++ /dev/null @@ -1,6 +0,0 @@ -package hyperv - -const ( - // Alternative - AlternativeNetwork = "crc" -) diff --git a/pkg/crc/machine/hyperv/driver_windows.go b/pkg/crc/machine/libhvee/driver_windows.go similarity index 61% rename from pkg/crc/machine/hyperv/driver_windows.go rename to pkg/crc/machine/libhvee/driver_windows.go index 5662aefe73..ebf92e336b 100644 --- a/pkg/crc/machine/hyperv/driver_windows.go +++ b/pkg/crc/machine/libhvee/driver_windows.go @@ -1,4 +1,4 @@ -package hyperv +package libhvee import ( "path/filepath" @@ -6,29 +6,17 @@ import ( "github.com/crc-org/crc/pkg/crc/constants" "github.com/crc-org/crc/pkg/crc/machine/config" - "github.com/crc-org/crc/pkg/crc/network" - "github.com/crc-org/crc/pkg/drivers/hyperv" - winnet "github.com/crc-org/crc/pkg/os/windows/network" + "github.com/crc-org/crc/pkg/drivers/libhvee" "github.com/crc-org/machine/libmachine/drivers" ) -func CreateHost(machineConfig config.MachineConfig) *hyperv.Driver { - hypervDriver := hyperv.NewDriver(machineConfig.Name, constants.MachineBaseDir) +func CreateHost(machineConfig config.MachineConfig) *libhvee.Driver { + libhveeDriver := libhvee.NewDriver(machineConfig.Name, constants.MachineBaseDir) - config.InitVMDriverFromMachineConfig(machineConfig, hypervDriver.VMDriver) + config.InitVMDriverFromMachineConfig(machineConfig, libhveeDriver.VMDriver) - hypervDriver.DisableDynamicMemory = true - - if machineConfig.NetworkMode == network.UserNetworkingMode { - hypervDriver.VirtualSwitch = "" - } else { - // Determine the Virtual Switch to be used - _, switchName := winnet.SelectSwitchByNameOrDefault(AlternativeNetwork) - hypervDriver.VirtualSwitch = switchName - } - - hypervDriver.SharedDirs = configureShareDirs(machineConfig) - return hypervDriver + libhveeDriver.SharedDirs = configureShareDirs(machineConfig) + return libhveeDriver } // converts a path like c:\users\crc to /mnt/c/users/crc diff --git a/pkg/crc/machine/hyperv/driver_windows_test.go b/pkg/crc/machine/libhvee/driver_windows_test.go similarity index 94% rename from pkg/crc/machine/hyperv/driver_windows_test.go rename to pkg/crc/machine/libhvee/driver_windows_test.go index b331204e40..e757d54799 100755 --- a/pkg/crc/machine/hyperv/driver_windows_test.go +++ b/pkg/crc/machine/libhvee/driver_windows_test.go @@ -1,4 +1,4 @@ -package hyperv +package libhvee import ( "testing" diff --git a/pkg/crc/preflight/preflight_checks_windows.go b/pkg/crc/preflight/preflight_checks_windows.go index 91af99c629..b5c467404c 100644 --- a/pkg/crc/preflight/preflight_checks_windows.go +++ b/pkg/crc/preflight/preflight_checks_windows.go @@ -12,7 +12,6 @@ import ( "github.com/crc-org/crc/pkg/os/windows/powershell" "github.com/crc-org/crc/pkg/crc/constants" - "github.com/crc-org/crc/pkg/crc/machine/hyperv" ) const ( @@ -166,19 +165,6 @@ func fixUserPartOfCrcUsersAndHypervAdminsGroup() error { return errReboot } -func checkIfHyperVVirtualSwitchExists() error { - switchName := hyperv.AlternativeNetwork - - // use winnet instead - exists, foundName := winnet.SelectSwitchByNameOrDefault(switchName) - if exists { - logging.Info("Found Virtual Switch to use: ", foundName) - return nil - } - - return fmt.Errorf("Virtual Switch not found") -} - func checkIfRunningAsNormalUser() error { if !powershell.IsAdmin() { return nil diff --git a/pkg/crc/preflight/preflight_windows.go b/pkg/crc/preflight/preflight_windows.go index 6038e5bb0a..def02a7fae 100644 --- a/pkg/crc/preflight/preflight_windows.go +++ b/pkg/crc/preflight/preflight_windows.go @@ -55,14 +55,6 @@ var hypervPreflightChecks = []Check{ labels: labels{Os: Windows}, }, - { - configKeySuffix: "check-hyperv-switch", - checkDescription: "Checking if the Hyper-V virtual switch exists", - check: checkIfHyperVVirtualSwitchExists, - flags: StartUpOnly, - - labels: labels{Os: Windows, NetworkMode: System}, - }, { cleanupDescription: "Removing dns server from interface", cleanup: removeDNSServerAddress, diff --git a/pkg/drivers/hyperv/hyperv_windows.go b/pkg/drivers/hyperv/hyperv_windows.go deleted file mode 100644 index c1a9e1cfad..0000000000 --- a/pkg/drivers/hyperv/hyperv_windows.go +++ /dev/null @@ -1,416 +0,0 @@ -package hyperv - -import ( - "encoding/json" - "errors" - "fmt" - "os/exec" - "strconv" - "strings" - "time" - - log "github.com/crc-org/crc/pkg/crc/logging" - crcos "github.com/crc-org/crc/pkg/os" - "github.com/crc-org/crc/pkg/os/windows/powershell" - crcstrings "github.com/crc-org/crc/pkg/strings" - "github.com/crc-org/machine/libmachine/drivers" - "github.com/crc-org/machine/libmachine/state" -) - -type Driver struct { - *drivers.VMDriver - VirtualSwitch string - MacAddress string - DisableDynamicMemory bool -} - -const ( - defaultMemory = 8192 - defaultCPU = 4 - defaultDisableDynamicMemory = false -) - -// NewDriver creates a new Hyper-v driver with default settings. -func NewDriver(hostName, storePath string) *Driver { - return &Driver{ - DisableDynamicMemory: defaultDisableDynamicMemory, - VMDriver: &drivers.VMDriver{ - BaseDriver: &drivers.BaseDriver{ - MachineName: hostName, - StorePath: storePath, - }, - Memory: defaultMemory, - CPU: defaultCPU, - }, - } -} - -func (d *Driver) UpdateConfigRaw(rawConfig []byte) error { - var newDriver Driver - - err := json.Unmarshal(rawConfig, &newDriver) - if err != nil { - return err - } - if newDriver.Memory != d.Memory { - log.Debugf("Updating memory from %d MB to %d MB", d.Memory, newDriver.Memory) - err := cmd("Hyper-V\\Set-VMMemory", - "-VMName", d.MachineName, - "-StartupBytes", toMb(newDriver.Memory)) - if err != nil { - log.Warnf("Failed to update memory to %d MB: %v", newDriver.Memory, err) - return err - } - } - - if newDriver.CPU != d.CPU { - log.Debugf("Updating CPU count from %d to %d", d.CPU, newDriver.CPU) - err := cmd("Hyper-V\\Set-VMProcessor", - d.MachineName, - "-Count", fmt.Sprintf("%d", newDriver.CPU)) - if err != nil { - log.Warnf("Failed to set CPU count to %d", newDriver.CPU) - return err - } - } - if newDriver.DiskCapacity != d.DiskCapacity { - if err := d.resizeDisk(int64(newDriver.DiskCapacity)); err != nil { - log.Warnf("Failed to set disk size to %d", newDriver.DiskCapacity) - return err - } - } - *d = newDriver - return nil -} - -// DriverName returns the name of the driver -func (d *Driver) DriverName() string { - return "hyperv" -} - -func (d *Driver) GetState() (state.State, error) { - stdout, stderr, err := powershell.Execute("Hyper-V\\Get-VM", d.MachineName, "|", "Select-Object", "-ExpandProperty", "State") - if err != nil { - return state.Error, fmt.Errorf("Failed to find the VM status: %v - %s", err, stderr) - } - - resp := crcstrings.FirstLine(stdout) - if resp == "" { - return state.Error, fmt.Errorf("unexpected Hyper-V state %s", stdout) - } - - switch resp { - case "Starting", "Running", "Stopping": - return state.Running, nil - case "Off": - return state.Stopped, nil - default: - return state.Error, fmt.Errorf("unexpected Hyper-V state %s", resp) - } -} - -// PreCreateCheck checks that the machine creation process can be started safely. -func (d *Driver) PreCreateCheck() error { - // Check that powershell was found - if _, err := exec.LookPath("powershell.exe"); err != nil { - return ErrPowerShellNotFound - } - - // Check that hyperv is installed - if err := hypervAvailable(); err != nil { - return err - } - - // Check that the user is an Administrator - isAdmin, err := isAdministrator() - if err != nil { - return err - } - if !isAdmin { - return ErrNotAdministrator - } - - if d.VirtualSwitch == "" { - return nil - } - - // Check that there is a virtual switch already configured - if _, err := d.chooseVirtualSwitch(); err != nil { - return err - } - - return err -} - -func (d *Driver) getDiskPath() string { - return d.ResolveStorePath(fmt.Sprintf("%s.%s", d.MachineName, d.ImageFormat)) -} - -func (d *Driver) resizeDisk(newSize int64) error { - diskPath := d.getDiskPath() - out, err := cmdOut(fmt.Sprintf("@(Get-VHD -Path %s).Size", quote(diskPath))) - if err != nil { - return fmt.Errorf("unable to get current size of crc.vhdx: %w", err) - } - currentSize, err := strconv.ParseInt(strings.TrimSpace(out), 10, 64) - if err != nil { - return fmt.Errorf("unable to convert disk size to int: %w", err) - } - if newSize == currentSize { - log.Debugf("%s is already %d bytes", diskPath, newSize) - return nil - } - if newSize < currentSize { - return fmt.Errorf("current disk image capacity is bigger than the requested size (%d > %d)", currentSize, newSize) - } - - log.Debugf("Resizing disk from %d bytes to %d bytes", currentSize, newSize) - return cmd("Hyper-V\\Resize-VHD", - "-Path", - quote(diskPath), - "-SizeBytes", - fmt.Sprintf("%d", newSize)) -} - -func (d *Driver) Create() error { - if err := crcos.CopyFile(d.ImageSourcePath, d.getDiskPath()); err != nil { - return err - } - - args := []string{ - "Hyper-V\\New-VM", - d.MachineName, - "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath(".")), - "-MemoryStartupBytes", toMb(d.Memory), - } - if d.VirtualSwitch != "" { - virtualSwitch, err := d.chooseVirtualSwitch() - if err != nil { - return err - } - log.Debugf("Using switch %q", virtualSwitch) - args = append(args, "-SwitchName", quote(virtualSwitch)) - } - - log.Debugf("Creating VM...") - if err := cmd(args...); err != nil { - return err - } - - if d.VirtualSwitch == "" { - if err := cmd("Hyper-V\\Remove-VMNetworkAdapter", "-VMName", d.MachineName); err != nil { - return err - } - } - - if d.DisableDynamicMemory { - if err := cmd("Hyper-V\\Set-VMMemory", - "-VMName", d.MachineName, - "-DynamicMemoryEnabled", "$false"); err != nil { - return err - } - } - - if d.CPU > 1 { - if err := cmd("Hyper-V\\Set-VMProcessor", - d.MachineName, - "-Count", fmt.Sprintf("%d", d.CPU)); err != nil { - return err - } - } - - if d.VirtualSwitch != "" && d.MacAddress != "" { - if err := cmd("Hyper-V\\Set-VMNetworkAdapter", - "-VMName", d.MachineName, - "-StaticMacAddress", fmt.Sprintf("\"%s\"", d.MacAddress)); err != nil { - return err - } - } - - // Disables creating checkpoints and Automatic Start - // Shuts down the VM when host shuts down - if err := cmd("Hyper-V\\Set-VM", - "-VMName", d.MachineName, - "-AutomaticStartAction", "Nothing", - "-AutomaticStopAction", "ShutDown", - "-CheckpointType", "Disabled"); err != nil { - return err - } - - if err := cmd("Hyper-V\\Add-VMHardDiskDrive", - "-VMName", d.MachineName, - "-Path", quote(d.getDiskPath())); err != nil { - return err - } - - return d.resizeDisk(int64(d.DiskCapacity)) - -} - -func (d *Driver) chooseVirtualSwitch() (string, error) { - if d.VirtualSwitch == "" { - return "", errors.New("no virtual switch given") - } - - stdout, err := cmdOut("[Console]::OutputEncoding = [Text.Encoding]::UTF8; (Hyper-V\\Get-VMSwitch).Name") - if err != nil { - return "", err - } - - switches := crcstrings.SplitLines(stdout) - - found := false - for _, name := range switches { - if name == d.VirtualSwitch { - found = true - break - } - } - - if !found { - return "", fmt.Errorf("virtual switch %q not found", d.VirtualSwitch) - } - - return d.VirtualSwitch, nil -} - -// waitForIP waits until the host has a valid IP -func (d *Driver) waitForIP() (string, error) { - if d.VirtualSwitch == "" { - return "", errors.New("no virtual switch given") - } - - log.Debugf("Waiting for host to start...") - - for { - ip, _ := d.GetIP() - if ip != "" { - return ip, nil - } - - time.Sleep(1 * time.Second) - } -} - -// waitStopped waits until the host is stopped -func (d *Driver) waitStopped() error { - log.Debugf("Waiting for host to stop...") - - for { - s, err := d.GetState() - if err != nil { - return err - } - - if s != state.Running { - return nil - } - - time.Sleep(1 * time.Second) - } -} - -// Start starts an host -func (d *Driver) Start() error { - if err := cmd("Hyper-V\\Start-VM", d.MachineName); err != nil { - return err - } - - if d.VirtualSwitch == "" { - return nil - } - - ip, err := d.waitForIP() - if err != nil { - return err - } - - d.IPAddress = ip - - return nil -} - -// Stop stops an host -func (d *Driver) Stop() error { - if err := cmd("Hyper-V\\Stop-VM", d.MachineName); err != nil { - return err - } - - if err := d.waitStopped(); err != nil { - return err - } - - d.IPAddress = "" - - return nil -} - -// Remove removes an host -func (d *Driver) Remove() error { - if _, _, err := powershell.Execute(`Hyper-V\Get-VM`, d.MachineName, "-ErrorAction", "SilentlyContinue", "-ErrorVariable", "getVmErrors"); err != nil { - return nil - } - - s, err := d.GetState() - if err != nil { - return err - } - - if s == state.Running { - if err := d.Kill(); err != nil { - return err - } - } - - return cmd("Hyper-V\\Remove-VM", d.MachineName, "-Force") -} - -// Kill force stops an host -func (d *Driver) Kill() error { - if err := cmd("Hyper-V\\Stop-VM", d.MachineName, "-TurnOff"); err != nil { - return err - } - - if err := d.waitStopped(); err != nil { - return err - } - - d.IPAddress = "" - - return nil -} - -func (d *Driver) GetIP() (string, error) { - if d.VirtualSwitch == "" { - return "", errors.New("no virtual switch given") - } - - s, err := d.GetState() - if err != nil { - return "", err - } - if s != state.Running { - return "", drivers.ErrHostIsNotRunning - } - - stdout, err := cmdOut("((", "Hyper-V\\Get-VM", d.MachineName, ").networkadapters[0]).ipaddresses[0]") - if err != nil { - return "", err - } - - resp := crcstrings.FirstLine(stdout) - if resp == "" { - return "", fmt.Errorf("IP not found") - } - - return resp, nil -} - -func (d *Driver) GetSharedDirs() ([]drivers.SharedDir, error) { - for _, dir := range d.SharedDirs { - if !smbShareExists(dir.Tag) { - return []drivers.SharedDir{}, nil - } - } - return d.SharedDirs, nil -} diff --git a/pkg/drivers/libhvee/libhvee_windows.go b/pkg/drivers/libhvee/libhvee_windows.go new file mode 100644 index 0000000000..39a66b9175 --- /dev/null +++ b/pkg/drivers/libhvee/libhvee_windows.go @@ -0,0 +1,309 @@ +package libhvee + +import ( + "encoding/json" + "fmt" + "os" + "os/exec" + "strconv" + "strings" + + "github.com/containers/libhvee/pkg/hypervctl" + log "github.com/crc-org/crc/pkg/crc/logging" + crcos "github.com/crc-org/crc/pkg/os" + "github.com/crc-org/machine/libmachine/drivers" + "github.com/crc-org/machine/libmachine/state" +) + +type Driver struct { + *drivers.VMDriver + DynamicMemory bool +} + +const ( + defaultMemory = 8192 + defaultCPU = 4 + defaultDynamicMemory = false + systemGeneration = "Microsoft:Hyper-V:SubType:2" +) + +// NewDriver creates a new Hyper-v driver with default settings. +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + VMDriver: &drivers.VMDriver{ + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + Memory: defaultMemory, + CPU: defaultCPU, + }, + DynamicMemory: defaultDynamicMemory, + } +} + +func (d *Driver) UpdateConfigRaw(rawConfig []byte) error { + var update Driver + + err := json.Unmarshal(rawConfig, &update) + if err != nil { + return err + } + + if update.Memory != d.Memory { + log.Debugf("Machine: libhvee -> Updating memory from %d MB to %d MB", d.Memory, update.Memory) + + vm, err := d.getMachine() + if err != nil { + return err + } + + err = vm.UpdateProcessorMemSettings( + func(ps *hypervctl.ProcessorSettings) {}, + func(ms *hypervctl.MemorySettings) { + ms.VirtualQuantity = uint64(update.Memory) + ms.Limit = uint64(update.Memory) + }) + + if err != nil { + return err + } + } + + if update.CPU != d.CPU { + log.Debugf("Machine: libhvee -> Updating CPU count from %d to %d", d.CPU, update.CPU) + + vm, err := d.getMachine() + if err != nil { + return err + } + + err = vm.UpdateProcessorMemSettings( + func(ps *hypervctl.ProcessorSettings) { + ps.VirtualQuantity = uint64(update.CPU) + }, + func(ms *hypervctl.MemorySettings) {}) + + if err != nil { + return err + } + } + if update.DiskCapacity != d.DiskCapacity { + if err := d.resizeDisk(int64(update.DiskCapacity)); err != nil { + log.Warnf("Machine: libhvee -> Failed to set disk size to %d", update.DiskCapacity) + return err + } + } + *d = update + return nil +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "libhvee" +} + +func (d *Driver) GetState() (state.State, error) { + log.Debugf("Machine: libhvee -> state") + vm, err := d.getMachine() + if err != nil { + return state.Error, err + } + + log.Debugf("Machine: libhvee -> state: get") + vmState := vm.State() + switch vmState { + case hypervctl.Enabled: + log.Debugf("Machine: libhvee -> state: running") + return state.Running, nil + case hypervctl.Disabled: + log.Debugf("Machine: libhvee -> state: stopped") + return state.Stopped, nil + } + + log.Debugf("Machine: libhvee -> state: unknown") + return state.Error, fmt.Errorf("Unknown state") +} + +// PreCreateCheck checks that the machine creation process can be started safely. +func (d *Driver) PreCreateCheck() error { + // Check that powershell was found + if _, err := exec.LookPath("powershell.exe"); err != nil { + return ErrPowerShellNotFound + } + + // Check that hyperv is installed + if err := hypervAvailable(); err != nil { + return err + } + + // Check that the user is an Administrator + isAdmin, err := isAdministrator() + if err != nil { + return err + } + if !isAdmin { + return ErrNotAdministrator + } + + return nil +} + +func (d *Driver) Create() error { + log.Debugf("Machine: libhvee -> creating: system settings") + systemSettings, err := hypervctl.NewSystemSettingsBuilder(). + PrepareSystemSettings(d.MachineName, nil). + PrepareMemorySettings( + func(ms *hypervctl.MemorySettings) { + ms.DynamicMemoryEnabled = d.DynamicMemory + ms.VirtualQuantity = uint64(d.Memory) + ms.Reservation = 1024 + ms.Limit = uint64(d.Memory) + }). + PrepareProcessorSettings( + func(ps *hypervctl.ProcessorSettings) { + ps.VirtualQuantity = uint64(d.CPU) + }). + Build() + + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> creating: copy disk image") + diskPath := d.getDiskPath() + if err := crcos.CopyFile(d.ImageSourcePath, diskPath); err != nil { + return err + } + + log.Debugf("Machine: libhvee -> creating: hardware setup") + err = hypervctl.NewDriveSettingsBuilder(systemSettings). + AddScsiController(). + AddSyntheticDiskDrive(0). + DefineVirtualHardDisk(diskPath, + func(vhdss *hypervctl.VirtualHardDiskStorageSettings) {}). + Finish(). + Finish(). + Finish(). + Complete() + + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> creating: done") + + return nil +} + +func (d *Driver) getMachine() (*hypervctl.VirtualMachine, error) { + vmm := hypervctl.NewVirtualMachineManager() + + log.Debugf("Machine: libhvee -> get machine") + return vmm.GetMachine(d.MachineName) +} + +// Start starts an host +func (d *Driver) Start() error { + vm, err := d.getMachine() + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> start") + return vm.Start() +} + +// Stop stops an host +func (d *Driver) Stop() error { + vm, err := d.getMachine() + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> stop") + return vm.Stop() +} + +// Remove removes an host +func (d *Driver) Remove() error { + s, err := d.GetState() + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> remove running") + if s == state.Running { + if err := d.Kill(); err != nil { + return err + } + } + + vm, err := d.getMachine() + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> remove vm") + err = vm.Remove("") + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> remove disk file") + return os.Remove(d.getDiskPath()) +} + +// Kill force stops an host +func (d *Driver) Kill() error { + vm, err := d.getMachine() + if err != nil { + return err + } + + log.Debugf("Machine: libhvee -> stop with force") + return vm.StopWithForce() +} + +func (d *Driver) GetIP() (string, error) { + return "", fmt.Errorf("") +} + +func (d *Driver) GetSharedDirs() ([]drivers.SharedDir, error) { + for _, dir := range d.SharedDirs { + if !smbShareExists(dir.Tag) { + return []drivers.SharedDir{}, nil + } + } + return d.SharedDirs, nil +} + +func (d *Driver) getDiskPath() string { + return d.ResolveStorePath(fmt.Sprintf("%s.%s", d.MachineName, d.ImageFormat)) +} + +func (d *Driver) resizeDisk(newSize int64) error { + diskPath := d.getDiskPath() + out, err := cmdOut(fmt.Sprintf("@(Get-VHD -Path %s).Size", quote(diskPath))) + if err != nil { + return fmt.Errorf("unable to get current size of crc.vhdx: %w", err) + } + currentSize, err := strconv.ParseInt(strings.TrimSpace(out), 10, 64) + if err != nil { + return fmt.Errorf("unable to convert disk size to int: %w", err) + } + if newSize == currentSize { + log.Debugf("%s is already %d bytes", diskPath, newSize) + return nil + } + if newSize < currentSize { + return fmt.Errorf("current disk image capacity is bigger than the requested size (%d > %d)", currentSize, newSize) + } + + log.Debugf("Resizing disk from %d bytes to %d bytes", currentSize, newSize) + return cmd("Hyper-V\\Resize-VHD", + "-Path", + quote(diskPath), + "-SizeBytes", + fmt.Sprintf("%d", newSize)) +} diff --git a/pkg/drivers/hyperv/powershell_windows.go b/pkg/drivers/libhvee/powershell_windows.go similarity index 96% rename from pkg/drivers/hyperv/powershell_windows.go rename to pkg/drivers/libhvee/powershell_windows.go index 412cdada01..d146c7395c 100644 --- a/pkg/drivers/hyperv/powershell_windows.go +++ b/pkg/drivers/libhvee/powershell_windows.go @@ -1,4 +1,4 @@ -package hyperv +package libhvee import ( "errors" @@ -80,10 +80,6 @@ func quote(text string) string { return fmt.Sprintf("'%s'", text) } -func toMb(value int) string { - return fmt.Sprintf("%dMB", value) -} - func smbShareExists(name string) bool { if err := cmd(fmt.Sprintf("Get-SmbShare -Name %s", name)); err != nil { return false diff --git a/pkg/libmachine/load_windows.go b/pkg/libmachine/load_windows.go index f25cb2dced..5066e2dd9b 100644 --- a/pkg/libmachine/load_windows.go +++ b/pkg/libmachine/load_windows.go @@ -3,12 +3,12 @@ package libmachine import ( "encoding/json" - "github.com/crc-org/crc/pkg/drivers/hyperv" + "github.com/crc-org/crc/pkg/drivers/libhvee" "github.com/crc-org/crc/pkg/libmachine/host" ) func (api *Client) NewHost(_ string, driverPath string, rawDriver []byte) (*host.Host, error) { - driver := hyperv.NewDriver("", "") + driver := libhvee.NewDriver("", "") if err := json.Unmarshal(rawDriver, &driver); err != nil { return nil, err } @@ -29,7 +29,7 @@ func (api *Client) Load(name string) (*host.Host, error) { return nil, err } - driver := hyperv.NewDriver("", "") + driver := libhvee.NewDriver("", "") if err := json.Unmarshal(h.RawDriver, &driver); err != nil { return nil, err } diff --git a/vendor/github.com/containers/libhvee/LICENSE b/vendor/github.com/containers/libhvee/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/github.com/containers/libhvee/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/diskdrive_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/diskdrive_settings.go new file mode 100644 index 0000000000..c493b1a8f2 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/diskdrive_settings.go @@ -0,0 +1,72 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "github.com/containers/libhvee/pkg/wmiext" +) + +const SyntheticDiskDriveType = "Microsoft:Hyper-V:Synthetic Disk Drive" + +type SyntheticDiskDriveSettings struct { + ResourceSettings + systemSettings *SystemSettings + controllerSettings *ScsiControllerSettings +} + +type diskAssociation interface { + setParent(parent string) + setHostResource(resource []string) + Path() string +} + +func (d *SyntheticDiskDriveSettings) DefineVirtualHardDisk(vhdxFile string, beforeAdd func(*VirtualHardDiskStorageSettings)) (*VirtualHardDiskStorageSettings, error) { + vhd := &VirtualHardDiskStorageSettings{} + + var cb func() + if beforeAdd != nil { + cb = func() { + beforeAdd(vhd) + } + } + + if err := createDiskResourceInternal(d.systemSettings.Path(), d.Path(), vhdxFile, vhd, VirtualHardDiskType, cb); err != nil { + return nil, err + } + + vhd.driveSettings = d + vhd.systemSettings = d.systemSettings + return vhd, nil +} + +func createDiskResourceInternal(systemPath string, drivePath string, file string, settings diskAssociation, resourceType string, cb func()) error { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + if err = populateDefaults(resourceType, settings); err != nil { + return err + } + + settings.setHostResource([]string{file}) + settings.setParent(drivePath) + if cb != nil { + cb() + } + + diskResource, err := createResourceSettingGeneric(settings, resourceType) + if err != nil { + return err + } + + path, err := addResource(service, systemPath, diskResource) + if err != nil { + return err + } + + return service.GetObjectAsObject(path, settings) +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/drive_settings_builder.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/drive_settings_builder.go new file mode 100644 index 0000000000..21d67478c3 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/drive_settings_builder.go @@ -0,0 +1,186 @@ +//go:build windows +// +build windows + +package hypervctl + +type DriveSettingsBuilder struct { + systemSettings *SystemSettings + err error +} + +type ControllerSettingsBuilder struct { + driveSettingsBuilder DriveSettingsBuilder + controllerSettings *ScsiControllerSettings + err error +} + +type SyntheticDiskDriveSettingsBuilder struct { + controllerBuilder *ControllerSettingsBuilder + driveSettings *SyntheticDiskDriveSettings + err error +} + +type SyntheticDvdDriveSettingsBuilder struct { + controllerBuilder *ControllerSettingsBuilder + driveSettings *SyntheticDvdDriveSettings + err error +} + +type VirtualHardDiskStorageSettingsBuilder struct { + driveBuilder *SyntheticDiskDriveSettingsBuilder + diskSettings *VirtualHardDiskStorageSettings + err error +} + +type VirtualDvdDiskStorageSettingsBuilder struct { + driveBuilder *SyntheticDvdDriveSettingsBuilder + diskSettings *VirtualDvdDiskStorageSettings + err error +} + +func NewDriveSettingsBuilder(systemSettings *SystemSettings) *DriveSettingsBuilder { + return &DriveSettingsBuilder{systemSettings: systemSettings} +} + +func (builder *DriveSettingsBuilder) AddScsiController() *ControllerSettingsBuilder { + if builder.err != nil { + return &ControllerSettingsBuilder{driveSettingsBuilder: *builder, err: builder.err} + } + + controllerSettings, err := builder.systemSettings.AddScsiController() + builder.setErr(err) + + return &ControllerSettingsBuilder{ + driveSettingsBuilder: *builder, + controllerSettings: controllerSettings, + err: err, + } +} + +func (builder *ControllerSettingsBuilder) AddSyntheticDiskDrive(slot uint) *SyntheticDiskDriveSettingsBuilder { + if builder.err != nil { + return &SyntheticDiskDriveSettingsBuilder{controllerBuilder: builder, err: builder.err} + } + + driveSettings, err := builder.controllerSettings.AddSyntheticDiskDrive(slot) + builder.setErr(err) + + return &SyntheticDiskDriveSettingsBuilder{ + controllerBuilder: builder, + driveSettings: driveSettings, + err: err, + } +} + +func (builder *ControllerSettingsBuilder) AddSyntheticDvdDrive(slot uint) *SyntheticDvdDriveSettingsBuilder { + if builder.err != nil { + return &SyntheticDvdDriveSettingsBuilder{controllerBuilder: builder, err: builder.err} + } + + driveSettings, err := builder.controllerSettings.AddSyntheticDvdDrive(slot) + builder.setErr(err) + + return &SyntheticDvdDriveSettingsBuilder{ + controllerBuilder: builder, + driveSettings: driveSettings, + err: err, + } +} + +func (builder *SyntheticDiskDriveSettingsBuilder) DefineVirtualHardDisk(vhdxFile string, beforeAdd func(*VirtualHardDiskStorageSettings)) *VirtualHardDiskStorageSettingsBuilder { + if builder.err != nil { + return &VirtualHardDiskStorageSettingsBuilder{driveBuilder: builder, err: builder.err} + } + + diskSettings, err := builder.driveSettings.DefineVirtualHardDisk(vhdxFile, beforeAdd) + builder.setErr(err) + + return &VirtualHardDiskStorageSettingsBuilder{ + driveBuilder: builder, + diskSettings: diskSettings, + err: err, + } +} + +func (builder *SyntheticDvdDriveSettingsBuilder) DefineVirtualDvdDisk(imageFile string) *VirtualDvdDiskStorageSettingsBuilder { + if builder.err != nil { + return &VirtualDvdDiskStorageSettingsBuilder{driveBuilder: builder, err: builder.err} + } + + diskSettings, err := builder.driveSettings.DefineVirtualDvdDisk(imageFile) + builder.setErr(err) + + return &VirtualDvdDiskStorageSettingsBuilder{ + driveBuilder: builder, + diskSettings: diskSettings, + err: err, + } +} + +func (builder *SyntheticDvdDriveSettingsBuilder) setErr(err error) { + builder.err = err + builder.controllerBuilder.setErr(err) +} + +func (builder *SyntheticDiskDriveSettingsBuilder) setErr(err error) { + builder.err = err + builder.controllerBuilder.setErr(err) +} + +func (builder *ControllerSettingsBuilder) setErr(err error) { + builder.err = err + builder.driveSettingsBuilder.setErr(err) +} + +func (builder *DriveSettingsBuilder) setErr(err error) { + builder.err = err +} + +func (builder *ControllerSettingsBuilder) Finish() *DriveSettingsBuilder { + return &builder.driveSettingsBuilder +} + +func (builder *VirtualHardDiskStorageSettingsBuilder) Finish() *SyntheticDiskDriveSettingsBuilder { + return builder.driveBuilder +} + +func (builder *VirtualDvdDiskStorageSettingsBuilder) Finish() *SyntheticDvdDriveSettingsBuilder { + return builder.driveBuilder +} + +func (builder *SyntheticDiskDriveSettingsBuilder) Finish() *ControllerSettingsBuilder { + return builder.controllerBuilder +} + +func (builder *SyntheticDvdDriveSettingsBuilder) Finish() *ControllerSettingsBuilder { + return builder.controllerBuilder +} + +func (builder *VirtualHardDiskStorageSettingsBuilder) Get(s **VirtualHardDiskStorageSettings) *VirtualHardDiskStorageSettingsBuilder { + *s = builder.diskSettings + return builder +} + +func (builder *VirtualDvdDiskStorageSettingsBuilder) Get(s **VirtualDvdDiskStorageSettings) *VirtualDvdDiskStorageSettingsBuilder { + *s = builder.diskSettings + return builder +} + +func (builder *SyntheticDiskDriveSettingsBuilder) Get(s **SyntheticDiskDriveSettings) *SyntheticDiskDriveSettingsBuilder { + *s = builder.driveSettings + return builder +} + +func (builder *SyntheticDvdDriveSettingsBuilder) Get(s **SyntheticDvdDriveSettings) *SyntheticDvdDriveSettingsBuilder { + *s = builder.driveSettings + return builder +} + +func (builder *ControllerSettingsBuilder) Get(s **ScsiControllerSettings) *ControllerSettingsBuilder { + *s = builder.controllerSettings + return builder +} + +func (builder *DriveSettingsBuilder) Complete() error { + return builder.err +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/dvddrive_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/dvddrive_settings.go new file mode 100644 index 0000000000..2f66163a27 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/dvddrive_settings.go @@ -0,0 +1,24 @@ +//go:build windows +// +build windows + +package hypervctl + +const SyntheticDvdDriveType = "Microsoft:Hyper-V:Synthetic DVD Drive" + +type SyntheticDvdDriveSettings struct { + ResourceSettings + systemSettings *SystemSettings + controllerSettings *ScsiControllerSettings +} + +func (d *SyntheticDvdDriveSettings) DefineVirtualDvdDisk(imageFile string) (*VirtualDvdDiskStorageSettings, error) { + vdvd := &VirtualDvdDiskStorageSettings{} + + if err := createDiskResourceInternal(d.systemSettings.Path(), d.Path(), imageFile, vdvd, VirtualDvdDiskType, nil); err != nil { + return nil, err + } + + vdvd.driveSettings = d + vdvd.systemSettings = d.systemSettings + return vdvd, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/error.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/error.go new file mode 100644 index 0000000000..7fe985d979 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/error.go @@ -0,0 +1,157 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "errors" + "fmt" +) + +// VM State errors +var ( + ErrMachineAlreadyRunning = errors.New("machine already running") + ErrMachineNotRunning = errors.New("machine not running") + ErrMachineStateInvalid = errors.New("machine in invalid state for action") + ErrMachineStarting = errors.New("machine is currently starting") +) + +// VM Creation errors +var ( + ErrMachineAlreadyExists = errors.New("machine already exists") +) + +type DestroySystemResult int32 + +// VM Destroy Exit Codes +const ( + VMDestroyCompletedwithNoError DestroySystemResult = 0 + VMDestroyNotSupported DestroySystemResult = 1 + VMDestroyFailed DestroySystemResult = 2 + VMDestroyTimeout DestroySystemResult = 3 + VMDestroyInvalidParameter DestroySystemResult = 4 + VMDestroyInvalidState DestroySystemResult = 5 +) + +func (e DestroySystemResult) Reason() string { + switch e { + case VMDestroyNotSupported: + return "not supported" + case VMDestroyFailed: + return "failed" + case VMDestroyTimeout: + return "timeout" + case VMDestroyInvalidParameter: + return "invalid parameter" + case VMDestroyInvalidState: + return "invalid state" + } + return "Unknown" +} + +// Shutdown operation error codes +const ( + ErrShutdownFailed = 32768 + ErrShutdownAccessDenied = 32769 + ErrShutdownNotSupported = 32770 + ErrShutdownStatusUnkown = 32771 + ErrShutdownTimeout = 32772 + ErrShutdownInvalidParameter = 32773 + ErrShutdownSystemInUse = 32774 + ErrShutdownInvalidState = 32775 + ErrShutdownIncorrectData = 32776 + ErrShutdownNotAvailable = 32777 + ErrShutdownOutOfMemory = 32778 + ErrShutdownFileNotFound = 32779 + ErrShutdownNotReady = 32780 + ErrShutdownMachineLocked = 32781 + ErrShutdownInProgress = 32782 +) + +type shutdownCompError struct { + errorCode int + message string +} + +func (s *shutdownCompError) Error() string { + return fmt.Sprintf("%s (%d)", s.message, s.errorCode) +} + +func translateShutdownError(code int) error { + var message string + switch code { + case ErrShutdownFailed: + message = "shutdown failed" + case ErrShutdownAccessDenied: + message = "access was denied" + case ErrShutdownNotSupported: + message = "shutdown not supported by virtual machine" + case ErrShutdownStatusUnkown: + message = "virtual machine status is unknown" + case ErrShutdownTimeout: + message = "timeout starting shutdown" + case ErrShutdownInvalidParameter: + message = "invalid parameter" + case ErrShutdownSystemInUse: + message = "system in use" + case ErrShutdownInvalidState: + message = "virtual machine is in an invalid state for shutdown" + case ErrShutdownIncorrectData: + message = "incorrect data type" + case ErrShutdownNotAvailable: + message = "system is not available" + case ErrShutdownOutOfMemory: + message = "out of memory" + case ErrShutdownFileNotFound: + message = "file not found" + case ErrShutdownMachineLocked: + message = "machine is locked and cannot be shut down without the force option" + case ErrShutdownInProgress: + message = "shutdown is already in progress" + default: + message = "unknown error" + } + + return &shutdownCompError{code, message} +} + +// Modify resource errors +const ( + ErrModifyResourceNotSupported = 1 + ErrModifyResourceFailed = 2 + ErrModifyResourceTimeout = 3 + ErrModifyResourceInvalidParameter = 4 + ErrModifyResourceInvalidState = 5 + ErrModifyResourceIncompatParam = 6 +) + +type modifyResourceError struct { + errorCode int + message string +} + +func (m *modifyResourceError) Error() string { + return fmt.Sprintf("%s (%d)", m.message, m.errorCode) +} + +func translateModifyError(code int) error { + var message string + switch code { + case ErrModifyResourceNotSupported: + message = "virtual machine does not support modification operations" + case ErrModifyResourceFailed: + message = "resource modification failed" + case ErrModifyResourceTimeout: + message = "timeout modifying resource" + case ErrModifyResourceInvalidParameter: + message = "a modify resource operation was passed an invalid parameter" + case ErrModifyResourceInvalidState: + message = "the requested modification could not be applied due to an invalid state" + case ErrModifyResourceIncompatParam: + message = "an incompatible parameter was passed to a modify resource operation" + default: + message = "unknown error" + } + + return &modifyResourceError{code, message} +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_alloc_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_alloc_settings.go new file mode 100644 index 0000000000..9cdb644954 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_alloc_settings.go @@ -0,0 +1,50 @@ +//go:build windows +// +build windows + +package hypervctl + +const EthernetPortAllocationResourceType = "Microsoft:Hyper-V:Ethernet Connection" + +type EthernetPortAllocationSettings struct { + InstanceID string // = "Microsoft:GUID\DeviceSpecificData" + Caption string // = "Ethernet Switch Port Settings" + Description string // = "Ethernet Switch Port Settings" + ElementName string + ResourceType uint16 // = 33 + OtherResourceType string + ResourceSubType string + PoolID string + ConsumerVisibility uint16 // = 3 + HostResource []string + AllocationUnits string + VirtualQuantity uint64 + Reservation uint64 + Limit uint64 + Weight uint32 // = 0 + AutomaticAllocation bool + AutomaticDeallocation bool + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualQuantityUnits string // = "count" + DesiredVLANEndpointMode uint16 + OtherEndpointMode string + EnabledState uint16 + LastKnownSwitchName string + RequiredFeatures []string + RequiredFeatureHints []string + TestReplicaPoolID string + TestReplicaSwitchName string + CompartmentGuid string +} + +func fetchEthernetPortAllocationSettings() (*EthernetPortAllocationSettings, error) { + settings := &EthernetPortAllocationSettings{} + return settings, populateDefaults(EthernetPortAllocationResourceType, settings) +} + +func creatEthernetPortAllocationSettings(settings *EthernetPortAllocationSettings) (string, error) { + return createResourceSettingGeneric(settings, EthernetPortAllocationResourceType) +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_port_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_port_settings.go new file mode 100644 index 0000000000..f1d8930d89 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/ethernet_port_settings.go @@ -0,0 +1,109 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "fmt" + + "github.com/containers/libhvee/pkg/wmiext" +) + +const SyntheticEthernetPortResourceType = "Microsoft:Hyper-V:Synthetic Ethernet Port" +const DefaultSwitchId = "C08CB7B8-9B3C-408E-8E30-5E16A3AEB444" + +type SyntheticEthernetPortSettings struct { + S__PATH string + InstanceID string + Caption string // = "Virtual Ethernet Port Default Settings" + Description string // = "Describes the default settings for the virtual Ethernet port resources." + ElementName string + ResourceType uint16 // = 10 + OtherResourceType string + ResourceSubType string // = "Microsoft:Hyper-V:Synthetic Ethernet Port" + PoolID string + ConsumerVisibility uint16 // = 3 + HostResource []string + AllocationUnits string // = "count" + VirtualQuantity uint64 // = 1 + Reservation uint64 // = 1 + Limit uint64 // = 1 + Weight uint32 // = 0 + AutomaticAllocation bool // = True + AutomaticDeallocation bool // = True + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualQuantityUnits string // = "count" + DesiredVLANEndpointMode uint16 + OtherEndpointMode string + VirtualSystemIdentifiers []string + DeviceNamingEnabled bool // = FALSE + AllowPacketDirect bool // = FALSE + StaticMacAddress bool // = False + ClusterMonitored bool // = TRUE + + systemSettings *SystemSettings +} + +func (p *SyntheticEthernetPortSettings) Path() string { + return p.S__PATH +} + +func (p *SyntheticEthernetPortSettings) DefineEthernetPortConnection(switchName string) (*EthernetPortAllocationSettings, error) { + const wqlFormat = "select * from Msvm_VirtualEthernetSwitch where %s = '%s'" + + var wqlProperty, wqlValue string + if len(switchName) > 0 { + wqlProperty = "ElementName" + wqlValue = switchName + } else { + wqlProperty = "Name" + wqlValue = DefaultSwitchId + } + + wql := fmt.Sprintf(wqlFormat, wqlProperty, wqlValue) + + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return nil, err + } + defer service.Close() + + switchInst, err := service.FindFirstInstance(wql) + if err != nil { + return nil, err + } + defer switchInst.Close() + switchPath, err := switchInst.Path() + if err != nil { + return nil, err + } + + connectSettings, err := fetchEthernetPortAllocationSettings() + if err != nil { + return nil, err + } + + connectSettings.Parent = p.Path() + connectSettings.HostResource = append(connectSettings.HostResource, switchPath) + + resource, err := creatEthernetPortAllocationSettings(connectSettings) + if err != nil { + return nil, err + } + + path, err := addResource(service, p.systemSettings.Path(), resource) + if err != nil { + return nil, err + } + + if err := service.GetObjectAsObject(path, connectSettings); err != nil { + return nil, err + } + + return connectSettings, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/kvp.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/kvp.go new file mode 100644 index 0000000000..04bed34298 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/kvp.go @@ -0,0 +1,138 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "encoding/xml" + "fmt" + "io" + "strings" + + "github.com/containers/libhvee/pkg/wmiext" +) + +const ( + KvpOperationFailed = 32768 + KvpAccessDenied = 32769 + KvpNotSupported = 32770 + KvpStatusUnknown = 32771 + KvpTimeoutOccurred = 32772 + KvpIllegalArgument = 32773 + KvpSystemInUse = 32774 + KvpInvalidState = 32775 + KvpIncorrectDataType = 32776 + KvpSystemNotAvailable = 32777 + KvpOutOfMemory = 32778 + KvpNotFound = 32779 + + KvpExchangeDataItemName = "Msvm_KvpExchangeDataItem" + MemorySettingDataName = "Msvm_MemorySettingData" +) + +type CimKvpItems struct { + Instances []CimKvpItem `xml:"INSTANCE"` +} + +type CimKvpItem struct { + Properties []CimKvpItemProperty `xml:"PROPERTY"` +} + +type CimKvpItemProperty struct { + Name string `xml:"NAME,attr"` + Value string `xml:"VALUE"` +} + +type KvpError struct { + ErrorCode int + message string +} + +func (k *KvpError) Error() string { + return fmt.Sprintf("%s (%d)", k.message, k.ErrorCode) +} + +func createKvpItem(service *wmiext.Service, key string, value string) (string, error) { + item, err := service.SpawnInstance(KvpExchangeDataItemName) + if err != nil { + return "", err + } + defer item.Close() + + _ = item.Put("Name", key) + _ = item.Put("Data", value) + _ = item.Put("Source", 0) + itemStr := item.GetCimText() + return itemStr, nil +} + +func parseKvpMapXml(kvpXml string) (map[string]string, error) { + // Workaround XML decoder's inability to handle multiple root elements + r := io.MultiReader( + strings.NewReader(""), + strings.NewReader(kvpXml), + strings.NewReader(""), + ) + + var items CimKvpItems + if err := xml.NewDecoder(r).Decode(&items); err != nil { + return nil, err + } + + ret := make(map[string]string) + for _, item := range items.Instances { + var key, value string + for _, prop := range item.Properties { + if strings.EqualFold(prop.Name, "Name") { + key = prop.Value + } else if strings.EqualFold(prop.Name, "Data") { + value = prop.Value + } + } + if len(key) > 0 { + ret[key] = value + } + } + + return ret, nil +} + +func translateKvpError(source error, illegalSuggestion string) error { + j, ok := source.(*wmiext.JobError) + + if !ok { + return source + } + + var message string + switch j.ErrorCode { + case KvpOperationFailed: + message = "Operation failed" + case KvpAccessDenied: + message = "Access denied" + case KvpNotSupported: + message = "Not supported" + case KvpStatusUnknown: + message = "Status is unknown" + case KvpTimeoutOccurred: + message = "Timeout occurred" + case KvpIllegalArgument: + message = "Illegal argument (" + illegalSuggestion + ")" + case KvpSystemInUse: + message = "System is in use" + case KvpInvalidState: + message = "Invalid state for this operation" + case KvpIncorrectDataType: + message = "Incorrect data type" + case KvpSystemNotAvailable: + message = "System is not available" + case KvpOutOfMemory: + message = "Out of memory" + case KvpNotFound: + message = "Not found" + default: + return source + } + + return &KvpError{j.ErrorCode, message} +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/memory_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/memory_settings.go new file mode 100644 index 0000000000..960694eb70 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/memory_settings.go @@ -0,0 +1,56 @@ +//go:build windows +// +build windows + +package hypervctl + +import "fmt" + +const MemoryResourceType = "Microsoft:Hyper-V:Memory" + +type MemorySettings struct { + S__PATH string + InstanceID string + Caption string // = "Memory Default Settings" + Description string // = "Describes the default settings for the memory resources." + ElementName string + ResourceType uint16 // = 4 + OtherResourceType string + ResourceSubType string // = "Microsoft:Hyper-V:Memory" + PoolID string + ConsumerVisibility uint16 + HostResource []string + HugePagesEnabled bool + AllocationUnits string // = "byte * 2^20" + VirtualQuantity uint64 + Reservation uint64 + Limit uint64 + Weight uint32 + AutomaticAllocation bool // = True + AutomaticDeallocation bool // = True + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualQuantityUnits string // = "byte * 2^20" + DynamicMemoryEnabled bool + TargetMemoryBuffer uint32 + IsVirtualized bool // = True + SwapFilesInUse bool + MaxMemoryBlocksPerNumaNode uint64 + SgxSize uint64 + SgxEnabled bool +} + +func createMemorySettings(settings *MemorySettings) (string, error) { + str, err := createResourceSettingGeneric(settings, MemoryResourceType) + if err != nil { + err = fmt.Errorf("could not create memory settings: %w", err) + } + return str, err +} + +func fetchDefaultMemorySettings() (*MemorySettings, error) { + settings := &MemorySettings{} + return settings, populateDefaults(MemoryResourceType, settings) +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/network_settings_builder.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/network_settings_builder.go new file mode 100644 index 0000000000..ed5abd6371 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/network_settings_builder.go @@ -0,0 +1,86 @@ +//go:build windows +// +build windows + +package hypervctl + +type NetworkSettingsBuilder struct { + systemSettings *SystemSettings + err error +} + +type SyntheticEthernetPortSettingsBuilder struct { + networkSettingsBuilder *NetworkSettingsBuilder + portSettings *SyntheticEthernetPortSettings + err error +} + +type EthernetPortAllocationSettingsBuilder struct { + portSettingsBuilder *SyntheticEthernetPortSettingsBuilder + allocSettings *EthernetPortAllocationSettings + err error +} + +func NewNetworkSettingsBuilder(systemSettings *SystemSettings) *NetworkSettingsBuilder { + return &NetworkSettingsBuilder{systemSettings: systemSettings} +} + +func (builder *NetworkSettingsBuilder) AddSyntheticEthernetPort(beforeAdd func(*SyntheticEthernetPortSettings)) *SyntheticEthernetPortSettingsBuilder { + if builder.err != nil { + return &SyntheticEthernetPortSettingsBuilder{networkSettingsBuilder: builder, err: builder.err} + } + + portSettings, err := builder.systemSettings.AddSyntheticEthernetPort(beforeAdd) + builder.setErr(err) + + return &SyntheticEthernetPortSettingsBuilder{ + networkSettingsBuilder: builder, + portSettings: portSettings, + err: err, + } +} + +func (builder *SyntheticEthernetPortSettingsBuilder) AddEthernetPortAllocation(switchName string) *EthernetPortAllocationSettingsBuilder { + if builder.err != nil { + return &EthernetPortAllocationSettingsBuilder{portSettingsBuilder: builder, err: builder.err} + } + + allocSettings, err := builder.portSettings.DefineEthernetPortConnection(switchName) + builder.setErr(err) + + return &EthernetPortAllocationSettingsBuilder{ + portSettingsBuilder: builder, + allocSettings: allocSettings, + err: err, + } +} + +func (builder *SyntheticEthernetPortSettingsBuilder) Finish() *NetworkSettingsBuilder { + return builder.networkSettingsBuilder +} + +func (builder *EthernetPortAllocationSettingsBuilder) Finish() *SyntheticEthernetPortSettingsBuilder { + return builder.portSettingsBuilder +} + +func (builder *NetworkSettingsBuilder) setErr(err error) { + builder.err = err +} + +func (builder *SyntheticEthernetPortSettingsBuilder) setErr(err error) { + builder.err = err + builder.networkSettingsBuilder.setErr(err) +} + +func (builder *EthernetPortAllocationSettingsBuilder) Get(s **EthernetPortAllocationSettings) *EthernetPortAllocationSettingsBuilder { + *s = builder.allocSettings + return builder +} + +func (builder *SyntheticEthernetPortSettingsBuilder) Get(s **SyntheticEthernetPortSettings) *SyntheticEthernetPortSettingsBuilder { + *s = builder.portSettings + return builder +} + +func (builder *NetworkSettingsBuilder) Complete() error { + return builder.err +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/processor_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/processor_settings.go new file mode 100644 index 0000000000..9c0d6d95e8 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/processor_settings.go @@ -0,0 +1,98 @@ +//go:build windows +// +build windows + +package hypervctl + +import "fmt" + +const ProcessorResourceType = "Microsoft:Hyper-V:Processor" + +/* +AllocationUnits : percent / 1000 +AllowACountMCount : True +AutomaticAllocation : True +AutomaticDeallocation : True +Caption : Processor +Connection : +ConsumerVisibility : 3 +CpuGroupId : 00000000-0000-0000-0000-000000000000 +Description : Settings for Microsoft Virtual Processor. +DisableSpeculationControls : False +ElementName : Processor +EnableHostResourceProtection : False +EnableLegacyApicMode : False +EnablePageShattering : 0 +EnablePerfmonIpt : False +EnablePerfmonLbr : False +EnablePerfmonPebs : False +EnablePerfmonPmu : False +ExposeVirtualizationExtensions : False +HideHypervisorPresent : False +HostResource : +HwThreadsPerCore : 0 +InstanceID : Microsoft:B5314955-3924-42BA-ABF9-793993D340A0\b637f346-6a0e-4dec-af52-bd70cb80a21d\0 +Limit : 100000 +LimitCPUID : False +LimitProcessorFeatures : False +MappingBehavior : +MaxNumaNodesPerSocket : 1 +MaxProcessorsPerNumaNode : 4 +OtherResourceType : +Parent : +PoolID : +Reservation : 0 +ResourceSubType : Microsoft:Hyper-V:Processor +ResourceType : 3 +VirtualQuantity : 2 +VirtualQuantityUnits : count +Weight : 100 +*/ + +type ProcessorSettings struct { + S__PATH string + InstanceID string + Caption string // = "Processor" + Description string // = "A logical processor of the hypervisor running on the host computer system." + ElementName string + ResourceType uint16 // = 3 + OtherResourceType string + ResourceSubType string // = "Microsoft:Hyper-V:Processor" + PoolID string + ConsumerVisibility uint16 + HostResource []string + AllocationUnits string // = "percent / 1000" + VirtualQuantity uint64 // = "count" + Reservation uint64 // = 0 + Limit uint64 // = 100000 + Weight uint32 // = 100 + AutomaticAllocation bool // = True + AutomaticDeallocation bool // = True + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualQuantityUnits string // = "count" + LimitCPUID bool + HwThreadsPerCore uint64 + LimitProcessorFeatures bool + MaxProcessorsPerNumaNode uint64 + MaxNumaNodesPerSocket uint64 + EnableHostResourceProtection bool + CpuGroupId string + HideHypervisorPresent bool + ExposeVirtualizationExtensions bool +} + +func fetchDefaultProcessorSettings() (*ProcessorSettings, error) { + settings := &ProcessorSettings{} + return settings, populateDefaults(ProcessorResourceType, settings) +} + +func createProcessorSettings(settings *ProcessorSettings) (string, error) { + str, err := createResourceSettingGeneric(settings, ProcessorResourceType) + if err != nil { + err = fmt.Errorf("could not create processor settings: %w", err) + } + return str, err +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/resources_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/resources_settings.go new file mode 100644 index 0000000000..c229121339 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/resources_settings.go @@ -0,0 +1,135 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "errors" + "fmt" + + "github.com/containers/libhvee/pkg/wmiext" +) + +type ResourceSettings struct { + S__PATH string + InstanceID string // = "Microsoft:GUID\DeviceSpecificData" + Caption string + Description string + ElementName string + ResourceType uint16 + OtherResourceType string + ResourceSubType string + PoolID string + ConsumerVisibility uint16 + HostResource []string + AllocationUnits string + VirtualQuantity uint64 + Reservation uint64 + Limit uint64 + Weight uint32 + AutomaticAllocation bool + AutomaticDeallocation bool + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualQuantityUnits string // = "count" + VirtualSystemIdentifiers []string // = { "GUID" } +} + +func (s *ResourceSettings) setParent(parent string) { + s.Parent = parent +} + +func (s *ResourceSettings) setAddressOnParent(address string) { + s.AddressOnParent = address +} + +func (s *ResourceSettings) Path() string { + return s.S__PATH +} + +func createResourceSettingGeneric(settings interface{}, resourceType string) (string, error) { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return "", err + } + + ref, err := findResourceDefaults(service, resourceType) + if err != nil { + return "", err + } + + resource, err := service.GetObject(ref) + if err != nil { + return "", err + } + + defer resource.Close() + resource, err = resource.CloneInstance() + if err != nil { + return "", err + } + defer resource.Close() + + if err = resource.PutAll(settings); err != nil { + return "", err + } + + return resource.GetCimText(), nil +} + +func populateDefaults(subType string, settings interface{}) error { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + ref, err := findResourceDefaults(service, subType) + if err != nil { + return err + } + + return service.GetObjectAsObject(ref, settings) +} + +func findResourceDefaults(service *wmiext.Service, subType string) (string, error) { + wql := fmt.Sprintf("SELECT * FROM Msvm_AllocationCapabilities WHERE ResourceSubType = '%s'", subType) + instance, err := service.FindFirstInstance(wql) + if err != nil { + return "", err + } + defer instance.Close() + + path, err := instance.Path() + if err != nil { + return "", err + } + + enum, err := service.ExecQuery(fmt.Sprintf("references of {%s} where ResultClass = Msvm_SettingsDefineCapabilities", path)) + if err != nil { + return "", err + } + defer enum.Close() + + for { + entry, err := enum.Next() + if err != nil { + return "", err + } + if entry == nil { + return "", errors.New("could not find settings definition for resource") + } + + value, vErr := entry.GetAsUint("ValueRole") + ref, pErr := entry.GetAsString("PartComponent") + entry.Close() + if vErr == nil && pErr == nil && value == 0 { + return ref, nil + } + } +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/scsi_controller.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/scsi_controller.go new file mode 100644 index 0000000000..b9a2e2cdcf --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/scsi_controller.go @@ -0,0 +1,69 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "fmt" + + "github.com/containers/libhvee/pkg/wmiext" +) + +type ScsiControllerSettings struct { + ResourceSettings + systemSettings *SystemSettings +} + +type driveAssociation interface { + setParent(parent string) + setAddressOnParent(address string) +} + +func (c *ScsiControllerSettings) AddSyntheticDiskDrive(slot uint) (*SyntheticDiskDriveSettings, error) { + drive := &SyntheticDiskDriveSettings{} + if err := c.createSyntheticDriveInternal(slot, drive, SyntheticDiskDriveType); err != nil { + return nil, err + } + drive.systemSettings = c.systemSettings + drive.controllerSettings = c + return drive, nil +} + +func (c *ScsiControllerSettings) AddSyntheticDvdDrive(slot uint) (*SyntheticDvdDriveSettings, error) { + drive := &SyntheticDvdDriveSettings{} + if err := c.createSyntheticDriveInternal(slot, drive, SyntheticDvdDriveType); err != nil { + return nil, err + } + drive.systemSettings = c.systemSettings + drive.controllerSettings = c + return drive, nil +} + +func (c *ScsiControllerSettings) createSyntheticDriveInternal(slot uint, settings driveAssociation, resourceType string) error { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + if err = populateDefaults(resourceType, settings); err != nil { + return err + } + + settings.setParent(c.Path()) + settings.setAddressOnParent(fmt.Sprintf("%d", slot)) + + driveResource, err := createResourceSettingGeneric(settings, resourceType) + if err != nil { + return err + } + + path, err := addResource(service, c.systemSettings.Path(), driveResource) + if err != nil { + return err + } + + err = service.GetObjectAsObject(path, settings) + return err +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/storage_alloc_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/storage_alloc_settings.go new file mode 100644 index 0000000000..e6baa54301 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/storage_alloc_settings.go @@ -0,0 +1,61 @@ +//go:build windows +// +build windows + +package hypervctl + +type StorageAllocationSettings struct { + S__PATH string + InstanceID string + Caption string // = "Hard Disk Image Default Settings" + Description string // = "Describes the default settings for the hard disk image resources" + ElementName string + ResourceType uint16 + OtherResourceType string + ResourceSubType string + PoolID string + ConsumerVisibility uint16 + HostResource []string + AllocationUnits string + VirtualQuantity uint64 + Limit uint64 // = 1 + Weight uint32 + StorageQoSPolicyID string + AutomaticAllocation bool + AutomaticDeallocation bool + Parent string + Connection []string + Address string + MappingBehavior uint16 + AddressOnParent string + VirtualResourceBlockSize uint64 + VirtualQuantityUnits string // = "count(fixed size block)" + Access uint16 + HostResourceBlockSize uint64 + Reservation uint64 + HostExtentStartingAddress uint64 + HostExtentName string + HostExtentNameFormat uint16 + OtherHostExtentNameFormat string + HostExtentNameNamespace uint16 + OtherHostExtentNameNamespace string + IOPSLimit uint64 + IOPSReservation uint64 + IOPSAllocationUnits string + PersistentReservationsSupported bool + CachingMode uint16 + SnapshotId string // = "" + IgnoreFlushes bool + WriteHardeningMethod uint16 +} + +func (s *StorageAllocationSettings) setParent(parent string) { + s.Parent = parent +} + +func (s *StorageAllocationSettings) setHostResource(resource []string) { + s.HostResource = resource +} + +func (s *StorageAllocationSettings) Path() string { + return s.S__PATH +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/summary.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/summary.go new file mode 100644 index 0000000000..c8abcef1b0 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/summary.go @@ -0,0 +1,202 @@ +//go:build windows +// +build windows + +package hypervctl + +import "time" + +const ( + SummaryRequestName = 0 + SummaryRequestElementName = 1 + SummaryRequestCreationTime = 2 + SummaryRequestNotes = 3 + SummaryRequestProcessors = 4 + SummaryRequestSmallThumbnail = 5 + SummaryRequestMediumThumbnail = 6 + SummaryRequestLargeThumbnail = 7 + SummaryRequestAllocatedGPU = 8 + SummaryRequestVirtualSwitchNames = 9 + SummaryRequestVersion = 10 + SummaryRequestShielded = 11 + SummaryRequestEnabledState = 100 + SummaryRequestProcessorLoad = 101 + SummaryRequestProcessorLoadHistory = 102 + SummaryRequestMemoryUsage = 103 + SummaryRequestHeartbeat = 104 + SummaryRequestUptime = 105 + SummaryRequestGuestOperatingSystem = 106 + SummaryRequestSnapshots = 107 + SummaryRequestAsynchronousTasks = 108 + SummaryRequestHealthState = 109 + SummaryRequestOperationalStatus = 110 + SummaryRequestStatusDescriptions = 111 + SummaryRequestMemoryAvailable = 112 + SummaryRequestMemoryBuffer = 113 + SummaryRequestReplicationMode = 114 + SummaryRequestReplicationState = 115 + SummaryRequestReplicationHealth = 116 + SummaryRequestApplicationHealth = 117 + SummaryRequestReplicationStateEx = 118 + SummaryRequestReplicationHealthEx = 119 + SummaryRequestSwapFilesInUse = 120 + SummaryRequestIntegrationServicesVersionState = 121 + SummaryRequestReplicationProvider = 122 + SummaryRequestMemorySpansPhysicalNumaNodes = 123 + SummaryRequestIntegrationServicesVersionState2 = 132 + SummaryRequestOtherEnabledState = 132 +) + +type SummaryRequestSet []uint + +var ( + + // SummaryRequestCommon includes a smaller subset of commonly used fields + SummaryRequestCommon = SummaryRequestSet{ + SummaryRequestName, + SummaryRequestElementName, + SummaryRequestCreationTime, + SummaryRequestNotes, + SummaryRequestProcessors, + SummaryRequestEnabledState, + SummaryRequestProcessorLoad, + SummaryRequestMemoryUsage, + SummaryRequestHeartbeat, + SummaryRequestUptime, + SummaryRequestGuestOperatingSystem, + SummaryRequestHealthState, + SummaryRequestOperationalStatus, + SummaryRequestStatusDescriptions, + SummaryRequestMemoryAvailable, + SummaryRequestMemoryBuffer, + SummaryRequestSwapFilesInUse, + } + + // SummaryRequestNearAll includes everything but load history and thumbnails + SummaryRequestNearAll = SummaryRequestSet{ + SummaryRequestName, + SummaryRequestElementName, + SummaryRequestCreationTime, + SummaryRequestNotes, + SummaryRequestProcessors, + SummaryRequestAllocatedGPU, + SummaryRequestVirtualSwitchNames, + SummaryRequestVersion, + SummaryRequestShielded, + SummaryRequestEnabledState, + SummaryRequestProcessorLoad, + SummaryRequestMemoryUsage, + SummaryRequestHeartbeat, + SummaryRequestUptime, + SummaryRequestGuestOperatingSystem, + SummaryRequestSnapshots, + SummaryRequestAsynchronousTasks, + SummaryRequestHealthState, + SummaryRequestOperationalStatus, + SummaryRequestStatusDescriptions, + SummaryRequestMemoryAvailable, + SummaryRequestMemoryBuffer, + SummaryRequestReplicationMode, + SummaryRequestReplicationState, + SummaryRequestReplicationHealth, + SummaryRequestApplicationHealth, + SummaryRequestReplicationStateEx, + SummaryRequestReplicationHealthEx, + SummaryRequestSwapFilesInUse, + SummaryRequestIntegrationServicesVersionState, + SummaryRequestReplicationProvider, + SummaryRequestMemorySpansPhysicalNumaNodes, + SummaryRequestIntegrationServicesVersionState2, + SummaryRequestOtherEnabledState, + } +) + +// SummaryInformation https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-summaryinformation +type SummaryInformation struct { + InstanceID string + AllocatedGPU string + Shielded bool + AsynchronousTasks []ConcreteJob + CreationTime time.Time + ElementName string + EnabledState uint16 + OtherEnabledState string + GuestOperatingSystem string + HealthState uint16 + Heartbeat uint16 + MemoryUsage uint64 + MemoryAvailable int32 + AvailableMemoryBuffer int32 + SwapFilesInUse bool + Name string + Notes string + Version string + NumberOfProcessors uint16 + OperationalStatus []uint16 + ProcessorLoad uint16 + ProcessorLoadHistory []uint16 + Snapshots []SystemSettings + StatusDescriptions []string + ThumbnailImage []uint8 + ThumbnailImageHeight uint16 + ThumbnailImageWidth uint16 + UpTime uint64 + ReplicationState uint16 + ReplicationStateEx []uint16 + ReplicationHealth uint16 + ReplicationHealthEx []uint16 + ReplicationMode uint16 + TestReplicaSystem string // REF to CIM_ComputerSystem + ApplicationHealth uint16 + IntegrationServicesVersionState uint16 + MemorySpansPhysicalNumaNodes bool + ReplicationProviderId []string + EnhancedSessionModeState uint16 + VirtualSwitchNames []string + VirtualSystemSubType string + HostComputerSystemName string +} + +// CIM_ConcreteJob https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-concretejob +type ConcreteJob struct { + InstanceID string + Caption string + Description string + ElementName string + InstallDate time.Time + Name string + OperationalStatus []uint16 // = { 2 } + StatusDescriptions []string // = { "OK" } + Status string + HealthState uint16 // = 5 + CommunicationStatus uint16 + DetailedStatus uint16 + OperatingStatus uint16 + PrimaryStatus uint16 + JobStatus string + TimeSubmitted time.Time + ScheduledStartTime time.Time + StartTime time.Time + ElapsedTime time.Duration + JobRunTimes uint32 + RunMonth uint8 + RunDay int8 + RunDayOfWeek int8 + RunStartInterval time.Time + LocalOrUtcTime uint16 + UntilTime time.Time + Notify string + Owner string + Priority uint32 + PercentComplete uint16 + DeleteOnCompletion bool + ErrorCode uint16 + ErrorDescription string + ErrorSummaryDescription string + RecoveryAction uint16 + OtherRecoveryAction string + JobState uint16 + TimeOfLastStateChange time.Time + TimeBeforeRemoval time.Duration // = + Cancellable bool + JobType uint16 +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings.go new file mode 100644 index 0000000000..527a8574c2 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings.go @@ -0,0 +1,207 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "fmt" + "time" + + "github.com/containers/libhvee/pkg/wmiext" +) + +type SystemSettings struct { + S__PATH string + InstanceID string + Caption string // = "Virtual Machine Settings" + Description string + ElementName string + VirtualSystemIdentifier string + VirtualSystemType string + Notes []string + CreationTime time.Time + ConfigurationID string + ConfigurationDataRoot string + ConfigurationFile string + SnapshotDataRoot string + SuspendDataRoot string + SwapFileDataRoot string + LogDataRoot string + AutomaticStartupAction uint16 // non-zero + AutomaticStartupActionDelay time.Duration + AutomaticStartupActionSequenceNumber uint16 + AutomaticShutdownAction uint16 // non-zero + AutomaticRecoveryAction uint16 // non-zero + RecoveryFile string + BIOSGUID string + BIOSSerialNumber string + BaseBoardSerialNumber string + ChassisSerialNumber string + Architecture string + ChassisAssetTag string + BIOSNumLock bool + BootOrder []uint16 + Parent string + UserSnapshotType uint16 // non-zero + IsSaved bool + AdditionalRecoveryInformation string + AllowFullSCSICommandSet bool + DebugChannelId uint32 + DebugPortEnabled uint16 + DebugPort uint32 + Version string + IncrementalBackupEnabled bool + VirtualNumaEnabled bool + AllowReducedFcRedundancy bool // = False + VirtualSystemSubType string + BootSourceOrder []string + PauseAfterBootFailure bool + NetworkBootPreferredProtocol uint16 // non-zero + GuestControlledCacheTypes bool + AutomaticSnapshotsEnabled bool + IsAutomaticSnapshot bool + GuestStateFile string + GuestStateDataRoot string + LockOnDisconnect bool + ParentPackage string + AutomaticCriticalErrorActionTimeout time.Duration + AutomaticCriticalErrorAction uint16 + ConsoleMode uint16 + SecureBootEnabled bool + SecureBootTemplateId string + LowMmioGapSize uint64 + HighMmioGapSize uint64 + EnhancedSessionTransportType uint16 +} + +func DefaultSystemSettings() *SystemSettings { + return &SystemSettings{ + // setup all non-zero settings + AutomaticStartupAction: 2, // no auto-start + AutomaticShutdownAction: 4, // shutdown + AutomaticRecoveryAction: 3, // restart + UserSnapshotType: 2, // no snapshotting + NetworkBootPreferredProtocol: 4096, // ipv4 for pxe + VirtualSystemSubType: "Microsoft:Hyper-V:SubType:2", + } + +} + +func (s *SystemSettings) Path() string { + return s.S__PATH +} + +func (s *SystemSettings) AddScsiController() (*ScsiControllerSettings, error) { + const scsiControllerType = "Microsoft:Hyper-V:Synthetic SCSI Controller" + controller := &ScsiControllerSettings{} + + if err := s.createSystemResourceInternal(controller, scsiControllerType, nil); err != nil { + return nil, err + } + + controller.systemSettings = s + return controller, nil +} + +func (s *SystemSettings) createSystemResourceInternal(settings interface{}, resourceType string, cb func()) error { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + if err = populateDefaults(resourceType, settings); err != nil { + return err + } + + if cb != nil { + cb() + } + + resourceStr, err := createResourceSettingGeneric(settings, resourceType) + if err != nil { + return err + } + + path, err := addResource(service, s.Path(), resourceStr) + if err != nil { + return err + } + + err = service.GetObjectAsObject(path, settings) + return err +} + +func (s *SystemSettings) AddSyntheticEthernetPort(beforeAdd func(*SyntheticEthernetPortSettings)) (*SyntheticEthernetPortSettings, error) { + const networkAdapterType = SyntheticEthernetPortResourceType + port := &SyntheticEthernetPortSettings{} + + var cb func() + if beforeAdd != nil { + cb = func() { + beforeAdd(port) + } + } + + if err := s.createSystemResourceInternal(port, networkAdapterType, cb); err != nil { + return nil, err + } + + port.systemSettings = s + return port, nil +} + +func addResource(service *wmiext.Service, systemSettingPath string, resourceSettings string) (string, error) { + vsms, err := service.GetSingletonInstance(VirtualSystemManagementService) + if err != nil { + return "", err + } + defer vsms.Close() + + var res int32 + var resultingSettings []string + var job *wmiext.Instance + err = vsms.BeginInvoke("AddResourceSettings"). + In("AffectedConfiguration", systemSettingPath). + In("ResourceSettings", []string{resourceSettings}). + Execute(). + Out("Job", &job). + Out("ResultingResourceSettings", &resultingSettings). + Out("ReturnValue", &res).End() + + if err != nil { + return "", fmt.Errorf("AddResourceSettings failed: %w", err) + } + + err = waitVMResult(res, service, job, "failed to add resource", nil) + + if len(resultingSettings) > 0 { + return resultingSettings[0], err + } + + return "", err +} + +func (s *SystemSettings) GetVM() (*VirtualMachine, error) { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return nil, err + } + defer service.Close() + + inst, err := service.FindFirstRelatedInstance(s.Path(), "Msvm_ComputerSystem") + if err != nil { + return nil, err + } + defer inst.Close() + + vm := &VirtualMachine{} + + if err = inst.GetAll(vm); err != nil { + return nil, err + } + + return vm, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings_builder.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings_builder.go new file mode 100644 index 0000000000..119ba9e6d4 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/system_settings_builder.go @@ -0,0 +1,161 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "fmt" + + "github.com/containers/libhvee/pkg/wmiext" +) + +type SystemSettingsBuilder struct { + systemSettings *SystemSettings + processorSettings *ProcessorSettings + memorySettings *MemorySettings + err error +} + +func NewSystemSettingsBuilder() *SystemSettingsBuilder { + return &SystemSettingsBuilder{} +} + +func (builder *SystemSettingsBuilder) PrepareSystemSettings(name string, beforeAdd func(*SystemSettings)) *SystemSettingsBuilder { + if builder.err != nil { + return builder + } + + if builder.systemSettings == nil { + settings := DefaultSystemSettings() + settings.ElementName = name + builder.systemSettings = settings + } + + if beforeAdd != nil { + beforeAdd(builder.systemSettings) + } + + return builder +} + +func (builder *SystemSettingsBuilder) PrepareProcessorSettings(beforeAdd func(*ProcessorSettings)) *SystemSettingsBuilder { + if builder.err != nil { + return builder + } + + if builder.processorSettings == nil { + settings, err := fetchDefaultProcessorSettings() + if err != nil { + builder.err = err + return builder + } + builder.processorSettings = settings + } + + if beforeAdd != nil { + beforeAdd(builder.processorSettings) + } + + return builder +} + +func (builder *SystemSettingsBuilder) PrepareMemorySettings(beforeAdd func(*MemorySettings)) *SystemSettingsBuilder { + if builder.err != nil { + return builder + } + + if builder.memorySettings == nil { + settings, err := fetchDefaultMemorySettings() + if err != nil { + builder.err = err + return builder + } + builder.memorySettings = settings + } + + if beforeAdd != nil { + beforeAdd(builder.memorySettings) + } + + return builder +} + +func (builder *SystemSettingsBuilder) Build() (*SystemSettings, error) { + var service *wmiext.Service + var err error + + if builder.PrepareSystemSettings("unnamed-vm", nil). + PrepareProcessorSettings(nil). + PrepareMemorySettings(nil).err != nil { + return nil, err + } + + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return nil, err + } + defer service.Close() + + systemSettingsInst, err := service.SpawnInstance("Msvm_VirtualSystemSettingData") + if err != nil { + return nil, err + } + defer systemSettingsInst.Close() + + err = systemSettingsInst.PutAll(builder.systemSettings) + if err != nil { + return nil, err + } + + memoryStr, err := createMemorySettings(builder.memorySettings) + if err != nil { + return nil, err + } + + processorStr, err := createProcessorSettings(builder.processorSettings) + if err != nil { + return nil, err + } + + vsms, err := service.GetSingletonInstance(VirtualSystemManagementService) + if err != nil { + return nil, err + } + defer vsms.Close() + + systemStr := systemSettingsInst.GetCimText() + + var job *wmiext.Instance + var res int32 + var resultingSystem string + err = vsms.BeginInvoke("DefineSystem"). + In("SystemSettings", systemStr). + In("ResourceSettings", []string{memoryStr, processorStr}). + Execute(). + Out("Job", &job). + Out("ResultingSystem", &resultingSystem). + Out("ReturnValue", &res).End() + + if err != nil { + return nil, fmt.Errorf("failed to define system: %w", err) + } + + err = waitVMResult(res, service, job, "failed to define system", nil) + if err != nil { + return nil, err + } + + newSettings, err := service.FindFirstRelatedInstance(resultingSystem, "Msvm_VirtualSystemSettingData") + if err != nil { + return nil, err + } + path, err := newSettings.Path() + if err != nil { + return nil, err + } + + if err = service.GetObjectAsObject(path, builder.systemSettings); err != nil { + return nil, err + } + + return builder.systemSettings, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vdvd_storage_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vdvd_storage_settings.go new file mode 100644 index 0000000000..ad5eceabe2 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vdvd_storage_settings.go @@ -0,0 +1,13 @@ +//go:build windows +// +build windows + +package hypervctl + +const VirtualDvdDiskType = "Microsoft:Hyper-V:Virtual CD/DVD Disk" + +type VirtualDvdDiskStorageSettings struct { + StorageAllocationSettings + + systemSettings *SystemSettings + driveSettings *SyntheticDvdDriveSettings +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_settings.go new file mode 100644 index 0000000000..e6bd8b4bff --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_settings.go @@ -0,0 +1,28 @@ +//go:build windows +// +build windows + +package hypervctl + +import "time" + +type VirtualHardDiskSettings struct { + S__PATH string + InstanceID string + Caption string // = "Virtual Hard Disk Setting Data" + Description string // = "Setting Data for a Virtual Hard Disk" + ElementName string + Type uint16 + Format uint16 + Path string + ParentPath string + ParentTimestamp time.Time + ParentIdentifier string + MaxInternalSize uint64 + BlockSize uint32 + LogicalSectorSize uint32 + PhysicalSectorSize uint32 + VirtualDiskId string + DataAlignment uint64 + PmemAddressAbstractionType uint16 + IsPmemCompatible bool +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_storage_settings.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_storage_settings.go new file mode 100644 index 0000000000..0384408cec --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vhd_storage_settings.go @@ -0,0 +1,13 @@ +//go:build windows +// +build windows + +package hypervctl + +const VirtualHardDiskType = "Microsoft:Hyper-V:Virtual Hard Disk" + +type VirtualHardDiskStorageSettings struct { + StorageAllocationSettings + + systemSettings *SystemSettings + driveSettings *SyntheticDiskDriveSettings +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vm.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vm.go new file mode 100644 index 0000000000..4d60f551c6 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vm.go @@ -0,0 +1,601 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "bytes" + "errors" + "fmt" + "os" + "strings" + "time" + + "github.com/containers/libhvee/pkg/kvp/ginsu" + "github.com/containers/libhvee/pkg/wmiext" +) + +// delete this when close to being done +var ( + ErrNotImplemented = errors.New("function not implemented") +) + +type VirtualMachine struct { + S__PATH string `json:"-"` + S__CLASS string `json:"-"` + InstanceID string + Caption string + Description string + ElementName string + InstallDate time.Time + OperationalStatus []uint16 + StatusDescriptions []string + Status string + HealthState uint16 + CommunicationStatus uint16 + DetailedStatus uint16 + OperatingStatus uint16 + PrimaryStatus uint16 + EnabledState uint16 + OtherEnabledState string + RequestedState uint16 + EnabledDefault uint16 + TimeOfLastStateChange string + AvailableRequestedStates []uint16 + TransitioningToState uint16 + CreationClassName string + Name string + PrimaryOwnerName string + PrimaryOwnerContact string + Roles []string + NameFormat string + OtherIdentifyingInfo []string + IdentifyingDescriptions []string + Dedicated []uint16 + OtherDedicatedDescriptions []string + ResetCapability uint16 + PowerManagementCapabilities []uint16 + OnTimeInMilliseconds uint64 + ProcessID uint32 + TimeOfLastConfigurationChange string + NumberOfNumaNodes uint16 + ReplicationState uint16 + ReplicationHealth uint16 + ReplicationMode uint16 + FailedOverReplicationType uint16 + LastReplicationType uint16 + LastApplicationConsistentReplicationTime string + LastReplicationTime time.Time + LastSuccessfulBackupTime string + EnhancedSessionModeState uint16 + vmm *VirtualMachineManager +} + +func (vm *VirtualMachine) Path() string { + return vm.S__PATH +} +func (vm *VirtualMachine) SplitAndAddIgnition(keyPrefix string, ignRdr *bytes.Reader) error { + parts, err := ginsu.Dice(ignRdr) + if err != nil { + return err + } + for idx, val := range parts { + key := fmt.Sprintf("%s%d", keyPrefix, idx) + if err := vm.AddKeyValuePair(key, val); err != nil { + return err + } + } + return nil +} + +func (vm *VirtualMachine) AddKeyValuePair(key string, value string) error { + return vm.kvpOperation("AddKvpItems", key, value, "key already exists?") +} + +func (vm *VirtualMachine) ModifyKeyValuePair(key string, value string) error { + return vm.kvpOperation("ModifyKvpItems", key, value, "key invalid?") +} + +func (vm *VirtualMachine) PutKeyValuePair(key string, value string) error { + err := vm.AddKeyValuePair(key, value) + kvpError, ok := err.(*KvpError) + if !ok || kvpError.ErrorCode != KvpIllegalArgument { + return err + } + + return vm.ModifyKeyValuePair(key, value) +} + +func (vm *VirtualMachine) RemoveKeyValuePair(key string) error { + return vm.kvpOperation("RemoveKvpItems", key, "", "key invalid?") +} + +func (vm *VirtualMachine) GetKeyValuePairs() (map[string]string, error) { + var service *wmiext.Service + var err error + + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return nil, err + } + + defer service.Close() + + i, err := service.FindFirstRelatedInstance(vm.Path(), "Msvm_KvpExchangeComponent") + if err != nil { + return nil, err + } + + defer i.Close() + + var path string + path, err = i.GetAsString("__PATH") + if err != nil { + return nil, err + + } + + i, err = service.FindFirstRelatedInstance(path, "Msvm_KvpExchangeComponentSettingData") + if err != nil { + return nil, err + } + defer i.Close() + + s, err := i.GetAsString("HostExchangeItems") + if err != nil { + return nil, err + } + + return parseKvpMapXml(s) +} + +func (vm *VirtualMachine) kvpOperation(op string, key string, value string, illegalSuggestion string) error { + var service *wmiext.Service + var vsms, job *wmiext.Instance + var err error + + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + vsms, err = service.GetSingletonInstance(VirtualSystemManagementService) + if err != nil { + return err + } + defer vsms.Close() + + itemStr, err := createKvpItem(service, key, value) + if err != nil { + return err + } + + execution := vsms.BeginInvoke(op). + In("TargetSystem", vm.Path()). + In("DataItems", []string{itemStr}). + Execute() + + if err := execution.Out("Job", &job).End(); err != nil { + return fmt.Errorf("%s execution failed: %w", op, err) + } + + err = translateKvpError(wmiext.WaitJob(service, job), illegalSuggestion) + defer job.Close() + return err +} + +func waitVMResult(res int32, service *wmiext.Service, job *wmiext.Instance, errorMsg string, translate func(int) error) error { + var err error + + switch res { + case 0: + return nil + case 4096: + err = wmiext.WaitJob(service, job) + defer job.Close() + default: + if translate != nil { + return translate(int(res)) + } + + return fmt.Errorf("%s (result code %d)", errorMsg, res) + } + + if err != nil { + desc, _ := job.GetAsString("ErrorDescription") + desc = strings.Replace(desc, "\n", " ", -1) + return fmt.Errorf("%s: %w (%s)", errorMsg, err, desc) + } + + return err +} + +func (vm *VirtualMachine) StopWithForce() error { + return vm.stop(true) +} + +func (vm *VirtualMachine) Stop() error { + return vm.stop(false) +} + +func (vm *VirtualMachine) stop(force bool) error { + if !Enabled.equal(vm.EnabledState) { + return ErrMachineNotRunning + } + var ( + err error + res int32 + srv *wmiext.Service + ) + if srv, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + wmiInst, err := srv.FindFirstRelatedInstance(vm.Path(), "Msvm_ShutdownComponent") + if err != nil { + return err + } + // https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-shutdowncomponent-initiateshutdown + err = wmiInst.BeginInvoke("InitiateShutdown"). + In("Reason", "User requested"). + In("Force", force). + Execute(). + Out("ReturnValue", &res).End() + if err != nil { + return err + } + + if res != 0 { + return translateShutdownError(int(res)) + } + + // Wait for vm to actually *be* down + for i := 0; i < 200; i++ { + refreshVM, err := vm.vmm.GetMachine(vm.ElementName) + if err != nil { + return err + } + if refreshVM.State() == Disabled { + break + } + time.Sleep(50 * time.Millisecond) + } + return nil +} + +func (vm *VirtualMachine) Start() error { + var ( + srv *wmiext.Service + err error + job *wmiext.Instance + res int32 + ) + + if s := vm.EnabledState; !Disabled.equal(s) { + if Enabled.equal(s) { + return ErrMachineAlreadyRunning + } else if Starting.equal(s) { + return ErrMachineAlreadyRunning + } + return errors.New("machine not in a state to start") + } + + if srv, err = getService(srv); err != nil { + return err + } + defer srv.Close() + + instance, err := srv.GetObject(vm.Path()) + if err != nil { + return err + } + defer instance.Close() + + // https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/cim-concretejob-requeststatechange + if err := instance.BeginInvoke("RequestStateChange"). + In("RequestedState", uint16(start)). + In("TimeoutPeriod", &time.Time{}). + Execute(). + Out("Job", &job). + Out("ReturnValue", &res).End(); err != nil { + return err + } + return waitVMResult(res, srv, job, "failed to start vm", nil) +} + +func getService(_ *wmiext.Service) (*wmiext.Service, error) { + // any reason why when we instantiate a vm, we should NOT just embed a service? + return wmiext.NewLocalService(HyperVNamespace) +} + +func (vm *VirtualMachine) list() ([]*HyperVConfig, error) { + + return nil, ErrNotImplemented +} + +func (vm *VirtualMachine) GetConfig(diskPath string) (*HyperVConfig, error) { + var ( + diskSize uint64 + ) + summary, err := vm.GetSummaryInformation(SummaryRequestCommon) + if err != nil { + return nil, err + } + + // Grabbing actual disk size + diskPathInfo, err := os.Stat(diskPath) + if err != nil { + return nil, err + } + diskSize = uint64(diskPathInfo.Size()) + + config := HyperVConfig{ + Hardware: HardwareConfig{ + CPUs: summary.NumberOfProcessors, + DiskPath: diskPath, + DiskSize: diskSize, + Memory: summary.MemoryAvailable, + }, + Status: Statuses{ + Created: vm.InstallDate, + LastUp: time.Time{}, + Running: Enabled.equal(vm.EnabledState), + Starting: vm.IsStarting(), + State: EnabledState(vm.EnabledState), + }, + } + return &config, nil +} + +// GetSummaryInformation returns the live VM summary information for this virtual machine. +// The requestedFields parameter controls which fields of summary information are populated. +// SummaryRequestCommon and SummaryRequestNearAll provide predefined combinations for this +// parameter +func (vm *VirtualMachine) GetSummaryInformation(requestedFields SummaryRequestSet) (*SummaryInformation, error) { + service, err := wmiext.NewLocalService(HyperVNamespace) + if err != nil { + return nil, err + } + defer service.Close() + + instance, err := vm.fetchSystemSettingsInstance(service) + if err != nil { + return nil, err + } + defer instance.Close() + + path, err := instance.Path() + if err != nil { + return nil, err + } + + result, err := vm.vmm.getSummaryInformation(path, requestedFields) + if err != nil { + return nil, err + } + + if len(result) < 1 { + return nil, errors.New("summary information search returned an empty result set") + } + + return &result[0], nil +} + +// NewVirtualMachine creates a new vm in hyperv +// decided to not return a *VirtualMachine here because of how Podman is +// likely to use this. this could be easily added if desirable +func (vmm *VirtualMachineManager) NewVirtualMachine(name string, config *HardwareConfig) error { + exists, err := vmm.Exists(name) + if err != nil { + return err + } + if exists { + return ErrMachineAlreadyExists + } + + // TODO I gotta believe there are naming restrictions for vms in hyperv? + // TODO If something fails during creation, do we rip things down or follow precedent from other machines? user deletes things + + systemSettings, err := NewSystemSettingsBuilder(). + PrepareSystemSettings(name, nil). + PrepareMemorySettings(func(ms *MemorySettings) { + //ms.DynamicMemoryEnabled = false + //ms.VirtualQuantity = 8192 // Startup memory + //ms.Reservation = config.Memory // min + + // The API seems to require both of these even + // when not using dynamic memory + ms.Limit = uint64(config.Memory) + ms.VirtualQuantity = uint64(config.Memory) + }). + PrepareProcessorSettings(func(ps *ProcessorSettings) { + ps.VirtualQuantity = uint64(config.CPUs) // 4 cores + }). + Build() + if err != nil { + return err + } + + if err := NewDriveSettingsBuilder(systemSettings). + AddScsiController(). + AddSyntheticDiskDrive(0). + DefineVirtualHardDisk(config.DiskPath, func(vhdss *VirtualHardDiskStorageSettings) { + // set extra params like + // vhdss.IOPSLimit = 5000 + }). + Finish(). // disk + Finish(). // drive + //AddSyntheticDvdDrive(1). + //DefineVirtualDvdDisk(isoFile). + //Finish(). // disk + //Finish(). // drive + Finish(). // controller + Complete(); err != nil { + return err + } + // Add default network connection + if config.Network { + if err := NewNetworkSettingsBuilder(systemSettings). + AddSyntheticEthernetPort(nil). + AddEthernetPortAllocation(""). // "" = connect to default switch + Finish(). // allocation + Finish(). // port + Complete(); err != nil { + return err + } + } + return nil +} + +func (vm *VirtualMachine) fetchSystemSettingsInstance(service *wmiext.Service) (*wmiext.Instance, error) { + // When a settings snapshot is taken there are multiple associations, use only the realized/active version + return service.FindFirstRelatedInstanceThrough(vm.Path(), "Msvm_VirtualSystemSettingData", "Msvm_SettingsDefineState") +} + +func (vm *VirtualMachine) fetchExistingResourceSettings(service *wmiext.Service, resourceType string, resourceSettings interface{}) error { + const errFmt = "could not fetch resource settings (%s): %w" + // When a settings snapshot is taken there are multiple associations, use only the realized/active version + instance, err := vm.fetchSystemSettingsInstance(service) + if err != nil { + return fmt.Errorf(errFmt, resourceType, err) + } + defer instance.Close() + + path, err := instance.Path() + if err != nil { + return fmt.Errorf(errFmt, resourceType, err) + + } + + return service.FindFirstRelatedObject(path, resourceType, resourceSettings) +} + +// Update processor and/or mem +func (vm *VirtualMachine) UpdateProcessorMemSettings(updateProcessor func(*ProcessorSettings), updateMemory func(*MemorySettings)) error { + service, err := wmiext.NewLocalService(HyperVNamespace) + if err != nil { + return err + } + defer service.Close() + + proc := &ProcessorSettings{} + mem := &MemorySettings{} + + var settings []string + if updateProcessor != nil { + err = vm.fetchExistingResourceSettings(service, "Msvm_ProcessorSettingData", proc) + if err != nil { + return err + } + + updateProcessor(proc) + + processorStr, err := createProcessorSettings(proc) + if err != nil { + return err + } + settings = append(settings, processorStr) + } + + if updateMemory != nil { + err = vm.fetchExistingResourceSettings(service, "Msvm_MemorySettingData", mem) + if err != nil { + return err + } + + updateMemory(mem) + + memStr, err := createMemorySettings(mem) + if err != nil { + return err + } + + settings = append(settings, memStr) + } + + if len(settings) < 1 { + return nil + } + + vsms, err := service.GetSingletonInstance("Msvm_VirtualSystemManagementService") + if err != nil { + return err + } + defer vsms.Close() + + var job *wmiext.Instance + var res int32 + err = vsms.BeginInvoke("ModifyResourceSettings"). + In("ResourceSettings", settings). + Execute(). + Out("Job", &job). + Out("ReturnValue", &res). + End() + + if err != nil { + return fmt.Errorf("failed to modify resource settings: %w", err) + } + + return waitVMResult(res, service, job, "failed to modify resource settings", translateModifyError) +} + +func (vm *VirtualMachine) remove() (int32, error) { + var ( + err error + res int32 + srv *wmiext.Service + ) + + // Check for disabled/stopped state + if !Disabled.equal(vm.EnabledState) { + return -1, ErrMachineStateInvalid + } + if srv, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return -1, err + } + + vsms, err := srv.GetSingletonInstance("Msvm_VirtualSystemManagementService") + if err != nil { + return -1, err + } + defer vsms.Close() + + var ( + job *wmiext.Instance + ) + + // https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/cim-virtualsystemmanagementservice-destroysystem + if err := vsms.BeginInvoke("DestroySystem"). + In("AffectedSystem", vm.Path()). + Execute(). + Out("Job", &job). + Out("ReturnValue", &res).End(); err != nil { + return -1, err + } + + // do i have this correct? you can get an error without a result? + if err := waitVMResult(res, srv, job, "failed to remove vm", nil); err != nil { + return -1, err + } + return res, nil +} + +func (vm *VirtualMachine) Remove(diskPath string) error { + if _, err := vm.remove(); err != nil { + return err + } + + // Remove disk only if we were given one + if len(diskPath) > 0 { + if err := os.Remove(diskPath); err != nil { + return err + } + } + return nil +} + +func (vm *VirtualMachine) State() EnabledState { + return EnabledState(vm.EnabledState) +} + +func (vm *VirtualMachine) IsStarting() bool { + return Starting.equal(vm.EnabledState) +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vm_config.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vm_config.go new file mode 100644 index 0000000000..6ee525ebd9 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vm_config.go @@ -0,0 +1,117 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "time" +) + +type vmState uint16 + +const ( + // Changes the state to 'Running'. + start vmState = 2 + // Stops the job temporarily. The intention is to subsequently restart the job with 'Start'. It might be possible to + // enter the 'Service' state while suspended. (This is job-specific.) + suspend vmState = 3 + // Stops the job cleanly, saves data, preserves the state, and shuts down all underlying processes' + // in an orderly manner. + terminate vmState = 4 + //Terminates the job immediately with no requirement to save data or preserve the state. + kill vmState = 5 +) + +type EnabledState uint16 + +const ( + // Unknown The state of the element could not be determined. + Unknown EnabledState = 0 + // Other No description + Other EnabledState = 1 + // Enabled The element is running. + Enabled EnabledState = 2 + // Disabled The element is turned off. + Disabled EnabledState = 3 + // ShuttingDown Shutting_Down The element is in the process of going to a Disabled state. + ShuttingDown EnabledState = 4 + // NotApplicable The element does not support being enabled or disabled. + NotApplicable EnabledState = 5 + // EnabledButOffline The element might be completing commands, and it will drop any new requests. + EnabledButOffline EnabledState = 6 + // InTest The element is in a test state. + InTest EnabledState = 7 + // Deferred The element might be completing commands, but it will queue any new requests. + Deferred EnabledState = 8 + // Quiesce The element is enabled but in a restricted mode. The behavior of the element is similar to the Enabled state + //(2), but it processes only a restricted set of commands. All other requests are queued. + Quiesce EnabledState = 9 + // Starting The element is in the process of going to an Enabled state (2). New requests are queued. + Starting EnabledState = 10 +) + +func (es EnabledState) String() string { + switch es { + case Unknown: + return "unknown" + case Other: + return "other" + case Enabled: + return "enabled" + case Disabled: + return "disabled" + case ShuttingDown: + return "shutting down" + case NotApplicable: + return "not applicable" + case EnabledButOffline: + return "enabled but offline" + case InTest: + return "in test" + case Deferred: + return "deferred" + case Quiesce: + return "quiesce" + } + return "starting" +} + +func (es EnabledState) equal(s uint16) bool { + return es == EnabledState(s) +} + +// HyperVConfig describes physical attributes of the machine +type HyperVConfig struct { + // Hardware configuration for HyperV + Hardware HardwareConfig + // state and descriptive info + Status Statuses +} + +type HardwareConfig struct { + // CPUs to be assigned to the VM + CPUs uint16 + // Diskpath is fully qualified location of the + // bootable disk image + DiskPath string + // Disk size in gigabytes assigned to the vm + DiskSize uint64 + // Memory in megabytes assigned to the vm + Memory int32 + // Network is bool to add a Network Connection to the + // default network switch in Microsoft HyperV + Network bool +} + +type Statuses struct { + // time vm created + Created time.Time + // last time vm ran + LastUp time.Time + // is vm running + Running bool + // is vm starting up + Starting bool + // vm state + State EnabledState +} diff --git a/vendor/github.com/containers/libhvee/pkg/hypervctl/vmm.go b/vendor/github.com/containers/libhvee/pkg/hypervctl/vmm.go new file mode 100644 index 0000000000..a7cce22081 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/hypervctl/vmm.go @@ -0,0 +1,184 @@ +//go:build windows +// +build windows + +package hypervctl + +import ( + "fmt" + + "github.com/containers/libhvee/pkg/wmiext" +) + +const ( + HyperVNamespace = "root\\virtualization\\v2" + VirtualSystemManagementService = "Msvm_VirtualSystemManagementService" +) + +// https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-computersystem + +type VirtualMachineManager struct { +} + +func NewVirtualMachineManager() *VirtualMachineManager { + return &VirtualMachineManager{} +} + +func (vmm *VirtualMachineManager) GetAll() ([]*VirtualMachine, error) { + const wql = "Select * From Msvm_ComputerSystem Where Caption = 'Virtual Machine'" + + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return []*VirtualMachine{}, err + } + defer service.Close() + + var enum *wmiext.Enum + if enum, err = service.ExecQuery(wql); err != nil { + return nil, err + } + defer enum.Close() + + var vms []*VirtualMachine + for { + vm := &VirtualMachine{vmm: vmm} + done, err := wmiext.NextObject(enum, vm) + if err != nil { + return vms, err + } + if done { + break + } + vms = append(vms, vm) + } + + return vms, nil +} +func (vmm *VirtualMachineManager) Exists(name string) (bool, error) { + vms, err := vmm.GetAll() + if err != nil { + return false, err + } + for _, i := range vms { + // TODO should case be honored or ignored? + if i.Name == name { + return true, nil + } + } + return false, nil +} + +func (*VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) { + const wql = "Select * From Msvm_ComputerSystem Where Caption = 'Virtual Machine' And ElementName='%s'" + + vm := &VirtualMachine{} + var service *wmiext.Service + var err error + + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return vm, err + } + defer service.Close() + + var enum *wmiext.Enum + if enum, err = service.ExecQuery(fmt.Sprintf(wql, name)); err != nil { + return nil, err + } + defer enum.Close() + + done, err := wmiext.NextObject(enum, vm) + if err != nil { + return vm, err + } + + if done { + return vm, fmt.Errorf("could not find virtual machine %q", name) + } + + return vm, nil +} + +func (*VirtualMachineManager) CreateVhdxFile(path string, maxSize uint64) error { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return err + } + defer service.Close() + + settings := &VirtualHardDiskSettings{} + settings.Format = 3 + settings.MaxInternalSize = maxSize + settings.Type = 3 + settings.Path = path + + instance, err := service.CreateInstance("Msvm_VirtualHardDiskSettingData", settings) + if err != nil { + return err + } + defer instance.Close() + settingsStr := instance.GetCimText() + + imms, err := service.GetSingletonInstance("Msvm_ImageManagementService") + if err != nil { + return err + } + defer imms.Close() + + var job *wmiext.Instance + var ret int32 + err = imms.BeginInvoke("CreateVirtualHardDisk"). + In("VirtualDiskSettingData", settingsStr). + Execute(). + Out("Job", &job). + Out("ReturnValue", &ret). + End() + + if err != nil { + return fmt.Errorf("failed to create vhdx: %w", err) + } + + return waitVMResult(ret, service, job, "failed to create vhdx", nil) +} + +// GetSummaryInformation returns the live VM summary information for all virtual machines. +// The requestedFields parameter controls which fields of summary information are populated. +// SummaryRequestCommon and SummaryRequestNearAll provide predefined combinations for this +// parameter. +func (vmm *VirtualMachineManager) GetSummaryInformation(requestedFields SummaryRequestSet) ([]SummaryInformation, error) { + return vmm.getSummaryInformation("", requestedFields) +} + +func (vmm *VirtualMachineManager) getSummaryInformation(settingsPath string, requestedFields SummaryRequestSet) ([]SummaryInformation, error) { + var service *wmiext.Service + var err error + if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil { + return nil, err + } + defer service.Close() + + vsms, err := service.GetSingletonInstance(VirtualSystemManagementService) + if err != nil { + return nil, err + } + defer vsms.Close() + + var summary []SummaryInformation + + inv := vsms.BeginInvoke("GetSummaryInformation"). + In("RequestedInformation", []uint(requestedFields)) + + if len(settingsPath) > 0 { + inv.In("SettingData", []string{settingsPath}) + } + + err = inv.Execute(). + Out("SummaryInformation", &summary). + End() + + if err != nil { + return nil, err + } + + return summary, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/kvp/ginsu/util.go b/vendor/github.com/containers/libhvee/pkg/kvp/ginsu/util.go new file mode 100644 index 0000000000..49e5e27487 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/kvp/ginsu/util.go @@ -0,0 +1,46 @@ +package ginsu + +// +// This function is purposely "namespaces" for easy and +// lightweight vendoring. +// + +import ( + "bytes" +) + +const ( + // KvpValueMaxLen is the maximum real-world length of bytes that can + // be stored in the value of the wmi key-value pair data exchange + KvpValueMaxLen = int(990) +) + +// Dice takes input and splits it into a string array so it can be +// passed by hyperv and wmi. Each part must be less than the maximum size +// of a kvp value +func Dice(k *bytes.Reader) ([]string, error) { + var ( + // done is a simple bool indicator that we no longer + // need to iterate + done bool + parts []string + ) + for { + sl := make([]byte, KvpValueMaxLen) + n, err := k.Read(sl) + if err != nil { + return parts, err + } + // if we read and the length is less that the max read, + // then we are at the end + if n < KvpValueMaxLen { + sl = sl[0:n] + done = true + } + parts = append(parts, string(sl)) + if done { + break + } + } + return parts, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/array.go b/vendor/github.com/containers/libhvee/pkg/wmiext/array.go new file mode 100644 index 0000000000..2b92dc80ba --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/array.go @@ -0,0 +1,202 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "errors" + "fmt" + "reflect" + "unsafe" + + "github.com/go-ole/go-ole" +) + +func CreateStringArrayVariant(array []string) (ole.VARIANT, error) { + safeByteArray, err := safeArrayFromStringSlice(array) + if err != nil { + return ole.VARIANT{}, err + } + arrayVariant := ole.NewVariant(ole.VT_ARRAY|ole.VT_BSTR, int64(uintptr(unsafe.Pointer(safeByteArray)))) + return arrayVariant, nil +} + +func CreateNumericArrayVariant(array interface{}, itemType ole.VT) (ole.VARIANT, error) { + safeArray, err := safeArrayFromNumericSlice(array, itemType) + if err != nil { + return ole.VARIANT{}, err + } + arrayVariant := ole.NewVariant(ole.VT_ARRAY|itemType, int64(uintptr(unsafe.Pointer(safeArray)))) + return arrayVariant, nil +} + +// The following safearray routines are unfortunately not yet exported from go-ole, +// so replicate them for now +func safeArrayCreateVector(variantType ole.VT, lowerBound int32, length uint32) (safearray *ole.SafeArray, err error) { + ret, _, _ := procSafeArrayCreateVector.Call( + uintptr(variantType), + uintptr(lowerBound), + uintptr(length)) + + if ret == 0 { // NULL return value + err = fmt.Errorf("could not create safe array") + } + safearray = (*ole.SafeArray)(unsafe.Pointer(ret)) + return +} + +func safeArrayFromNumericSlice(slice interface{}, itemType ole.VT) (*ole.SafeArray, error) { + sliceType := reflect.TypeOf(slice) + if sliceType.Kind() != reflect.Slice { + return nil, errors.New("expected a slice converting to safe array") + } + + val := reflect.ValueOf(slice) + + array, err := safeArrayCreateVector(itemType, 0, uint32(val.Len())) + if err != nil { + return nil, err + } + + // assignable holders used for conversion + var ( + vui1 uint8 + vui2 uint16 + vui4 uint32 + vui8 uint64 + vi1 int8 + vi2 int16 + vi4 int32 + vi8 int64 + ) + + for i := 0; i < val.Len(); i++ { + var data uintptr + item := val.Index(i) + switch itemType { + case ole.VT_UI1: + data = convertToUnsafeAddr(item, &vui1) + case ole.VT_UI2: + data = convertToUnsafeAddr(item, &vui2) + case ole.VT_UI4: + data = convertToUnsafeAddr(item, &vui4) + case ole.VT_UI8: + data = convertToUnsafeAddr(item, &vui8) + case ole.VT_I1: + data = convertToUnsafeAddr(item, &vi1) + case ole.VT_I2: + data = convertToUnsafeAddr(item, &vi2) + case ole.VT_I4: + data = convertToUnsafeAddr(item, &vi4) + case ole.VT_I8: + data = convertToUnsafeAddr(item, &vi8) + } + + err = safeArrayPutElement(array, int64(i), data) + if err != nil { + _ = safeArrayDestroy(array) + return nil, err + } + } + + return array, nil +} + +func convertToUnsafeAddr(src reflect.Value, target interface{}) uintptr { + val := reflect.ValueOf(target) + val = val.Elem() + val.Set(src.Convert(val.Type())) + return val.UnsafeAddr() +} + +func safeArrayDestroy(safearray *ole.SafeArray) (err error) { + ret, _, _ := procSafeArrayDestroy.Call(uintptr(unsafe.Pointer(safearray))) + + if ret != 0 { + return ole.NewError(ret) + } + + return nil +} + +func safeArrayPutElement(safearray *ole.SafeArray, index int64, element uintptr) (err error) { + + ret, _, _ := procSafeArrayPutElement.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&index)), + element) + + if ret != 0 { + return ole.NewError(ret) + } + + return nil +} + +func safeArrayGetElement(safearray *ole.SafeArray, index int64, element unsafe.Pointer) error { + + ret, _, _ := procSafeArrayGetElement.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&index)), + uintptr(element)) + + if ret != 0 { + return ole.NewError(ret) + } + + return nil +} + +func isVariantValConvertible(variant ole.VARIANT) bool { + return !(variant.VT == ole.VT_RECORD || variant.VT == ole.VT_VARIANT) +} + +func safeArrayGetAsVariantVal(safeArray *ole.SafeArray, index int64, variant ole.VARIANT) (int64, error) { + var block int64 + + if !isVariantValConvertible(variant) { + return 0, fmt.Errorf("numeric call on a non-numeric value: %d", variant.VT) + } + + if err := safeArrayGetElement(safeArray, index, unsafe.Pointer(&block)); err != nil { + return 0, err + } + + switch variant.VT { + case ole.VT_UI1: + return int64(uint64(*(*uint8)(unsafe.Pointer(&block)))), nil + case ole.VT_UI2: + return int64(uint64(*(*uint16)(unsafe.Pointer(&block)))), nil + case ole.VT_UI4: + return int64(uint64(*(*uint32)(unsafe.Pointer(&block)))), nil + case ole.VT_I1: + return int64(*(*int8)(unsafe.Pointer(&block))), nil + case ole.VT_I2: + return int64(*(*int16)(unsafe.Pointer(&block))), nil + case ole.VT_I4: + return int64(*(*int32)(unsafe.Pointer(&block))), nil + case ole.VT_UI8, ole.VT_I8: + fallthrough + case ole.VT_R4, ole.VT_R8: + fallthrough + default: + return block, nil + } +} + +func safeArrayFromStringSlice(slice []string) (*ole.SafeArray, error) { + array, err := safeArrayCreateVector(ole.VT_BSTR, 0, uint32(len(slice))) + + if err != nil { + return nil, err + } + + for i, v := range slice { + err = safeArrayPutElement(array, int64(i), uintptr(unsafe.Pointer(ole.SysAllocStringLen(v)))) + if err != nil { + _ = safeArrayDestroy(array) + return nil, err + } + } + return array, nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/conversion.go b/vendor/github.com/containers/libhvee/pkg/wmiext/conversion.go new file mode 100644 index 0000000000..9dc9690606 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/conversion.go @@ -0,0 +1,474 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "errors" + "fmt" + "math" + "reflect" + "strconv" + "strings" + "time" + "unsafe" + + "github.com/go-ole/go-ole" +) + +var ( + unixEpoch = time.Unix(0, 0) + zeroTime = time.Time{} +) + +// Automation variants do not follow the OLE rules, instead they use the following mapping: +// sint8 VT_I2 Signed 8-bit integer. +// sint16 VT_I2 Signed 16-bit integer. +// sint32 VT_I4 Signed 32-bit integer. +// sint64 VT_BSTR Signed 64-bit integer in string form. This type follows hexadecimal or decimal format +// +// according to the American National Standards Institute (ANSI) C rules. +// +// real32 VT_R4 4-byte floating-point value that follows the Institute of Electrical and Electronics +// +// Engineers, Inc. (IEEE) standard. +// +// real64 VT_R8 8-byte floating-point value that follows the IEEE standard. +// uint8 VT_UI1 Unsigned 8-bit integer. +// uint16 VT_I4 Unsigned 16-bit integer. +// uint32 VT_I4 Unsigned 32-bit integer. +// uint64 VT_BSTR Unsigned 64-bit integer in string form. This type follows hexadecimal or decimal format +// +// according to ANSI C rules. + +// NewAutomationVariant returns a new VARIANT com +// +//gocyclo:ignore +func NewAutomationVariant(value interface{}) (ole.VARIANT, error) { + switch cast := value.(type) { + case bool: + if cast { + return ole.NewVariant(ole.VT_BOOL, 0xffff), nil + } else { + return ole.NewVariant(ole.VT_BOOL, 0), nil + } + case int8: + return ole.NewVariant(ole.VT_I2, int64(cast)), nil + case []int8: + return CreateNumericArrayVariant(cast, ole.VT_I2) + case int16: + return ole.NewVariant(ole.VT_I2, int64(cast)), nil + case []int16: + return CreateNumericArrayVariant(cast, ole.VT_I2) + case int32: + return ole.NewVariant(ole.VT_I4, int64(cast)), nil + case []int32: + return CreateNumericArrayVariant(cast, ole.VT_I4) + case int64: + s := fmt.Sprintf("%d", cast) + return ole.NewVariant(ole.VT_BSTR, int64(uintptr(unsafe.Pointer(ole.SysAllocStringLen(s))))), nil + case []int64: + strs := make([]string, len(cast)) + for i, num := range cast { + strs[i] = fmt.Sprintf("%d", num) + } + return CreateStringArrayVariant(strs) + case float32: + return ole.NewVariant(ole.VT_R4, int64(math.Float32bits(cast))), nil + case float64: + return ole.NewVariant(ole.VT_R8, int64(math.Float64bits(cast))), nil + case uint8: + return ole.NewVariant(ole.VT_UI1, int64(cast)), nil + case []uint8: + return CreateNumericArrayVariant(cast, ole.VT_UI1) + case uint16: + return ole.NewVariant(ole.VT_I4, int64(cast)), nil + case []uint16: + return CreateNumericArrayVariant(cast, ole.VT_I4) + case uint32: + return ole.NewVariant(ole.VT_I4, int64(cast)), nil + case []uint32: + return CreateNumericArrayVariant(cast, ole.VT_I4) + case uint64: + s := fmt.Sprintf("%d", cast) + return ole.NewVariant(ole.VT_BSTR, int64(uintptr(unsafe.Pointer(ole.SysAllocStringLen(s))))), nil + case []uint64: + strs := make([]string, len(cast)) + for i, num := range cast { + strs[i] = fmt.Sprintf("%d", num) + } + return CreateStringArrayVariant(strs) + + // Assume 32 bit for generic (u)ints + case int: + return ole.NewVariant(ole.VT_I4, int64(cast)), nil + case uint: + return ole.NewVariant(ole.VT_I4, int64(cast)), nil + case []int: + return CreateNumericArrayVariant(cast, ole.VT_I4) + case []uint: + return CreateNumericArrayVariant(cast, ole.VT_I4) + + case string: + return ole.NewVariant(ole.VT_BSTR, int64(uintptr(unsafe.Pointer(ole.SysAllocStringLen(value.(string)))))), nil + case []string: + if len(cast) == 0 { + return ole.NewVariant(ole.VT_NULL, 0), nil + } + return CreateStringArrayVariant(cast) + + case time.Time: + return convertTimeToDataTime(&cast), nil + case *time.Time: + return convertTimeToDataTime(cast), nil + case time.Duration: + return convertDurationToDateTime(cast), nil + case nil: + return ole.NewVariant(ole.VT_NULL, 0), nil + case *ole.IUnknown: + if cast == nil { + return ole.NewVariant(ole.VT_NULL, 0), nil + } + return ole.NewVariant(ole.VT_UNKNOWN, int64(uintptr(unsafe.Pointer(cast)))), nil + case *Instance: + if cast == nil { + return ole.NewVariant(ole.VT_NULL, 0), nil + } + return ole.NewVariant(ole.VT_UNKNOWN, int64(uintptr(unsafe.Pointer(cast.object)))), nil + default: + return ole.VARIANT{}, fmt.Errorf("unsupported type for automation variants %T", value) + } +} + +func convertToGoType(variant *ole.VARIANT, outputValue reflect.Value, outputType reflect.Type) (value interface{}, err error) { + if variant.VT&ole.VT_ARRAY == ole.VT_ARRAY { + return convertVariantToArray(variant, outputType) + } + + if variant.VT == ole.VT_UNKNOWN { + return convertVariantToStruct(variant, outputType) + } + + switch cast := outputValue.Interface().(type) { + case bool: + return variant.Val != 0, nil + case time.Time: + return convertDataTimeToTime(variant) + case *time.Time: + x, err := convertDataTimeToTime(variant) + return &x, err + case time.Duration: + return convertIntervalToDuration(variant) + case uint, uint8, uint16, uint32, uint64, int, int8, int16, int32, int64: + return convertVariantToInt(variant, outputType) + case float32, float64: + return convertVariantToFloat(variant, outputType) + case string: + return variant.ToString(), nil + default: + if variant.VT == ole.VT_NULL { + return nil, nil + } + return nil, fmt.Errorf("could not convert %d to %v", variant.VT, cast) + } +} + +func convertInt64ToInt(value int64, outputType reflect.Type) (interface{}, error) { + switch outputType.Kind() { + case reflect.Int: + return int(value), nil + case reflect.Int8: + return int8(value), nil + case reflect.Int16: + return int16(value), nil + case reflect.Int32: + return int32(value), nil + case reflect.Int64: + return int64(value), nil + case reflect.Uint: + return uint(value), nil + case reflect.Uint8: + return uint8(value), nil + case reflect.Uint16: + return uint16(value), nil + case reflect.Uint32: + return uint32(value), nil + case reflect.Uint64: + return uint64(value), nil + default: + return 0, fmt.Errorf("could not convert int64 to %v", outputType) + } +} + +func convertStringToInt64(str string, unsigned bool) (int64, error) { + if unsigned { + val, err := strconv.ParseUint(str, 0, 64) + return int64(val), err + } + + return strconv.ParseInt(str, 0, 64) +} + +func convertVariantToInt(variant *ole.VARIANT, outputType reflect.Type) (interface{}, error) { + var value int64 + switch variant.VT { + case ole.VT_NULL: + fallthrough + case ole.VT_BOOL: + fallthrough + case ole.VT_I1, ole.VT_I2, ole.VT_I4, ole.VT_I8, ole.VT_INT: + fallthrough + case ole.VT_UI1, ole.VT_UI2, ole.VT_UI4, ole.VT_UI8, ole.VT_UINT: + value = variant.Val + case ole.VT_R4: + // not necessarily a useful conversion but handle it anyway + value = int64(*(*float32)(unsafe.Pointer(&variant.Val))) + case ole.VT_R8: + value = int64(*(*float64)(unsafe.Pointer(&variant.Val))) + case ole.VT_BSTR: + var err error + value, err = convertStringToInt64(variant.ToString(), outputType.Kind() == reflect.Uint64) + if err != nil { + return value, err + } + default: + return nil, fmt.Errorf("could not convert variant type %d to %v", variant.VT, outputType) + } + + return convertInt64ToInt(value, outputType) +} + +func convertVariantToFloat(variant *ole.VARIANT, outputType reflect.Type) (interface{}, error) { + var value float64 + switch variant.VT { + case ole.VT_NULL: + fallthrough + case ole.VT_BOOL: + fallthrough + case ole.VT_I1, ole.VT_I2, ole.VT_I4, ole.VT_I8, ole.VT_INT: + fallthrough + case ole.VT_UI1, ole.VT_UI2, ole.VT_UI4, ole.VT_UI8, ole.VT_UINT: + value = float64(variant.Val) + case ole.VT_R4: + value = float64(*(*float32)(unsafe.Pointer(&variant.Val))) + case ole.VT_R8: + value = *(*float64)(unsafe.Pointer(&variant.Val)) + case ole.VT_BSTR: + var err error + value, err = strconv.ParseFloat(variant.ToString(), 64) + if err != nil { + return value, err + } + default: + return nil, fmt.Errorf("could not convert variant type %d to %v", variant.VT, outputType) + } + + if outputType.Kind() == reflect.Float32 { + return float32(value), nil + } + + return value, nil +} + +func convertVariantToStruct(variant *ole.VARIANT, outputType reflect.Type) (interface{}, error) { + if variant.VT != ole.VT_UNKNOWN { + return nil, fmt.Errorf("could not convert non-IUnknown variant type %d to %v", variant.VT, outputType) + } + + ptr := variant.ToIUnknown() + + var rawInstance struct { + *ole.IUnknown + *IWbemClassObjectVtbl + } + + rawInstance.IUnknown = ptr + rawInstance.IWbemClassObjectVtbl = (*IWbemClassObjectVtbl)(unsafe.Pointer(ptr.RawVTable)) + + instance := (*Instance)(unsafe.Pointer(&rawInstance)) + val := reflect.New(outputType) + err := instance.GetAll(val.Interface()) + return val.Elem().Interface(), err +} + +func convertVariantToArray(variant *ole.VARIANT, outputType reflect.Type) (interface{}, error) { + if variant.VT&ole.VT_ARRAY != ole.VT_ARRAY { + return nil, fmt.Errorf("could not convert non-array variant type %d to %v", variant.VT, outputType) + } + + safeArrayConversion := ole.SafeArrayConversion{Array: *(**ole.SafeArray)(unsafe.Pointer(&variant.Val))} + + arrayLen, err := safeArrayConversion.TotalElements(0) + if err != nil { + return nil, err + } + elemVT := (^ole.VT_ARRAY) & variant.VT + slice := reflect.MakeSlice(reflect.SliceOf(outputType.Elem()), int(arrayLen), int(arrayLen)) + + for i := 0; i < int(arrayLen); i++ { + elemVariant := ole.VARIANT{VT: elemVT} + elemSrc, err := safeArrayGetAsVariantVal(safeArrayConversion.Array, int64(i), elemVariant) + if err != nil { + return nil, err + } + elemVariant.Val = int64(elemSrc) + elemDest, err := convertToGoType(&elemVariant, slice.Index(i), outputType.Elem()) + if err != nil { + return nil, err + } + + slice.Index(i).Set(reflect.ValueOf(elemDest)) + } + + return slice.Interface(), nil +} + +func convertToGenericValue(variant *ole.VARIANT) interface{} { + var result interface{} + if variant.VT&ole.VT_ARRAY == ole.VT_ARRAY { + safeArrayConversion := ole.SafeArrayConversion{Array: *(**ole.SafeArray)(unsafe.Pointer(&variant.Val))} + result = safeArrayConversion.ToValueArray() + } else { + result = variant.Value() + } + return result +} + +func convertTimeToDataTime(time *time.Time) ole.VARIANT { + if time == nil || !time.After(WindowsEpoch) { + return ole.NewVariant(ole.VT_NULL, 0) + } + _, offset := time.Zone() + // convert to minutes + offset /= 60 + //yyyymmddHHMMSS.mmmmmmsUUU + s := fmt.Sprintf("%s%+04d", time.Format("20060102150405.000000"), offset) + return ole.NewVariant(ole.VT_BSTR, int64(uintptr(unsafe.Pointer(ole.SysAllocStringLen(s))))) +} + +func convertDurationToDateTime(duration time.Duration) ole.VARIANT { + const daySeconds = time.Second * 86400 + + if duration == 0 { + return ole.NewVariant(ole.VT_NULL, 0) + } + + days := duration / daySeconds + duration = duration % daySeconds + + hours := duration / time.Hour + duration = duration % time.Hour + + mins := duration / time.Minute + duration = duration % time.Minute + + seconds := duration / time.Second + duration = duration % time.Second + + micros := duration / time.Microsecond + + s := fmt.Sprintf("%08d%02d%02d%02d.%06d:000", days, hours, mins, seconds, micros) + return ole.NewVariant(ole.VT_BSTR, int64(uintptr(unsafe.Pointer(ole.SysAllocStringLen(s))))) +} + +func extractDateTimeString(variant *ole.VARIANT) (string, error) { + switch variant.VT { + case ole.VT_BSTR: + return variant.ToString(), nil + case ole.VT_NULL: + return "", nil + default: + return "", errors.New("variant not compatible with dateTime field") + } +} + +func convertDataTimeToTime(variant *ole.VARIANT) (time.Time, error) { + var err error + dateTime, err := extractDateTimeString(variant) + if err != nil || len(dateTime) == 0 { + return zeroTime, err + } + + dLen := len(dateTime) + if dLen < 5 { + return zeroTime, errors.New("invalid datetime string") + } + + if strings.HasPrefix(dateTime, "00000000000000.000000") { + // Zero time + return zeroTime, nil + } + + zoneStart := dLen - 4 + timePortion := dateTime[0:zoneStart] + + var zoneMinutes int64 + if dateTime[zoneStart] == ':' { + // interval ends in :000 + return parseIntervalTime(dateTime) + } + + zoneSuffix := dateTime[zoneStart:dLen] + zoneMinutes, err = strconv.ParseInt(zoneSuffix, 10, 0) + if err != nil { + return zeroTime, errors.New("invalid datetime string, zone did not parse") + } + + timePortion = fmt.Sprintf("%s%+03d%02d", timePortion, zoneMinutes/60, abs(int(zoneMinutes%60))) + return time.Parse("20060102150405.000000-0700", timePortion) +} + +// parseIntervalTime encodes an interval time as an offset to Unix time +// allowing a duration to be computed without precision loss +func parseIntervalTime(interval string) (time.Time, error) { + if len(interval) < 25 || interval[21:22] != ":" { + return time.Time{}, fmt.Errorf("invalid interval time: %s", interval) + } + + days, err := parseUintChain(interval[0:8], nil) + hours, err := parseUintChain(interval[8:10], err) + mins, err := parseUintChain(interval[10:12], err) + secs, err := parseUintChain(interval[12:14], err) + micros, err := parseUintChain(interval[15:21], err) + + if err != nil { + return time.Time{}, err + } + + var stamp uint64 = secs + stamp += days * 86400 + stamp += hours * 3600 + stamp += mins * 60 + + return time.Unix(int64(stamp), int64(micros*1000)), nil +} + +func convertIntervalToDuration(variant *ole.VARIANT) (time.Duration, error) { + var err error + interval, err := extractDateTimeString(variant) + if err != nil || len(interval) == 0 { + return 0, err + } + + t, err := parseIntervalTime(interval) + if err != nil { + return 0, nil + } + + return t.Sub(unixEpoch), nil +} + +func parseUintChain(str string, err error) (uint64, error) { + if err != nil { + return 0, err + } + return strconv.ParseUint(str, 10, 0) +} + +func abs(num int) int { + if num < 0 { + return -num + } + + return num +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/enum.go b/vendor/github.com/containers/libhvee/pkg/wmiext/enum.go new file mode 100644 index 0000000000..7f1f562198 --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/enum.go @@ -0,0 +1,94 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "fmt" + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +type IEnumWbemClassObjectVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + Reset uintptr + Next uintptr + NextAsync uintptr + Clone uintptr + Skip uintptr +} + +type Enum struct { + enum *ole.IUnknown + vTable *IEnumWbemClassObjectVtbl + service *Service +} + +func (e *Enum) Close() { + if e != nil && e.enum != nil { + e.enum.Release() + } +} + +func newEnum(enumerator *ole.IUnknown, service *Service) *Enum { + return &Enum{ + enum: enumerator, + vTable: (*IEnumWbemClassObjectVtbl)(unsafe.Pointer(enumerator.RawVTable)), + service: service, + } +} + +// NextObject obtains the next instance in an enumeration and sets all fields +// of the struct pointer passed through the target parameter. Otherwise, if +// the target parameter is not a struct pointer type, an error will be +// returned. +func NextObject(enum *Enum, target interface{}) (bool, error) { + var err error + + var instance *Instance + if instance, err = enum.Next(); err != nil { + return false, err + } + + if instance == nil { + return true, nil + } + + defer instance.Close() + + return false, instance.GetAll(target) +} + +// Next returns the next object instance in this iteration +func (e *Enum) Next() (instance *Instance, err error) { + var res uintptr + var apObjects *ole.IUnknown + var uReturned uint32 + + res, _, _ = syscall.SyscallN( + e.vTable.Next, // IEnumWbemClassObject::Next() + uintptr(unsafe.Pointer(e.enum)), // IEnumWbemClassObject ptr + uintptr(WBEM_INFINITE), // [in] long lTimeout, + uintptr(1), // [in] ULONG uCount, + uintptr(unsafe.Pointer(&apObjects)), // [out] IWbemClassObject **apObjects, + uintptr(unsafe.Pointer(&uReturned))) // [out] ULONG *puReturned) + if res < 0 { + return nil, ole.NewError(res) + } + + if uReturned < 1 { + switch res { + case WBEM_S_NO_ERROR, WBEM_S_FALSE: + // No more elements + return nil, nil + default: + return nil, fmt.Errorf("failure advancing enumeration (%d)", res) + } + } + + return newInstance(apObjects, e.service), nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/init.go b/vendor/github.com/containers/libhvee/pkg/wmiext/init.go new file mode 100644 index 0000000000..03ca4f585f --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/init.go @@ -0,0 +1,113 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "github.com/go-ole/go-ole" + "github.com/sirupsen/logrus" + "golang.org/x/sys/windows" +) + +var ( + ole32 = windows.NewLazySystemDLL("ole32.dll") + procCoSetProxyBlanket = ole32.NewProc("CoSetProxyBlanket") + procCoInitializeSecurity = ole32.NewProc("CoInitializeSecurity") + + modoleaut32 = windows.NewLazySystemDLL("oleaut32.dll") + procSafeArrayCreateVector = modoleaut32.NewProc("SafeArrayCreateVector") + procSafeArrayPutElement = modoleaut32.NewProc("SafeArrayPutElement") + procSafeArrayGetElement = modoleaut32.NewProc("SafeArrayGetElement") + procSafeArrayDestroy = modoleaut32.NewProc("SafeArrayDestroy") + + clsidWbemObjectTextSrc = ole.NewGUID("{8d1c559d-84f0-4bb3-a7d5-56a7435a9ba6}") + iidIWbemObjectTextSrc = ole.NewGUID("{bfbf883a-cad7-11d3-a11b-00105a1f515a}") + + wmiWbemTxtLocator *ole.IUnknown + wmiWbemLocator *ole.IUnknown + + clsidWbemLocator = ole.NewGUID("4590f811-1d3a-11d0-891f-00aa004b2e24") + iidIWbemLocator = ole.NewGUID("dc12a687-737f-11cf-884d-00aa004b2e24") +) + +const ( + // WMI HRESULT values + WBEM_S_NO_ERROR = 0 + WBEM_S_FALSE = 1 + WBEM_S_NO_MORE_DATA = 0x40005 + + // WMI Generic flags + WBEM_FLAG_RETURN_WBEM_COMPLETE = 0x0 + WBEM_FLAG_RETURN_IMMEDIATELY = 0x10 + WBEM_FLAG_FORWARD_ONLY = 0x20 + + // WMI Query flags + WBEM_FLAG_SHALLOW = 1 + + // Timeout flags + WBEM_NO_WAIT = 0 + WBEM_INFINITE = 0xFFFFFFFF + + // COM Auth Flags + EOAC_NONE = 0 + + // RPC Authentication + RPC_C_AUTHN_WINNT = 10 + + // RPC Authentication Level + RPC_C_AUTHN_LEVEL_DEFAULT = 0 + RPC_C_AUTHN_LEVEL_CALL = 3 + + // RPC Authorization + RPC_C_AUTHZ_NONE = 0 + + // RPC Impersonation + RPC_C_IMP_LEVEL_IMPERSONATE = 3 +) + +func init() { + var err error + + err = ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED) + if err != nil { + if oleCode, ok := err.(*ole.OleError); ok { + code := oleCode.Code() + // 1 = Already init + if code != 0 && code != 1 { + logrus.Errorf("Unable to initialize COM: %s", err.Error()) + return + } + } + } + + initSecurity() + + wmiWbemLocator, err = ole.CreateInstance(clsidWbemLocator, iidIWbemLocator) + if err != nil { + logrus.Errorf("Could not initialize Wbem components, WMI operations will likely fail %s", err.Error()) + } + + // IID_IWbemObjectTextSrc Obtain the initial locator to WMI + wmiWbemTxtLocator, err = ole.CreateInstance(clsidWbemObjectTextSrc, iidIWbemObjectTextSrc) + if err != nil { + logrus.Errorf("Could not initialize Wbem components, WMI operations will likely fail %s", err.Error()) + } +} + +func initSecurity() { + var svc int32 = -1 + + res, _, _ := procCoInitializeSecurity.Call( // CoInitializeSecurity + uintptr(0), // [in, optional] PSECURITY_DESCRIPTOR pSecDesc, + uintptr(svc), // [in] LONG cAuthSvc, + uintptr(0), // [in, optional] SOLE_AUTHENTICATION_SERVICE *asAuthSvc, + uintptr(0), // [in, optional] void *pReserved1, + uintptr(RPC_C_AUTHN_LEVEL_DEFAULT), // [in] DWORD dwAuthnLevel, + uintptr(RPC_C_IMP_LEVEL_IMPERSONATE), // [in] DWORD dwImpLevel, + uintptr(0), // [in, optional] void *pAuthList, + uintptr(EOAC_NONE), // [in] DWORD dwCapabilities, + uintptr(0)) // [in, optional] void *pReserved3 + if res < 0 { + logrus.Errorf("Unable to initialize COM security: %s", ole.NewError(res).Error()) + } +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/instance.go b/vendor/github.com/containers/libhvee/pkg/wmiext/instance.go new file mode 100644 index 0000000000..8aece77aea --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/instance.go @@ -0,0 +1,634 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "syscall" + "time" + "unsafe" + + "github.com/go-ole/go-ole" +) + +const ( + WmiPathKey = "__PATH" +) + +var ( + WindowsEpoch = time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC) +) + +type Instance struct { + object *ole.IUnknown + vTable *IWbemClassObjectVtbl + service *Service +} + +type IWbemClassObjectVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + GetQualifierSet uintptr + Get uintptr + Put uintptr + Delete uintptr + GetNames uintptr + BeginEnumeration uintptr + Next uintptr + EndEnumeration uintptr + GetPropertyQualifierSet uintptr + Clone uintptr + GetObjectText uintptr + SpawnDerivedClass uintptr + SpawnInstance uintptr + CompareTo uintptr + GetPropertyOrigin uintptr + InheritsFrom uintptr + GetMethod uintptr + PutMethod uintptr + DeleteMethod uintptr + BeginMethodEnumeration uintptr + NextMethod uintptr + EndMethodEnumeration uintptr + GetMethodQualifierSet uintptr + GetMethodOrigin uintptr +} + +type CIMTYPE_ENUMERATION uint32 + +const ( + CIM_ILLEGAL CIMTYPE_ENUMERATION = 0xFFF + CIM_EMPTY CIMTYPE_ENUMERATION = 0 + CIM_SINT8 CIMTYPE_ENUMERATION = 16 + CIM_UINT8 CIMTYPE_ENUMERATION = 17 + CIM_SINT16 CIMTYPE_ENUMERATION = 2 + CIM_UINT16 CIMTYPE_ENUMERATION = 18 + CIM_SINT32 CIMTYPE_ENUMERATION = 3 + CIM_UINT32 CIMTYPE_ENUMERATION = 19 + CIM_SINT64 CIMTYPE_ENUMERATION = 20 + CIM_UINT64 CIMTYPE_ENUMERATION = 21 + CIM_REAL32 CIMTYPE_ENUMERATION = 4 + CIM_REAL64 CIMTYPE_ENUMERATION = 5 + CIM_BOOLEAN CIMTYPE_ENUMERATION = 11 + CIM_STRING CIMTYPE_ENUMERATION = 8 + CIM_DATETIME CIMTYPE_ENUMERATION = 101 + CIM_REFERENCE CIMTYPE_ENUMERATION = 102 + CIM_CHAR16 CIMTYPE_ENUMERATION = 103 + CIM_OBJECT CIMTYPE_ENUMERATION = 13 + CIM_FLAG_ARRAY CIMTYPE_ENUMERATION = 0x2000 +) + +type WBEM_FLAVOR_TYPE uint32 + +const ( + WBEM_FLAVOR_DONT_PROPAGATE WBEM_FLAVOR_TYPE = 0 + WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE WBEM_FLAVOR_TYPE = 0x1 + WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS WBEM_FLAVOR_TYPE = 0x2 + WBEM_FLAVOR_MASK_PROPAGATION WBEM_FLAVOR_TYPE = 0xf + WBEM_FLAVOR_OVERRIDABLE WBEM_FLAVOR_TYPE = 0 + WBEM_FLAVOR_NOT_OVERRIDABLE WBEM_FLAVOR_TYPE = 0x10 + WBEM_FLAVOR_MASK_PERMISSIONS WBEM_FLAVOR_TYPE = 0x10 + WBEM_FLAVOR_ORIGIN_LOCAL WBEM_FLAVOR_TYPE = 0 + WBEM_FLAVOR_ORIGIN_PROPAGATED WBEM_FLAVOR_TYPE = 0x20 + WBEM_FLAVOR_ORIGIN_SYSTEM WBEM_FLAVOR_TYPE = 0x40 + WBEM_FLAVOR_MASK_ORIGIN WBEM_FLAVOR_TYPE = 0x60 + WBEM_FLAVOR_NOT_AMENDED WBEM_FLAVOR_TYPE = 0 + WBEM_FLAVOR_AMENDED WBEM_FLAVOR_TYPE = 0x80 + WBEM_FLAVOR_MASK_AMENDED WBEM_FLAVOR_TYPE = 0x80 +) + +func newInstance(object *ole.IUnknown, service *Service) *Instance { + instance := &Instance{ + object: object, + vTable: (*IWbemClassObjectVtbl)(unsafe.Pointer(object.RawVTable)), + service: service, + } + + return instance +} + +// Close cleans up all memory associated with this instance. +func (i *Instance) Close() { + if i != nil && i.object != nil { + i.object.Release() + } +} + +// GetClassName Gets the WMI class name for this WMI object instance +func (i *Instance) GetClassName() (className string, err error) { + return i.GetAsString(`__CLASS`) +} + +// Path gets the WMI object path of this instance +func (i *Instance) Path() (string, error) { + ref, _, _, err := i.GetAsAny(WmiPathKey) + return ref.(string), err +} + +// IsReferenceProperty returns whether the property is of type CIM_REFERENCE, a string which points to +// an object path of another instance. +func (i *Instance) IsReferenceProperty(name string) (bool, error) { + _, cimType, _, err := i.GetAsAny(name) + return cimType == CIM_REFERENCE, err +} + +// SpawnInstance create a new WMI object instance that is zero-initialized. The returned instance +// will not respect expected default values, which must be populated by other means. +func (i *Instance) SpawnInstance() (instance *Instance, err error) { + var res uintptr + var newUnknown *ole.IUnknown + + res, _, _ = syscall.SyscallN( + i.vTable.SpawnInstance, // IWbemClassObject::SpawnInstance( + uintptr(unsafe.Pointer(i.object)), // IWbemClassObject ptr + uintptr(0), // [in] long lFlags, + uintptr(unsafe.Pointer(&newUnknown))) // [out] IWbemClassObject **ppNewInstance) + if res != 0 { + return nil, ole.NewError(res) + } + + return newInstance(newUnknown, i.service), nil +} + +// CloneInstance create a new cloned copy of this WMI instance. +func (i *Instance) CloneInstance() (*Instance, error) { + classObj := i.object + vTable := (*IWbemClassObjectVtbl)(unsafe.Pointer(classObj.RawVTable)) + var cloned *ole.IUnknown + + ret, _, _ := syscall.SyscallN( + vTable.Clone, // IWbemClassObject::Clone( + uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr + uintptr(unsafe.Pointer(&cloned))) // [out] IWbemClassObject **ppCopy) + if ret != 0 { + return nil, ole.NewError(ret) + } + + return newInstance(cloned, i.service), nil +} + +// PutAll sets all fields of this instance to the passed src parameter's fields, converting accordingly. +// The src parameter must be a pointer to a struct, otherwise an error will be returned. +func (i *Instance) PutAll(src interface{}) error { + val := reflect.ValueOf(src) + if val.Kind() == reflect.Pointer { + val = val.Elem() + } + + if val.Kind() != reflect.Struct { + return errors.New("not a struct or pointer to struct") + } + + props, err := i.GetAllProperties() + if err != nil { + return err + } + + return i.instancePutAllTraverse(val, props) +} + +func (i *Instance) instancePutAllTraverse(val reflect.Value, propMap map[string]interface{}) error { + for j := 0; j < val.NumField(); j++ { + fieldVal := val.Field(j) + fieldType := val.Type().Field(j) + + if fieldType.Type.Kind() == reflect.Struct && fieldType.Anonymous { + if err := i.instancePutAllTraverse(fieldVal, propMap); err != nil { + return err + } + continue + } + if strings.HasPrefix(fieldType.Name, "S__") { + continue + } + + if !fieldType.IsExported() { + continue + } + + if _, exists := propMap[fieldType.Name]; !exists { + continue + } + + if fieldVal.Kind() == reflect.String && fieldVal.Len() == 0 { + continue + } + + if err := i.Put(fieldType.Name, fieldVal.Interface()); err != nil { + return err + } + } + + return nil +} + +// Put sets the specified property to the passed Golang value, converting appropriately. +func (i *Instance) Put(name string, value interface{}) (err error) { + var variant ole.VARIANT + + switch cast := value.(type) { + case ole.VARIANT: + variant = cast + case *ole.VARIANT: + variant = *cast + default: + variant, err = NewAutomationVariant(value) + if err != nil { + return err + } + } + + var wszName *uint16 + if wszName, err = syscall.UTF16PtrFromString(name); err != nil { + return + } + + classObj := i.object + vTable := (*IWbemClassObjectVtbl)(unsafe.Pointer(classObj.RawVTable)) + res, _, _ := syscall.SyscallN( + vTable.Put, // IWbemClassObject::Put( + uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr + uintptr(unsafe.Pointer(wszName)), // [in] LPCWSTR wszName, + uintptr(0), // [in] long lFlags, + uintptr(unsafe.Pointer(&variant)), // [in] VARIANT *pVal, + uintptr(0)) // [in] CIMTYPE Type) + if res != 0 { + return ole.NewError(res) + } + + _ = variant.Clear() + return +} + +// GetCimText returns the CIM XML representation of this instance. Some WMI methods use a string +// parameter to represent a full complex object, and this method is used to generate +// the expected format. +func (i *Instance) GetCimText() string { + type wmiWbemTxtSrcVtable struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + GetTxt uintptr + } + const CIM_XML_FORMAT = 1 + + classObj := i.object + + vTable := (*wmiWbemTxtSrcVtable)(unsafe.Pointer(wmiWbemTxtLocator.RawVTable)) + var retString *uint16 + res, _, _ := syscall.SyscallN( + vTable.GetTxt, // IWbemObjectTextSrc::GetText() + uintptr(unsafe.Pointer(wmiWbemLocator)), // IWbemObjectTextSrc ptr + uintptr(0), // [in] long lFlags + uintptr(unsafe.Pointer(classObj)), // [in] IWbemClassObject *pObj + uintptr(CIM_XML_FORMAT), // [in] ULONG uObjTextFormat, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(&retString))) // [out] BSTR *strText) + if res != 0 { + return "" + } + itemStr := ole.BstrToString(retString) + return itemStr +} + +// GetAll gets all fields that map to a target struct and populates all struct fields according to +// the expected type information. The target parameter should be a pointer to a struct, and +// will return an error otherwise. +func (i *Instance) GetAll(target interface{}) error { + elem := reflect.ValueOf(target) + if elem.Kind() != reflect.Ptr || elem.IsNil() { + return errors.New("invalid destination type for mapping a WMI instance to an object") + } + + // deref pointer + elem = elem.Elem() + var err error + + if err = i.BeginEnumeration(); err != nil { + return err + } + + properties := make(map[string]*ole.VARIANT) + + for { + var name string + var value *ole.VARIANT + var done bool + + if done, name, value, _, _, err = i.NextAsVariant(); err != nil { + return err + } + + if done { + break + } + + if value != nil { + properties[name] = value + } + } + + defer func() { + for _, v := range properties { + _ = v.Clear() + } + }() + + _ = i.EndEnumeration() + + return i.instanceGetAllPopulate(elem, elem.Type(), properties) +} + +// GetAsAny gets a property and converts it to a Golang type that matches the internal +// variant automation type passed back from WMI. For usage with predictable static +// type mapping, use GetAsString(), GetAsUint(), or GetAll() instead of this method. +func (i *Instance) GetAsAny(name string) (interface{}, CIMTYPE_ENUMERATION, WBEM_FLAVOR_TYPE, error) { + variant, cimType, flavor, err := i.GetAsVariant(name) + if err != nil { + return nil, cimType, flavor, err + } + defer variant.Clear() + + // Since there is no type information only perform the stock conversion + result := convertToGenericValue(variant) + + return result, cimType, flavor, err +} + +// GetAsString gets a property value as a string value, converting if necessary +func (i *Instance) GetAsString(name string) (value string, err error) { + variant, _, _, err := i.GetAsVariant(name) + if err != nil || variant == nil { + return "", err + } + defer variant.Clear() + + // TODO: replace with something better + return fmt.Sprintf("%v", convertToGenericValue(variant)), nil +} + +// GetAsUint gets a property value as a uint value, if conversion is possible. Otherwise, +// returns an error. +func (i *Instance) GetAsUint(name string) (uint, error) { + val, _, _, err := i.GetAsAny(name) + if err != nil { + return 0, err + } + + switch ret := val.(type) { + case int: + return uint(ret), nil + case int8: + return uint(ret), nil + case int16: + return uint(ret), nil + case int32: + return uint(ret), nil + case int64: + return uint(ret), nil + case uint: + return ret, nil + case uint8: + return uint(ret), nil + case uint16: + return uint(ret), nil + case uint32: + return uint(ret), nil + case uint64: + return uint(ret), nil + case string: + parse, err := strconv.ParseUint(ret, 10, 64) + return uint(parse), err + default: + return 0, fmt.Errorf("type conversion from %T on param %s not supported", val, name) + } +} + +// GetAsVariant obtains a specified property value, if it exists. +func (i *Instance) GetAsVariant(name string) (*ole.VARIANT, CIMTYPE_ENUMERATION, WBEM_FLAVOR_TYPE, error) { + var variant ole.VARIANT + var err error + var wszName *uint16 + var cimType CIMTYPE_ENUMERATION + var flavor WBEM_FLAVOR_TYPE + + if wszName, err = syscall.UTF16PtrFromString(name); err != nil { + return nil, 0, 0, err + } + + classObj := i.object + vTable := (*IWbemClassObjectVtbl)(unsafe.Pointer(classObj.RawVTable)) + + res, _, _ := syscall.SyscallN( + vTable.Get, // IWbemClassObject::Get( + uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr + uintptr(unsafe.Pointer(wszName)), // [in] LPCWSTR wszName, + uintptr(0), // [in] long lFlags, + uintptr(unsafe.Pointer(&variant)), // [out] VARIANT *pVal, + uintptr(unsafe.Pointer(&cimType)), // [out, optional] CIMTYPE *pType, + uintptr(unsafe.Pointer(&flavor))) // [out, optional] long *plFlavor) + if res != 0 { + return nil, 0, 0, ole.NewError(res) + } + + return &variant, cimType, flavor, nil +} + +// Next retrieves the next property as a Golang type when iterating the properties using an enumerator +// created by BeginEnumeration(). The returned value's type represents the internal automation type +// used by WMI. It is usually preferred to use GetAsXXX(), GetAll(), or GetAll Properties() over this +// method. +func (i *Instance) Next() (done bool, name string, value interface{}, cimType CIMTYPE_ENUMERATION, flavor WBEM_FLAVOR_TYPE, err error) { + var variant *ole.VARIANT + done, name, variant, cimType, flavor, err = i.NextAsVariant() + + if err == nil && !done { + defer variant.Clear() + value = convertToGenericValue(variant) + } + + return +} + +// NextAsVariant retrieves the next property as a VARIANT type when iterating the properties using an enumerator +// created by BeginEnumeration(). The returned value's type represents the internal automation type +// used by WMI. It is usually preferred to use GetAsXXX(), GetAll(), or GetAllProperties() over this +// method. Callers are responsible for clearing the VARIANT, otherwise associated memory will leak. +func (i *Instance) NextAsVariant() (bool, string, *ole.VARIANT, CIMTYPE_ENUMERATION, WBEM_FLAVOR_TYPE, error) { + var res uintptr + var strName *uint16 + var variant ole.VARIANT + var cimType CIMTYPE_ENUMERATION + var flavor WBEM_FLAVOR_TYPE + + res, _, _ = syscall.SyscallN( + i.vTable.Next, // IWbemClassObject::Next( + uintptr(unsafe.Pointer(i.object)), // IWbemClassObject ptr + uintptr(0), // [in] long lFlags, + uintptr(unsafe.Pointer(&strName)), // [out] BSTR *strName, + uintptr(unsafe.Pointer(&variant)), // [out] VARIANT *pVal, + uintptr(unsafe.Pointer(&cimType)), // [out, optional] CIMTYPE *pType, + uintptr(unsafe.Pointer(&flavor))) // [out, optional] long *plFlavor + if res < 0 { + return false, "", nil, cimType, flavor, ole.NewError(res) + } + + if res == WBEM_S_NO_MORE_DATA { + return true, "", nil, cimType, flavor, nil + } + + defer ole.SysFreeString((*int16)(unsafe.Pointer(strName))) + name := ole.BstrToString(strName) + + return false, name, &variant, cimType, flavor, nil +} + +// GetAllProperties gets all properties on this instance. The returned map is keyed by the field name and the value +// is a Golang type which matches the WMI internal implementation. For static type conversions, +// it's recommended to use either GetAll(), which uses struct fields for type information, or +// the GetAsXXX() methods. +func (i *Instance) GetAllProperties() (map[string]interface{}, error) { + var err error + properties := make(map[string]interface{}) + + if err = i.BeginEnumeration(); err != nil { + return nil, err + } + + defer i.EndEnumeration() + + for { + var name string + var value interface{} + var done bool + + if done, name, value, _, _, err = i.Next(); err != nil || done { + return properties, err + } + + properties[name] = value + } +} + +// GetMethodParameters returns a WMI class object which represents the [in] method parameters for a method invocation. +// This is an advanced method, used for dynamic introspection or manual method invocation. In most +// cases it is recommended to use BeginInvoke() instead, which constructs the parameter payload +// automatically. +func (i *Instance) GetMethodParameters(method string) (*Instance, error) { + var err error + var res uintptr + var inSignature *ole.IUnknown + + var wszName *uint16 + if wszName, err = syscall.UTF16PtrFromString(method); err != nil { + return nil, err + } + + res, _, _ = syscall.SyscallN( + i.vTable.GetMethod, // IWbemClassObject::GetMethod( + uintptr(unsafe.Pointer(i.object)), // IWbemClassObject ptr + uintptr(unsafe.Pointer(wszName)), // [in] LPCWSTR wszName + uintptr(0), // [in] long lFlags, + uintptr(unsafe.Pointer(&inSignature)), // [out] IWbemClassObject **ppInSignature, + uintptr(0)) // [out] IWbemClassObject **ppOutSignature) + if res != 0 { + return nil, ole.NewError(res) + } + + return newInstance(inSignature, i.service), nil +} + +func (i *Instance) instanceGetAllPopulate(elem reflect.Value, elemType reflect.Type, properties map[string]*ole.VARIANT) error { + var err error + + for j := 0; j < elemType.NumField(); j++ { + fieldType := elemType.Field(j) + fieldVal := elem.Field(j) + + if !fieldType.IsExported() { + continue + } + + if fieldType.Type.Kind() == reflect.Struct && fieldType.Anonymous { + if err := i.instanceGetAllPopulate(fieldVal, fieldType.Type, properties); err != nil { + return err + } + continue + } + + fieldName := fieldType.Name + + if strings.HasPrefix(fieldName, "S__") { + fieldName = fieldName[1:] + } + if variant, ok := properties[fieldName]; ok { + var val interface{} + if val, err = convertToGoType(variant, fieldVal, fieldType.Type); err != nil { + return err + } + + if val != nil { + fieldVal.Set(reflect.ValueOf(val)) + } + } + } + + return nil +} + +// BeginEnumeration begins iterating the property list on this instance. This is an advanced method. +// In most cases, the GetAsXXX() methods, GetAll(), and GetAllProperties() methods should be +// preferred. +func (i *Instance) BeginEnumeration() error { + classObj := i.object + vTable := (*IWbemClassObjectVtbl)(unsafe.Pointer(classObj.RawVTable)) + + result, _, _ := syscall.SyscallN( + vTable.BeginEnumeration, // IWbemClassObject::BeginEnumeration( + uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr, + uintptr(0)) // [in] long lEnumFlags) // 0 = defaults + if result != 0 { + return ole.NewError(result) + } + + return nil +} + +// EndEnumeration completes iterating a property list on this instance. This is an advanced method. +// In most cases, the GetAsXXX() methods, GetAll(), and GetAllProperties() methods +// should be preferred. +func (i *Instance) EndEnumeration() error { + res, _, _ := syscall.SyscallN( + i.vTable.EndEnumeration, // IWbemClassObject::EndEnumeration( + uintptr(unsafe.Pointer(i.object))) // IWbemClassObject ptr) + if res != 0 { + return ole.NewError(res) + } + + return nil +} + +// BeginInvoke invokes a method on this Instance. Returns a MethodExecutor builder object +// that is used to construct the input parameters (via calls to In()), perform the +// invocation (using calls to Execute()), retrieve output parameters (via calls to +// Out()), and finally the method return value (using a call to End()) +func (i *Instance) BeginInvoke(method string) *MethodExecutor { + objPath, err := i.Path() + if err != nil { + return &MethodExecutor{err: err} + } + + var class, inParam *Instance + if class, err = i.service.GetClassInstance(i); err == nil { + inParam, err = class.GetMethodParameters(method) + class.Close() + } + + return &MethodExecutor{method: method, path: objPath, service: i.service, inParam: inParam, err: err} +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/invoke.go b/vendor/github.com/containers/libhvee/pkg/wmiext/invoke.go new file mode 100644 index 0000000000..8f7f36f66b --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/invoke.go @@ -0,0 +1,125 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "fmt" + "reflect" + + "github.com/go-ole/go-ole" +) + +type MethodExecutor struct { + err error + path string + method string + service *Service + inParam *Instance + outParam *Instance +} + +// In sets an input parameter for the method of this invocation, converting appropriately +func (e *MethodExecutor) In(name string, value interface{}) *MethodExecutor { + if e.err == nil && e.inParam != nil { + switch t := value.(type) { + case *Instance: + var ref bool + if ref, e.err = e.inParam.IsReferenceProperty(name); e.err != nil { + return e + } + if !ref { + // Embedded Object + break + } + if value, e.err = t.Path(); e.err != nil { + return e + } + } + + e.err = e.inParam.Put(name, value) + } + + return e +} + +// Out sets the specified output parameter, and assigns the value parameter to the result. +// The value parameter must be a reference to the field that should be set. +func (e *MethodExecutor) Out(name string, value interface{}) *MethodExecutor { + if e.err == nil && e.outParam != nil { + var variant *ole.VARIANT + var cimType CIMTYPE_ENUMERATION + var result interface{} + dest := reflect.ValueOf(value) + if dest.Kind() != reflect.Ptr { + e.err = fmt.Errorf("Out() on %q called with %T, out parameters must be a reference", name, value) + return e + } + dest = dest.Elem() + + variant, cimType, _, e.err = e.outParam.GetAsVariant(name) + if e.err != nil || variant == nil { + return e + } + defer variant.Clear() + if _, ok := value.(**Instance); ok && cimType == CIM_REFERENCE { + path := variant.ToString() + result, e.err = e.service.GetObject(path) + if e.err != nil { + return e + } + } else { + target := reflect.ValueOf(value).Elem() + result, e.err = convertToGoType(variant, target, target.Type()) + if e.err != nil { + return e + } + } + + newValue := reflect.ValueOf(result) + if result == nil { + // Nil must be typed to the destination + newValue = reflect.Zero(dest.Type()) + } + + dest.Set(newValue) + } + return e +} + +// Execute executes the method after in parameters have been specified using In() +func (e *MethodExecutor) Execute() *MethodExecutor { + defer e.cleanupInputs() + + if e.err == nil { + e.outParam, e.err = e.service.ExecMethod(e.path, e.method, e.inParam) + } + + return e +} + +func (e *MethodExecutor) cleanupInputs() { + if e.inParam != nil { + e.inParam.Close() + e.inParam = nil + } +} + +// End completes the method invocation and returns an error indicating the return +// code of the underlying method +func (e *MethodExecutor) End() error { + e.cleanupInputs() + + if e.outParam != nil { + e.outParam.Close() + e.outParam = nil + } + + return e.err +} + +// Obtains the last error that occurred while building the invocation. Once +// an error has occurred, all future operations are treated as a no-op. +func (e *MethodExecutor) Error() error { + return e.err +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/job.go b/vendor/github.com/containers/libhvee/pkg/wmiext/job.go new file mode 100644 index 0000000000..180c1e515f --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/job.go @@ -0,0 +1,53 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "fmt" + "time" +) + +type JobError struct { + ErrorCode int +} + +func (err *JobError) Error() string { + return fmt.Sprintf("Job failed with error code: %d", err.ErrorCode) +} + +// WaitJob waits on the specified job instance until it has completed and +// returns a JobError containing the result code in the event of +// a failure. +func WaitJob(service *Service, job *Instance) error { + var jobs []*Instance + defer func() { + for _, job := range jobs { + job.Close() + } + }() + for { + state, _, _, err := job.GetAsAny("JobState") + if err != nil { + return err + } + time.Sleep(100 * time.Millisecond) + job, _ = service.RefetchObject(job) + jobs = append(jobs, job) + // 7+ = completed + if state.(int32) >= 7 { + break + } + } + + result, _, _, err := job.GetAsAny("ErrorCode") + if err != nil { + return err + } + + if result.(int32) != 0 { + return &JobError{ErrorCode: int(result.(int32))} + } + + return nil +} diff --git a/vendor/github.com/containers/libhvee/pkg/wmiext/service.go b/vendor/github.com/containers/libhvee/pkg/wmiext/service.go new file mode 100644 index 0000000000..190d83acfb --- /dev/null +++ b/vendor/github.com/containers/libhvee/pkg/wmiext/service.go @@ -0,0 +1,416 @@ +//go:build windows +// +build windows + +package wmiext + +import ( + "errors" + "fmt" + "syscall" + "unsafe" + + "github.com/go-ole/go-ole" +) + +type IWbemLocatorVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + ConnectServer uintptr +} + +type Service struct { + service *ole.IUnknown + vTable *IWbemServicesVtbl +} + +type IWbemServicesVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr + OpenNamespace uintptr + CancelAsyncCall uintptr + QueryObjectSink uintptr + GetObject uintptr + GetObjectAsync uintptr + PutClass uintptr + PutClassAsync uintptr + DeleteClass uintptr + DeleteClassAsync uintptr + CreateClassEnum uintptr + CreateClassEnumAsync uintptr + PutInstance uintptr + PutInstanceAsync uintptr + DeleteInstance uintptr + DeleteInstanceAsync uintptr + CreateInstanceEnum uintptr + CreateInstanceEnumAsync uintptr + ExecQuery uintptr + ExecQueryAsync uintptr + ExecNotificationQuery uintptr + ExecNotificationQueryAsync uintptr + ExecMethod uintptr + ExecMethodAsync uintptr +} + +func connectService(namespace string) (*Service, error) { + + if wmiWbemLocator == nil { + return nil, errors.New("WMI failed initialization, service calls can not proceed") + } + + var err error + var res uintptr + var strResource *uint16 + var strLocale *uint16 + var service *ole.IUnknown + + loc := fmt.Sprintf(`\\.\%s`, namespace) + + if strResource, err = syscall.UTF16PtrFromString(loc); err != nil { + return nil, err + } + + // Connect with en_US LCID since we do pattern matching against English key values + if strLocale, err = syscall.UTF16PtrFromString("MS_409"); err != nil { + return nil, err + } + + myVTable := (*IWbemLocatorVtbl)(unsafe.Pointer(wmiWbemLocator.RawVTable)) + res, _, _ = syscall.SyscallN( + myVTable.ConnectServer, // IWbemLocator::ConnectServer( + uintptr(unsafe.Pointer(wmiWbemLocator)), // IWbemLocator ptr + uintptr(unsafe.Pointer(strResource)), // [in] const BSTR strNetworkResource, + uintptr(0), // [in] const BSTR strUser, + uintptr(0), // [in] const BSTR strPassword, + uintptr(unsafe.Pointer(strLocale)), // [in] const BSTR strLocale, + uintptr(WBEM_FLAG_CONNECT_USE_MAX_WAIT), // [in] long lSecurityFlags, + uintptr(0), // [in] const BSTR strAuthority, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(&service))) // [out] IWbemServices **ppNamespace) + + if res != 0 { + return nil, ole.NewError(res) + } + + if err = CoSetProxyBlanket(service); err != nil { + return nil, err + } + + return newService(service), nil +} + +func newService(service *ole.IUnknown) *Service { + return &Service{ + service: service, + vTable: (*IWbemServicesVtbl)(unsafe.Pointer(service.RawVTable)), + } +} + +const ( + WBEM_FLAG_CONNECT_USE_MAX_WAIT = 0x80 +) + +func CoSetProxyBlanket(service *ole.IUnknown) (err error) { + res, _, _ := procCoSetProxyBlanket.Call( //CoSetProxyBlanket( + uintptr(unsafe.Pointer(service)), // [in] IUnknown *pProxy, + uintptr(RPC_C_AUTHN_WINNT), // [in] DWORD dwAuthnSvc, + uintptr(RPC_C_AUTHZ_NONE), // [in] DWORD dwAuthzSvc, + uintptr(0), // [in, opt] OLECHAR *pServerPrincName, + uintptr(RPC_C_AUTHN_LEVEL_CALL), // [in] DWORD dwAuthnLevel, + uintptr(RPC_C_IMP_LEVEL_IMPERSONATE), // [in] DWORD dwImpLevel, + uintptr(0), // [in, opt] RPC_AUTH_IDENTITY_HANDLE pAuthInfo, + uintptr(EOAC_NONE)) // [in] DWORD dwCapabilities) + + if res != 0 { + return ole.NewError(res) + } + + return nil +} + +// NewLocalService creates a service and connect it to the local system at the specified namespace +func NewLocalService(namespace string) (s *Service, err error) { + return connectService(namespace) +} + +// Close frees all associated memory with this service +func (s *Service) Close() { + if s != nil && s.service != nil { + s.service.Release() + } +} + +// ExecQuery executes a WQL query and returns an enumeration to iterate the result set. +// Queries are executed in a semi-synchronous fashion. +func (s *Service) ExecQuery(wqlQuery string) (*Enum, error) { + var err error + var pEnum *ole.IUnknown + var strQuery *uint16 + var strQL *uint16 + + if strQL, err = syscall.UTF16PtrFromString("WQL"); err != nil { + return nil, err + } + + if strQuery, err = syscall.UTF16PtrFromString(wqlQuery); err != nil { + return nil, err + } + + // Semisynchronous mode = return immed + forward (for perf) + flags := WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY + + hres, _, _ := syscall.SyscallN( + s.vTable.ExecQuery, // IWbemServices::ExecQuery( + uintptr(unsafe.Pointer(s.service)), // IWbemServices ptr + uintptr(unsafe.Pointer(strQL)), // [in] const BSTR strQueryLanguage, + uintptr(unsafe.Pointer(strQuery)), // [in] const BSTR strQuery, + uintptr(flags), // [in] long lFlags, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(&pEnum))) // [out] IEnumWbemClassObject **ppEnum) + if hres != 0 { + return nil, ole.NewError(hres) + } + + if err = CoSetProxyBlanket(pEnum); err != nil { + return nil, err + } + + return newEnum(pEnum, s), nil +} + +// GetObject obtains a single WMI class or instance given its path +func (s *Service) GetObject(objectPath string) (instance *Instance, err error) { + var pObject *ole.IUnknown + var strObjectPath *uint16 + + if strObjectPath, err = syscall.UTF16PtrFromString(objectPath); err != nil { + return + } + + // Synchronous call + flags := WBEM_FLAG_RETURN_WBEM_COMPLETE + + res, _, _ := syscall.SyscallN( + s.vTable.GetObject, // IWbemServices::GetObject( + uintptr(unsafe.Pointer(s.service)), // IWbemServices ptr + uintptr(unsafe.Pointer(strObjectPath)), // [in] const BSTR strObjectPath, + uintptr(flags), // [in] long lFlags, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(&pObject)), // [out] IWbemClassObject **ppObject, + uintptr(0)) // [out] IWbemCallResult **ppCallResult) + if res < 0 { + // returns WBEM_E_PROVIDER_NOT_FOUND when no entry found + return nil, ole.NewError(res) + } + + return newInstance(pObject, s), nil +} + +// GetObjectAsObject gets an object by its path and set all fields of the passed in target to match the instance's +// properties. Conversion is performed as appropriate. +func (s *Service) GetObjectAsObject(objPath string, target interface{}) error { + instance, err := s.GetObject(objPath) + if err != nil { + return err + } + defer instance.Close() + + return instance.GetAll(target) +} + +// CreateInstanceEnum creates an enumerator that iterates all registered object instances for a given className. +func (s *Service) CreateInstanceEnum(className string) (*Enum, error) { + var err error + var pEnum *ole.IUnknown + var strFilter *uint16 + + if strFilter, err = syscall.UTF16PtrFromString(className); err != nil { + return nil, err + } + + // No subclasses in result set + flags := WBEM_FLAG_SHALLOW + + res, _, _ := syscall.SyscallN( + s.vTable.CreateInstanceEnum, // IWbemServices::CreateInstanceEnum( + uintptr(unsafe.Pointer(s.service)), // IWbemServices ptr + uintptr(unsafe.Pointer(strFilter)), // [in] const BSTR strFilter, + uintptr(flags), // [in] long lFlags, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(&pEnum))) // [out] IEnumWbemClassObject **ppEnum) + if res < 0 { + return nil, ole.NewError(res) + } + + if err = CoSetProxyBlanket(pEnum); err != nil { + return nil, err + } + + return newEnum(pEnum, s), nil +} + +// ExecMethod executes a method using the specified class and parameter payload instance. The parameter payload +// instance can be constructed using Instance.GetMethodParameters(). This is an advanced method, it is +// recommended to use BeginInvoke() instead, where possible. +func (s *Service) ExecMethod(className string, methodName string, inParams *Instance) (*Instance, error) { + var err error + var outParams *ole.IUnknown + var strObjectPath *uint16 + var strMethodName *uint16 + + if strObjectPath, err = syscall.UTF16PtrFromString(className); err != nil { + return nil, err + } + + if strMethodName, err = syscall.UTF16PtrFromString(methodName); err != nil { + return nil, err + } + + res, _, _ := syscall.SyscallN( + s.vTable.ExecMethod, // IWbemServices::ExecMethod( + uintptr(unsafe.Pointer(s.service)), // IWbemServices ptr + uintptr(unsafe.Pointer(strObjectPath)), // [in] const BSTR strObjectPath, + uintptr(unsafe.Pointer(strMethodName)), // [in] const BSTR strMethodName, + uintptr(0), // [in] long lFlags, + uintptr(0), // [in] IWbemContext *pCtx, + uintptr(unsafe.Pointer(inParams.object)), // [in] IWbemClassObject *pInParams, + uintptr(unsafe.Pointer(&outParams)), // [out] IWbemClassObject **ppOutParams, + uintptr(0)) // [out] IWbemCallResult **ppCallResult) + if res < 0 { + return nil, ole.NewError(res) + } + + return newInstance(outParams, s), nil +} + +// FindFirstInstance find and returns the first WMI Instance in the result set for a WSL query. +func (s *Service) FindFirstInstance(wql string) (*Instance, error) { + var enum *Enum + var err error + if enum, err = s.ExecQuery(wql); err != nil { + return nil, err + } + defer enum.Close() + + instance, err := enum.Next() + if err != nil { + return nil, err + } + + if instance == nil { + return nil, errors.New("no results found") + } + + return instance, nil +} + +// FindFirstRelatedInstance finds and returns a related associator of the specified WMI object path of the +// expected className type. +func (s *Service) FindFirstRelatedInstance(objPath string, className string) (*Instance, error) { + wql := fmt.Sprintf("ASSOCIATORS OF {%s} WHERE ResultClass = %s", objPath, className) + return s.FindFirstInstance(wql) +} + +// FindFirstRelatedInstanceThrough finds and returns a related associator of the specified WMI object path of the +// expected className type, and only through the expected association type. +func (s *Service) FindFirstRelatedInstanceThrough(objPath string, resultClass string, assocClass string) (*Instance, error) { + wql := fmt.Sprintf("ASSOCIATORS OF {%s} WHERE AssocClass = %s ResultClass = %s ", objPath, assocClass, resultClass) + return s.FindFirstInstance(wql) +} + +// FindFirstRelatedObject finds and returns a related associator of the specified WMI object path of the +// expected className type, and populates the passed in struct with its fields +func (s *Service) FindFirstRelatedObject(objPath string, className string, target interface{}) error { + wql := fmt.Sprintf("ASSOCIATORS OF {%s} WHERE ResultClass = %s", objPath, className) + return s.FindFirstObject(wql, target) +} + +// FindFirstObject finds and returns the first WMI Instance in the result set for a WSL query, and +// populates the specified struct pointer passed in through the target parameter. +func (s *Service) FindFirstObject(wql string, target interface{}) error { + var enum *Enum + var err error + if enum, err = s.ExecQuery(wql); err != nil { + return err + } + defer enum.Close() + + done, err := NextObject(enum, target) + if err != nil { + return err + } + + if done { + return errors.New("no results found") + } + + return nil +} + +// GetSingletonInstance gets the first WMI instance of the specified object class type. This is a +// shortcut method for uses where only one instance is expected. +func (s *Service) GetSingletonInstance(className string) (*Instance, error) { + var ( + enum *Enum + instance *Instance + err error + ) + + if enum, err = s.CreateInstanceEnum(className); err != nil { + return nil, err + } + defer enum.Close() + + if instance, err = enum.Next(); err != nil { + return nil, err + } + + return instance, nil +} + +// CreateInstance creates a new WMI object class instance of the specified className, and sets +// all properties according to the passed in struct pointer through the src +// parameter, converting appropriately. +func (s *Service) CreateInstance(className string, src interface{}) (*Instance, error) { + instance, err := s.SpawnInstance(className) + if err != nil { + return nil, err + } + + return instance, instance.PutAll(src) +} + +// SpawnInstance creates a new zeroed WMI instance. This instance will not contain expected values. +// Those must be retrieved and set separately, or CreateInstance() can be used instead. +func (s *Service) SpawnInstance(className string) (*Instance, error) { + var class *Instance + var err error + if class, err = s.GetObject(className); err != nil { + return nil, err + } + defer class.Close() + + return class.SpawnInstance() +} + +// RefetchObject re-fetches the object and returns a new instance. The original instance will not +// automatically Close(). Callers of this method will need to manually close the +// original. +func (s *Service) RefetchObject(instance *Instance) (*Instance, error) { + path, err := instance.Path() + if err != nil { + return instance, err + } + return s.GetObject(path) +} + +// GetClassInstance gets the WMI class instance associated with the specified object instance. +// This method is used to perform schema queries. +func (s *Service) GetClassInstance(obj *Instance) (*Instance, error) { + name, err := obj.GetClassName() + if err != nil { + return nil, err + } + return s.GetObject(name) +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 0c4d14929a..8f775fafa6 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -624,7 +624,7 @@ ccflags="$@" $2 ~ /^MEM/ || $2 ~ /^WG/ || $2 ~ /^FIB_RULE_/ || - $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} + $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} diff --git a/vendor/golang.org/x/sys/unix/mmap_nomremap.go b/vendor/golang.org/x/sys/unix/mmap_nomremap.go new file mode 100644 index 0000000000..ca0513632e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mmap_nomremap.go @@ -0,0 +1,14 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris +// +build aix darwin dragonfly freebsd openbsd solaris + +package unix + +var mapper = &mmapper{ + active: make(map[*byte][]byte), + mmap: mmap, + munmap: munmap, +} diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go index 86213c05d6..fa93d0aa90 100644 --- a/vendor/golang.org/x/sys/unix/mremap.go +++ b/vendor/golang.org/x/sys/unix/mremap.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build linux -// +build linux +//go:build linux || netbsd +// +build linux netbsd package unix @@ -14,8 +14,17 @@ type mremapMmapper struct { mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) } +var mapper = &mremapMmapper{ + mmapper: mmapper{ + active: make(map[*byte][]byte), + mmap: mmap, + munmap: munmap, + }, + mremap: mremap, +} + func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { - if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&MREMAP_FIXED != 0 { + if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 { return nil, EINVAL } @@ -32,9 +41,13 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [ } bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength) pNew := &bNew[cap(bNew)-1] - if flags&MREMAP_DONTUNMAP == 0 { + if flags&mremapDontunmap == 0 { delete(m.active, pOld) } m.active[pNew] = bNew return bNew, nil } + +func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { + return mapper.Mremap(oldData, newLength, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index c406ae00f4..9a6e5acacb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -535,21 +535,6 @@ func Fsync(fd int) error { //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg //sys munmap(addr uintptr, length uintptr) (err error) - -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Madvise(b []byte, advice int) (err error) //sys Mprotect(b []byte, prot int) (err error) //sys Mlock(b []byte) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index 7705c3270b..4217de518b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -601,20 +601,6 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { // Gethostuuid(uuid *byte, timeout *Timespec) (err error) // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Madvise(b []byte, behav int) (err error) //sys Mlock(b []byte) (err error) //sys Mlockall(flags int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 206921504c..135cc3cd75 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -510,30 +510,36 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { return nil, err } - // Find size. - n := uintptr(0) - if err := sysctl(mib, nil, &n, nil, 0); err != nil { - return nil, err - } - if n == 0 { - return nil, nil - } - if n%SizeofKinfoProc != 0 { - return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) - } + for { + // Find size. + n := uintptr(0) + if err := sysctl(mib, nil, &n, nil, 0); err != nil { + return nil, err + } + if n == 0 { + return nil, nil + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } - // Read into buffer of that size. - buf := make([]KinfoProc, n/SizeofKinfoProc) - if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { - return nil, err - } - if n%SizeofKinfoProc != 0 { - return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) - } + // Read into buffer of that size. + buf := make([]KinfoProc, n/SizeofKinfoProc) + if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { + if err == ENOMEM { + // Process table grew. Try again. + continue + } + return nil, err + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } - // The actual call may return less than the original reported required - // size so ensure we deal with that. - return buf[:n/SizeofKinfoProc], nil + // The actual call may return less than the original reported required + // size so ensure we deal with that. + return buf[:n/SizeofKinfoProc], nil + } } //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 39de5f1430..a730878e49 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1885,7 +1885,7 @@ func Getpgrp() (pid int) { //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) -//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 +//sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) @@ -2125,28 +2125,6 @@ func writevRacedetect(iovecs []Iovec, n int) { // mmap varies by architecture; see syscall_linux_*.go. //sys munmap(addr uintptr, length uintptr) (err error) //sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) - -var mapper = &mremapMmapper{ - mmapper: mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, - }, - mremap: mremap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - -func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { - return mapper.Mremap(oldData, newLength, flags) -} - //sys Madvise(b []byte, advice int) (err error) //sys Mprotect(b []byte, prot int) (err error) //sys Mlock(b []byte) (err error) @@ -2155,6 +2133,12 @@ func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { //sys Munlock(b []byte) (err error) //sys Munlockall() (err error) +const ( + mremapFixed = MREMAP_FIXED + mremapDontunmap = MREMAP_DONTUNMAP + mremapMaymove = MREMAP_MAYMOVE +) + // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, // using the specified flags. func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { @@ -2454,6 +2438,39 @@ func Getresgid() (rgid, egid, sgid int) { return int(r), int(e), int(s) } +// Pselect is a wrapper around the Linux pselect6 system call. +// This version does not modify the timeout argument. +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + // Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES, + // The Linux pselect6() system call modifies its timeout argument. + // [Not modifying the argument] is the behavior required by POSIX.1-2001. + var mutableTimeout *Timespec + if timeout != nil { + mutableTimeout = new(Timespec) + *mutableTimeout = *timeout + } + + // The final argument of the pselect6() system call is not a + // sigset_t * pointer, but is instead a structure + var kernelMask *sigset_argpack + if sigmask != nil { + wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize + + // A sigset stores one bit per signal, + // offset by 1 (because signal 0 does not exist). + // So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉. + sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits) + + sigsetBytes := uintptr(sigsetWords * (wordBits / 8)) + kernelMask = &sigset_argpack{ + ss: sigmask, + ssLen: sigsetBytes, + } + } + + return pselect6(nfd, r, w, e, mutableTimeout, kernelMask) +} + /* * Unimplemented */ diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go index 5b21fcfd75..70601ce369 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go @@ -40,7 +40,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index a81f5742b8..f5266689af 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -33,7 +33,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go index 69d2d7c3db..f6ab02ec15 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go @@ -28,7 +28,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index 76d564095e..93fe59d25d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -31,7 +31,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 35851ef70b..5e6ceee129 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -32,7 +32,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) @@ -177,3 +177,14 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +//sys riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error) + +func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error) { + var setSize uintptr + + if set != nil { + setSize = uintptr(unsafe.Sizeof(*set)) + } + return riscvHWProbe(pairs, setSize, set, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 018d7d4782..ddd1ac8534 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -360,6 +360,18 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) +const ( + mremapFixed = MAP_FIXED + mremapDontunmap = 0 + mremapMaymove = 0 +) + +//sys mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) = SYS_MREMAP + +func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (uintptr, error) { + return mremapNetBSD(oldaddr, oldlength, newaddr, newlength, flags) +} + /* * Unimplemented */ @@ -564,7 +576,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { // mq_timedreceive // mq_timedsend // mq_unlink -// mremap // msgget // msgrcv // msgsnd diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index b600a289d3..72d23575fa 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -716,20 +716,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { return } -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - // Event Ports type fileObjCookie struct { diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 8e48c29ec3..8bb30e7ce3 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -147,6 +147,14 @@ func (m *mmapper) Munmap(data []byte) (err error) { return nil } +func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { + return mapper.Mmap(fd, offset, length, prot, flags) +} + +func Munmap(b []byte) (err error) { + return mapper.Munmap(b) +} + func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) if raceenabled { diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index d3d49ec3ed..44e72edb42 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -285,25 +285,11 @@ func Close(fd int) (err error) { return } -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - // Dummy function: there are no semantics for Madvise on z/OS func Madvise(b []byte, advice int) (err error) { return } -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A //sysnb Getegid() (egid int) //sysnb Geteuid() (uid int) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index a46df0f1e5..cfb1430018 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80041272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 6cd4a3ea9d..df64f2d590 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index c7ebee24df..3025cd5b2d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80041272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 12a9a1389e..09e1ffbef9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index f26a164f4a..a457235407 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 890bc3c9b7..fee7dfb819 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 549f26ac64..a5b2373aea 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index e0365e32c1..5dde82c98a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index fdccce15ca..2e80ea6b33 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index b2205c83fa..a65dcd7cbe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 81aa5ad0f6..cbd34e3d89 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 76807a1fd4..e4afa7a317 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index d4a5ab9e4e..44f45a039d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 66e65db951..74733e260f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 48984202c6..f5f3934b1a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -30,22 +30,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 7ceec233fb..a07321bed9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -1356,7 +1356,7 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { +func pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) { r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) n = int(r0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go index 0b29239583..0ab4f2ed72 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go @@ -531,3 +531,19 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error) { + var _p0 unsafe.Pointer + if len(pairs) > 0 { + _p0 = unsafe.Pointer(&pairs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_RISCV_HWPROBE, uintptr(_p0), uintptr(len(pairs)), uintptr(cpuCount), uintptr(unsafe.Pointer(cpus)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index cdb2af5ae0..35f499b32a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 9d25f76b0b..3cda65b0da 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index d3f8035169..1e1fea902b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go index 887188a529..3b77da1107 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go @@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 3e594a8c09..ef285c567b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -251,6 +251,8 @@ const ( SYS_ACCEPT4 = 242 SYS_RECVMMSG = 243 SYS_ARCH_SPECIFIC_SYSCALL = 244 + SYS_RISCV_HWPROBE = 258 + SYS_RISCV_FLUSH_ICACHE = 259 SYS_WAIT4 = 260 SYS_PRLIMIT64 = 261 SYS_FANOTIFY_INIT = 262 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 02e2462c8f..26ef52aafc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -866,6 +866,11 @@ const ( POLLNVAL = 0x20 ) +type sigset_argpack struct { + ss *Sigset_t + ssLen uintptr +} + type SignalfdSiginfo struct { Signo uint32 Errno int32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 9ea54b7b86..83c69c119f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -718,3 +718,26 @@ type SysvShmDesc struct { _ uint64 _ uint64 } + +type RISCVHWProbePairs struct { + Key int64 + Value uint64 +} + +const ( + RISCV_HWPROBE_KEY_MVENDORID = 0x0 + RISCV_HWPROBE_KEY_MARCHID = 0x1 + RISCV_HWPROBE_KEY_MIMPID = 0x2 + RISCV_HWPROBE_KEY_BASE_BEHAVIOR = 0x3 + RISCV_HWPROBE_BASE_BEHAVIOR_IMA = 0x1 + RISCV_HWPROBE_KEY_IMA_EXT_0 = 0x4 + RISCV_HWPROBE_IMA_FD = 0x1 + RISCV_HWPROBE_IMA_C = 0x2 + RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 + RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 + RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 + RISCV_HWPROBE_MISALIGNED_SLOW = 0x2 + RISCV_HWPROBE_MISALIGNED_FAST = 0x3 + RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 + RISCV_HWPROBE_MISALIGNED_MASK = 0x7 +) diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 9645900754..373d16388a 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -135,14 +135,14 @@ func Getpagesize() int { return 4096 } // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. // This is useful when interoperating with Windows code requiring callbacks. -// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallback(fn interface{}) uintptr { return syscall.NewCallback(fn) } // NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. // This is useful when interoperating with Windows code requiring callbacks. -// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallbackCDecl(fn interface{}) uintptr { return syscall.NewCallbackCDecl(fn) } diff --git a/vendor/modules.txt b/vendor/modules.txt index adbbf07e79..5dd9b9e7b1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -157,6 +157,11 @@ github.com/containers/image/v5/signature/simplesigning github.com/containers/image/v5/transports github.com/containers/image/v5/types github.com/containers/image/v5/version +# github.com/containers/libhvee v0.4.1-0.20230901182836-fcf1478fdd75 +## explicit; go 1.18 +github.com/containers/libhvee/pkg/hypervctl +github.com/containers/libhvee/pkg/kvp/ginsu +github.com/containers/libhvee/pkg/wmiext # github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 ## explicit github.com/containers/libtrust @@ -845,7 +850,7 @@ golang.org/x/oauth2/internal golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.10.0 +# golang.org/x/sys v0.11.0 ## explicit; go 1.17 golang.org/x/sys/cpu golang.org/x/sys/execabs