mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-09-06 09:21:28 +00:00
add support for virtualization framework
Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -10,20 +10,25 @@ jobs:
|
||||
- os: linux
|
||||
arch: amd64
|
||||
suffix: amd64-linux
|
||||
runner: ubuntu-latest
|
||||
- os: linux
|
||||
arch: arm64
|
||||
suffix: arm64-linux
|
||||
runner: ubuntu-latest
|
||||
- os: linux
|
||||
arch: s390x
|
||||
suffix: s390x-linux
|
||||
runner: ubuntu-latest
|
||||
- os: darwin
|
||||
arch: amd64
|
||||
suffix: amd64-darwin
|
||||
runner: macos-latest
|
||||
- os: windows
|
||||
arch: amd64
|
||||
suffix: amd64-windows.exe
|
||||
runner: ubuntu-latest
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.target.runner }}
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.16
|
||||
@@ -64,7 +69,10 @@ jobs:
|
||||
|
||||
- name: Checksum
|
||||
run: |
|
||||
cd bin && sha256sum linuxkit-${{matrix.target.suffix}} > linuxkit-${{matrix.target.suffix}}.SHA256SUM
|
||||
cd bin
|
||||
if command -v sha256sum > /dev/null; then sha256sum linuxkit-${{matrix.target.suffix}} > linuxkit-${{matrix.target.suffix}}.SHA256SUM
|
||||
else openssl sha256 -r linuxkit-${{matrix.target.suffix}} | tr -d '*' > linuxkit-${{matrix.target.suffix}}.SHA256SUM
|
||||
fi
|
||||
cat linuxkit-${{matrix.target.suffix}}.SHA256SUM
|
||||
|
||||
- name: Test
|
||||
|
10
Makefile
10
Makefile
@@ -5,17 +5,14 @@ GO_COMPILE=linuxkit/go-compile:7b1f5a37d2a93cd4a9aa2a87db264d8145944006
|
||||
ifeq ($(OS),Windows_NT)
|
||||
LINUXKIT?=$(CURDIR)/bin/linuxkit.exe
|
||||
RTF?=bin/rtf.exe
|
||||
GOOS?=windows
|
||||
else
|
||||
LINUXKIT?=$(CURDIR)/bin/linuxkit
|
||||
RTF?=bin/rtf
|
||||
GOOS?=$(shell uname -s | tr '[:upper:]' '[:lower:]')
|
||||
endif
|
||||
GOARCH?=amd64
|
||||
ifneq ($(GOOS),linux)
|
||||
ifneq ($(GOOS),)
|
||||
CROSS+=-e GOOS=$(GOOS)
|
||||
endif
|
||||
ifneq ($(GOARCH),amd64)
|
||||
ifneq ($(GOARCH),)
|
||||
CROSS+=-e GOARCH=$(GOARCH)
|
||||
endif
|
||||
|
||||
@@ -74,6 +71,9 @@ bin:
|
||||
install:
|
||||
cp -R bin/* $(PREFIX)/bin
|
||||
|
||||
sign:
|
||||
codesign --entitlements linuxkit.entitlements --force -s - $(PREFIX)/bin/linuxkit
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(MAKE) -C test
|
||||
|
@@ -75,6 +75,7 @@ for example VMWare. See `linuxkit run --help`.
|
||||
|
||||
Currently supported platforms are:
|
||||
- Local hypervisors
|
||||
- [Virtualization.Framework (macOS)](docs/platform-virtualization-framework.md) `[x86_64, arm64]`
|
||||
- [HyperKit (macOS)](docs/platform-hyperkit.md) `[x86_64]`
|
||||
- [Hyper-V (Windows)](docs/platform-hyperv.md) `[x86_64]`
|
||||
- [qemu (macOS, Linux, Windows)](docs/platform-qemu.md) `[x86_64, arm64, s390x]`
|
||||
|
@@ -7,7 +7,8 @@
|
||||
## Make Disk Available
|
||||
In order to make the disk available, you need to tell `linuxkit` where the disk file or block device is.
|
||||
|
||||
All local `linuxkit run` methods (currently `hyperkit`, `qemu`, and `vmware`) take a `-disk` argument:
|
||||
All local `linuxkit run` methods (currently `hyperkit`, `qemu`, `virtualization.framework` and `vmware`)
|
||||
take a `-disk` argument:
|
||||
|
||||
* `-disk path,size=100M,format=qcow2`. For size the default is in GB but an `M` can be appended to specify sizes in MB. The format can be omitted for the platform default, and is only useful on `qemu` at present.
|
||||
|
||||
|
@@ -115,3 +115,9 @@ and made available in `/run/config/userdata`.
|
||||
HyperKit does not distinguish metadata and userdata, it's simply
|
||||
refered to as data, which is passed to the VM as a disk image
|
||||
in ISO9660 format.
|
||||
|
||||
## Virtualization.Framework
|
||||
|
||||
Virtualization.Framework does not distinguish metadata and userdata, it's simply
|
||||
refered to as data, which is passed to the VM as a disk image
|
||||
in ISO9660 format.
|
||||
|
204
docs/platform-virtualization-framework.md
Normal file
204
docs/platform-virtualization-framework.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# LinuxKit with Virtualization.Framework (macOS)
|
||||
|
||||
We recommend using LinuxKit in conjunction with
|
||||
[Docker for Mac](https://docs.docker.com/docker-for-mac/install/). For
|
||||
the time being it's best to be on the latest edge release. `linuxkit
|
||||
run` uses [Virtualization.Framework](https://developer.apple.com/documentation/virtualization) and
|
||||
[VPNKit](https://github.com/moby/vpnkit) and the edge release ships
|
||||
with updated versions of both.
|
||||
|
||||
Alternatively, you can install Virtualization.Framework and VPNKit standalone and use it without Docker for Mac.
|
||||
|
||||
|
||||
## Boot
|
||||
|
||||
The Virtualization.Framework backend currently supports booting:
|
||||
- `kernel+initrd` output from `linuxkit build`.
|
||||
- `kernel+squashfs` output from `linuxkit build`.
|
||||
- EFI ISOs using the EFI firmware.
|
||||
|
||||
You need to select the boot method manually using the command line
|
||||
options. The default is `kernel+initrd`. `kernel+squashfs` can be
|
||||
selected using `-squashfs` and to boot a ISO with EFI you have to
|
||||
specify `-iso -uefi`.
|
||||
|
||||
The `kernel+initrd` uses a RAM disk for the root filesystem. If you
|
||||
have RAM constraints or large images we recommend using either the
|
||||
`kernel+squashfs` or the EFI ISO boot.
|
||||
|
||||
## Console
|
||||
|
||||
With `linuxkit run` on Virtualization.Framework the serial console is redirected to
|
||||
stdio, providing interactive access to the VM. The output of the VM
|
||||
can be re-directed to a file or pipe, but then stdin is not available.
|
||||
Virtualization.Framework does not provide a console device.
|
||||
|
||||
|
||||
## Disks
|
||||
|
||||
The Virtualization.Framework backend support configuring a persistent disk using the
|
||||
standard `linuxkit` `-disk` syntax. Multiple disks are
|
||||
supported and the disks are in raw format.
|
||||
|
||||
## Power management
|
||||
|
||||
Virtualization.Framework sends an ACPI power event when it receives SIGTERM to allow the VM to
|
||||
shut down properly. The VM has to be able to receive ACPI events to initiate the
|
||||
shutdown. This is provided by the [`acpid` package](../pkg/acpid). An example
|
||||
is available in the [Docker for Mac example](../examples/docker-for-mac.yml).
|
||||
|
||||
## Networking
|
||||
|
||||
By default, `linuxkit run` creates a VM with a single network
|
||||
interface which, logically, is attached to a L2 bridge. The bridge
|
||||
also has the VM used by Docker for Mac attached to it. This means that
|
||||
the LinuxKit VMs, created with `linuxkit run`, can be accessed from
|
||||
containers running on Docker for Mac.
|
||||
|
||||
The LinuxKit VMs have IP addresses on the `192.168.65.0/24` subnet
|
||||
assigned by a DHCP server part of VPNKit. `192.168.65.1` is reserved
|
||||
for VPNKit as the default gateway and `192.168.65.2` is used by the
|
||||
Docker for Mac VM.
|
||||
|
||||
By default, LinuxKit VMs get incrementally increasing IP addresses,
|
||||
but you can assign a fixed IP address with `linuxkit run -ip`. It's
|
||||
best to choose an IP address from the DHCP address range above, but
|
||||
care must be taken to avoid clashes of IP address.
|
||||
|
||||
*NOTE:* The LinuxKit VMs can *not* be directly accessed by IP address
|
||||
from the host. Enabling this would require use of the macOS `vmnet`
|
||||
framework, which requires the VMs to run as `root`. We don't consider
|
||||
this option palatable, and provide alternative options to access the
|
||||
VMs over the network below.
|
||||
|
||||
|
||||
### Accessing network services
|
||||
|
||||
Virtualization.Framework offers a number of ways for accessing network services
|
||||
running inside the LinuxKit VM from the host. These depend on the
|
||||
networking mode selected via `-networking`. The default mode is
|
||||
`vmnet`, where it sets up a network bridge. We intend to add support for
|
||||
`docker-for-mac`, where the same VPNkit instance is shared between
|
||||
LinuxKit VMs and the VM running as part of Docker for Mac, in the future.
|
||||
|
||||
#### Access from the Docker for Mac VM (`-networking docker-for-mac`)
|
||||
|
||||
The simplest way to access networking services exposed by a LinuxKit
|
||||
VM is to use a Docker for Mac container. For example, to access an ssh
|
||||
server in a LinuxKit VM, create a ssh client container from:
|
||||
|
||||
```
|
||||
FROM alpine:edge
|
||||
RUN apk add --no-cache openssh-client
|
||||
```
|
||||
|
||||
and then run
|
||||
|
||||
```
|
||||
docker build -t ssh .
|
||||
docker run --rm -ti -v ~/.ssh:/root/.ssh ssh ssh <IP address of VM>
|
||||
```
|
||||
|
||||
#### Forwarding ports with `socat` (`-networking docker-for-mac`)
|
||||
|
||||
A `socat` container on Docker for Mac can be used to proxy between the
|
||||
LinuxKit VM's ports and localhost. For example, to expose the redis
|
||||
port from the [RedisOS example](../examples/redis-os.yml), use this
|
||||
Dockerfile:
|
||||
|
||||
```
|
||||
FROM alpine:edge
|
||||
RUN apk add --no-cache socat
|
||||
ENTRYPOINT [ "/usr/bin/socat" ]
|
||||
```
|
||||
and then:
|
||||
```
|
||||
docker build -t socat .
|
||||
docker run --rm -t -d -p 6379:6379 socat tcp-listen:6379,reuseaddr,fork tcp:<IP address of VM>:6379
|
||||
```
|
||||
|
||||
#### Port forwarding with VPNKit (`-networking docker-for-mac`)
|
||||
|
||||
There is **experimental** support for exposing selected ports of the
|
||||
guest on `localhost` using the `-publish` command line option. For
|
||||
example, using `-publish 2222:22/tcp` exposes the guest TCP port 22 on
|
||||
localhost on port 2222. Multiple `-publish` options can be
|
||||
specified. For example, the image build from the [`sshd
|
||||
example`](../examples/sshd.yml) can be started with:
|
||||
|
||||
```
|
||||
linuxkit run -publish 2222:22/tcp sshd
|
||||
```
|
||||
|
||||
and then you can log into the LinuxKit VM with `ssh -p 2222
|
||||
root@localhost`.
|
||||
|
||||
Note, this mode is **experimental** and may cause the VPNKit instance
|
||||
shared with Docker for Mac being confused about which ports are
|
||||
currently in use, in particular if the LinuxKit VM does not exit
|
||||
gracefully. This can typically be fixed by restarting Docker for Mac.
|
||||
|
||||
|
||||
#### Port forwarding with VPNKit (`-networking vpnkit`)
|
||||
|
||||
An alternative to the previous method is to start your own copy of
|
||||
`vpnkit` (or connect to an already running instance). This can be done
|
||||
using the `-networking vpnkit` command line option.
|
||||
|
||||
VPNKit uses a 9P mount in `/port` for coordination between
|
||||
components. The first VM on a VPNKit instance currently needs mount
|
||||
the 9P filesystem and also needs to run the `vpnkit-forwarder` service
|
||||
to enable port forwarding to localhost. A full example with `vpnkit`
|
||||
forwarding of `sshd` is available in
|
||||
[examples/vpnkit-forwarder.yml](/examples/vpnkit-forwarder.yml).
|
||||
|
||||
To run this example with its own instance of VPNKit, use:
|
||||
|
||||
```
|
||||
linuxkit run -networking vpnkit -publish 2222:22/tcp vpnkit-forwarder
|
||||
```
|
||||
|
||||
You can then access it via:
|
||||
|
||||
```
|
||||
ssh -p 2222 root@localhost
|
||||
```
|
||||
|
||||
More details about the VPNKit forwarding mechanism is available in the
|
||||
[VPNKit
|
||||
documentation](https://github.com/moby/vpnkit/blob/master/docs/ports.md#signalling-from-the-vm-to-the-host).
|
||||
|
||||
|
||||
## Integration services and Metadata
|
||||
|
||||
There are no special integration services available for Virtualization.Framework, but
|
||||
there are a number of packages, such as `vsudd`, which enable
|
||||
tighter integration of the VM with the host (see below).
|
||||
|
||||
The Virtualization.Framework backend also allows passing custom userdata into the
|
||||
[metadata package](./metadata.md) using either the `-data` or `-data-file` command-line
|
||||
option. This attaches a CD device with the data on.
|
||||
|
||||
|
||||
### `vsudd` unix domain socket forwarding
|
||||
|
||||
The [`vsudd` package](/pkg/vsudd) provides a daemon that exposes unix
|
||||
domain socket inside the VM to the host via virtio or Hyper-V sockets.
|
||||
With Virtualization.Framework, the virtio sockets can be exposed as unix domain
|
||||
sockets on the host, enabling access to other daemons, like
|
||||
`containerd` and `dockerd`, from the host. An example configuration
|
||||
file is available in [examples/vsudd-containerd.yml](/examples/vsudd-containerd.yml).
|
||||
|
||||
After building the example, run it with `linuxkit run virtualization.framework
|
||||
-vsock-ports 2374 vsudd`. This will create a unix domain socket in the state directory that maps to the `containerd` control socket. The socket is called `guest.00000946`.
|
||||
|
||||
If you install the `ctr` tool on the host you should be able to access the
|
||||
`containerd` running in the VM:
|
||||
|
||||
```
|
||||
$ go get -u -ldflags -s github.com/containerd/containerd/cmd/ctr
|
||||
...
|
||||
$ ctr -a vsudd-state/guest.00000946 list
|
||||
ID IMAGE PID STATUS
|
||||
vsudd 466 RUNNING
|
||||
```
|
@@ -25,10 +25,16 @@ default: $(LINUXKIT)
|
||||
all: default
|
||||
|
||||
LINUXKIT_DEPS=$(wildcard *.go) $(wildcard */*.go) Makefile
|
||||
|
||||
|
||||
ifeq ($(GOOS),darwin)
|
||||
$(LINUXKIT): local-build sign | bin
|
||||
else
|
||||
$(LINUXKIT): tmp_linuxkit_bin.tar | bin
|
||||
tar -C $(dir $(LINUXKIT)) -xf $<
|
||||
rm $<
|
||||
touch $@
|
||||
endif
|
||||
|
||||
tmp_linuxkit_bin.tar: $(LINUXKIT_DEPS)
|
||||
tar cf - -C . . | docker run --rm --net=none --log-driver=none -i $(CROSS) $(GO_COMPILE) --package github.com/linuxkit/linuxkit/src/cmd/linuxkit --ldflags "-X github.com/linuxkit/linuxkit/src/cmd/linuxkit/version.GitCommit=$(GIT_COMMIT) -X github.com/linuxkit/linuxkit/src/cmd/linuxkit/version.Version=$(VERSION)" -o $(notdir $(LINUXKIT)) > $@
|
||||
@@ -54,6 +60,11 @@ ifeq ($(STATIC), 1)
|
||||
CGO_ENABLED=0
|
||||
endif
|
||||
|
||||
# darwin needs CGO to build for virtualization framework
|
||||
ifeq ($(GOOS), darwin)
|
||||
CGO_ENABLED=1
|
||||
endif
|
||||
|
||||
ifeq ($(PIE), 1)
|
||||
CGO_ENABLED=0
|
||||
BUILD_FLAGS+= --buildmode pie
|
||||
@@ -81,6 +92,9 @@ local: local-check local-build local-test
|
||||
bin:
|
||||
mkdir -p $@
|
||||
|
||||
sign:
|
||||
codesign --entitlements linuxkit.entitlements --force -s - $(LOCAL_TARGET)
|
||||
|
||||
install:
|
||||
cp -R ./bin/* $(PREFIX)/bin
|
||||
|
||||
|
@@ -10,6 +10,7 @@ require (
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||
github.com/Code-Hex/vz v0.0.4
|
||||
github.com/Microsoft/go-winio v0.5.2
|
||||
github.com/ScaleFT/sshkeys v0.0.0-20181112160850-82451a803681
|
||||
github.com/aws/aws-sdk-go v1.34.9
|
||||
@@ -34,6 +35,7 @@ require (
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
github.com/packethost/packngo v0.1.1-0.20171201154433-f1be085ecd6f
|
||||
github.com/pkg/term v1.1.0
|
||||
github.com/radu-matei/azure-sdk-for-go v5.0.0-beta.0.20161118192335-3b1282355199+incompatible
|
||||
github.com/radu-matei/azure-vhd-utils v0.0.0-20170531165126-e52754d5569d
|
||||
github.com/rn/iso9660wrap v0.0.0-20171120145750-baf8d62ad315
|
||||
@@ -47,6 +49,7 @@ require (
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
google.golang.org/api v0.57.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
@@ -134,6 +134,8 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM
|
||||
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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Code-Hex/vz v0.0.4 h1:1rM8ijE+znlrOeYIer441cSwpYq2rk57Fd3dRpxUDUA=
|
||||
github.com/Code-Hex/vz v0.0.4/go.mod h1:UeHKXSv3hP7BzU6IaVE/a7VHSHUHpqbS3oVko4O5UYI=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
|
||||
@@ -1215,6 +1217,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk=
|
||||
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -1285,6 +1289,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
8
src/cmd/linuxkit/linuxkit.entitlements
Normal file
8
src/cmd/linuxkit/linuxkit.entitlements
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.virtualization</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@@ -20,7 +20,8 @@ func runUsage() {
|
||||
fmt.Printf(" aws\n")
|
||||
fmt.Printf(" azure\n")
|
||||
fmt.Printf(" gcp\n")
|
||||
fmt.Printf(" hyperkit [macOS]\n")
|
||||
fmt.Printf(" virtualization [macOS]\n")
|
||||
fmt.Printf(" hyperkit\n")
|
||||
fmt.Printf(" hyperv [Windows]\n")
|
||||
fmt.Printf(" openstack\n")
|
||||
fmt.Printf(" packet\n")
|
||||
@@ -55,6 +56,8 @@ func run(args []string) {
|
||||
os.Exit(0)
|
||||
case "hyperkit":
|
||||
runHyperKit(args[1:])
|
||||
case "virtualization":
|
||||
runVirtualizationFramework(args[1:])
|
||||
case "hyperv":
|
||||
runHyperV(args[1:])
|
||||
case "openstack":
|
||||
@@ -74,7 +77,7 @@ func run(args []string) {
|
||||
default:
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
runHyperKit(args)
|
||||
runVirtualizationFramework(args)
|
||||
case "linux":
|
||||
runQemu(args)
|
||||
case "windows":
|
||||
|
13
src/cmd/linuxkit/run_virtualizationframework.go
Normal file
13
src/cmd/linuxkit/run_virtualizationframework.go
Normal file
@@ -0,0 +1,13 @@
|
||||
//go:build !darwin
|
||||
// +build !darwin
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func runVirtualizationFramework(args []string) {
|
||||
log.Fatal("virtualization framework is available only on macOS")
|
||||
}
|
324
src/cmd/linuxkit/run_virtualizationframework_darwin.go
Normal file
324
src/cmd/linuxkit/run_virtualizationframework_darwin.go
Normal file
@@ -0,0 +1,324 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/Code-Hex/vz"
|
||||
"github.com/pkg/term/termios"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
virtualizationNetworkingNone string = "none"
|
||||
virtualizationNetworkingDockerForMac = "docker-for-mac"
|
||||
virtualizationNetworkingVPNKit = "vpnkit"
|
||||
virtualizationNetworkingVMNet = "vmnet"
|
||||
virtualizationNetworkingDefault = virtualizationNetworkingVMNet
|
||||
virtualizationFrameworkConsole = "console=hvc0"
|
||||
)
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func runVirtualizationFramework(args []string) {
|
||||
flags := flag.NewFlagSet("virtualization", flag.ExitOnError)
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run virtualization [options] prefix\n\n", invoked)
|
||||
fmt.Printf("'prefix' specifies the path to the VM image.\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("Options:\n")
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
cpus := flags.Uint("cpus", 1, "Number of CPUs")
|
||||
mem := flags.Uint64("mem", 1024, "Amount of memory in MB")
|
||||
memBytes := *mem * 1024 * 1024
|
||||
var disks Disks
|
||||
flags.Var(&disks, "disk", "Disk config. [file=]path[,size=1G]")
|
||||
data := flags.String("data", "", "String of metadata to pass to VM; error to specify both -data and -data-file")
|
||||
dataPath := flags.String("data-file", "", "Path to file containing metadata to pass to VM; error to specify both -data and -data-file")
|
||||
|
||||
if *data != "" && *dataPath != "" {
|
||||
log.Fatal("Cannot specify both -data and -data-file")
|
||||
}
|
||||
|
||||
state := flags.String("state", "", "Path to directory to keep VM state in")
|
||||
networking := flags.String("networking", virtualizationNetworkingDefault, "Networking mode. Valid options are 'default', 'vmnet' and 'none'. 'vmnet' uses the Apple vmnet framework. 'none' disables networking.`")
|
||||
|
||||
kernelBoot := flags.Bool("kernel", false, "Boot image is kernel+initrd+cmdline 'path'-kernel/-initrd/-cmdline")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
remArgs := flags.Args()
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Println("Please specify the prefix to the image to boot")
|
||||
flags.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
path := remArgs[0]
|
||||
prefix := path
|
||||
|
||||
_, err := os.Stat(path + "-kernel")
|
||||
statKernel := err == nil
|
||||
|
||||
var isoPaths []string
|
||||
|
||||
// Default to kernel+initrd
|
||||
if !statKernel {
|
||||
log.Fatalf("Cannot find kernel file: %s", path+"-kernel")
|
||||
}
|
||||
_, err = os.Stat(path + "-initrd.img")
|
||||
statInitrd := err == nil
|
||||
if !statInitrd {
|
||||
log.Fatalf("Cannot find initrd file (%s): %v", path+"-initrd.img", err)
|
||||
}
|
||||
*kernelBoot = true
|
||||
|
||||
metadataPaths, err := CreateMetadataISO(*state, *data, *dataPath)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
isoPaths = append(isoPaths, metadataPaths...)
|
||||
|
||||
// TODO: We should generate new UUID, otherwise /sys/class/dmi/id/product_uuid is identical on all VMs.
|
||||
// but it is not clear if support is there in VF, or if it is built-in
|
||||
|
||||
// Run
|
||||
|
||||
cmdlineBytes, err := ioutil.ReadFile(prefix + "-cmdline")
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot open cmdline file: %v", err)
|
||||
}
|
||||
// must have hvc0 as console for vf
|
||||
kernelCommandLineArguments := strings.Split(string(cmdlineBytes), " ")
|
||||
|
||||
// Use the first virtio console device as system console.
|
||||
//"console=hvc0",
|
||||
// Stop in the initial ramdisk before attempting to transition to
|
||||
// the root file system.
|
||||
//"root=/dev/vda",
|
||||
kernelCommandLineArguments = append(kernelCommandLineArguments, "console=hvc0")
|
||||
|
||||
vmlinuz := prefix + "-kernel"
|
||||
initrd := prefix + "-initrd.img"
|
||||
|
||||
vmlinuzFile := vmlinuz
|
||||
// need to check if it is gzipped, and, if so, gunzip it
|
||||
filetype, err := checkFileType(vmlinuz)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to check kernel file type at %s: %v", vmlinuz, err)
|
||||
}
|
||||
|
||||
if filetype == "application/x-gzip" {
|
||||
vmlinuzUncompressed := fmt.Sprintf("%s-uncompressed", vmlinuz)
|
||||
// gzipped kernel, we load it into memory, unzip it, and pass it
|
||||
f, err := os.Open(vmlinuz)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to read kernel file %s: %v", vmlinuz, err)
|
||||
}
|
||||
defer f.Close()
|
||||
r, err := gzip.NewReader(f)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to read from file %s: %v", vmlinuz, err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
writer, err := os.Create(vmlinuzUncompressed)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to create decompressed kernel file %s: %v", vmlinuzUncompressed, err)
|
||||
}
|
||||
defer writer.Close()
|
||||
|
||||
if _, err = io.Copy(writer, r); err != nil {
|
||||
log.Fatalf("unable to decompress kernel file to %s: %v", vmlinuzUncompressed, err)
|
||||
}
|
||||
vmlinuzFile = vmlinuzUncompressed
|
||||
}
|
||||
bootLoader := vz.NewLinuxBootLoader(
|
||||
vmlinuzFile,
|
||||
vz.WithCommandLine(strings.Join(kernelCommandLineArguments, " ")),
|
||||
vz.WithInitrd(initrd),
|
||||
)
|
||||
|
||||
config := vz.NewVirtualMachineConfiguration(
|
||||
bootLoader,
|
||||
*cpus,
|
||||
memBytes,
|
||||
)
|
||||
|
||||
// console
|
||||
stdin, stdout := os.Stdin, os.Stdout
|
||||
serialPortAttachment := vz.NewFileHandleSerialPortAttachment(stdin, stdout)
|
||||
consoleConfig := vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment)
|
||||
config.SetSerialPortsVirtualMachineConfiguration([]*vz.VirtioConsoleDeviceSerialPortConfiguration{
|
||||
consoleConfig,
|
||||
})
|
||||
setRawMode(os.Stdin)
|
||||
|
||||
// network
|
||||
// Select network mode
|
||||
// for now, we only support vmnet and none, but hoping to have more in the future
|
||||
if *networking == "" || *networking == "default" {
|
||||
dflt := virtualizationNetworkingDefault
|
||||
networking = &dflt
|
||||
}
|
||||
netMode := strings.SplitN(*networking, ",", 3)
|
||||
switch netMode[0] {
|
||||
|
||||
case virtualizationNetworkingVMNet:
|
||||
natAttachment := vz.NewNATNetworkDeviceAttachment()
|
||||
networkConfig := vz.NewVirtioNetworkDeviceConfiguration(natAttachment)
|
||||
config.SetNetworkDevicesVirtualMachineConfiguration([]*vz.VirtioNetworkDeviceConfiguration{
|
||||
networkConfig,
|
||||
})
|
||||
networkConfig.SetMacAddress(vz.NewRandomLocallyAdministeredMACAddress())
|
||||
case virtualizationNetworkingNone:
|
||||
default:
|
||||
log.Fatalf("Invalid networking mode: %s", netMode[0])
|
||||
}
|
||||
|
||||
// entropy
|
||||
entropyConfig := vz.NewVirtioEntropyDeviceConfiguration()
|
||||
config.SetEntropyDevicesVirtualMachineConfiguration([]*vz.VirtioEntropyDeviceConfiguration{
|
||||
entropyConfig,
|
||||
})
|
||||
|
||||
var storageDevices []vz.StorageDeviceConfiguration
|
||||
for i, d := range disks {
|
||||
var id, diskPath string
|
||||
if i != 0 {
|
||||
id = strconv.Itoa(i)
|
||||
}
|
||||
if d.Size != 0 && d.Path == "" {
|
||||
diskPath = filepath.Join(*state, "disk"+id+".raw")
|
||||
}
|
||||
if d.Path == "" {
|
||||
log.Fatalf("disk specified with no size or name")
|
||||
}
|
||||
diskImageAttachment, err := vz.NewDiskImageStorageDeviceAttachment(
|
||||
diskPath,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
storageDeviceConfig := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment)
|
||||
storageDevices = append(storageDevices, storageDeviceConfig)
|
||||
}
|
||||
for _, iso := range isoPaths {
|
||||
diskImageAttachment, err := vz.NewDiskImageStorageDeviceAttachment(
|
||||
iso,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
storageDeviceConfig := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment)
|
||||
storageDevices = append(storageDevices, storageDeviceConfig)
|
||||
}
|
||||
|
||||
config.SetStorageDevicesVirtualMachineConfiguration(storageDevices)
|
||||
|
||||
// traditional memory balloon device which allows for managing guest memory. (optional)
|
||||
config.SetMemoryBalloonDevicesVirtualMachineConfiguration([]vz.MemoryBalloonDeviceConfiguration{
|
||||
vz.NewVirtioTraditionalMemoryBalloonDeviceConfiguration(),
|
||||
})
|
||||
|
||||
// socket device (optional)
|
||||
config.SetSocketDevicesVirtualMachineConfiguration([]vz.SocketDeviceConfiguration{
|
||||
vz.NewVirtioSocketDeviceConfiguration(),
|
||||
})
|
||||
validated, err := config.Validate()
|
||||
if !validated || err != nil {
|
||||
log.Fatal("validation failed", err)
|
||||
}
|
||||
|
||||
vm := vz.NewVirtualMachine(config)
|
||||
|
||||
signalCh := make(chan os.Signal, 1)
|
||||
signal.Notify(signalCh, syscall.SIGTERM)
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
vm.Start(func(err error) {
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
})
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-signalCh:
|
||||
result, err := vm.RequestStop()
|
||||
if err != nil {
|
||||
log.Println("request stop error:", err)
|
||||
return
|
||||
}
|
||||
log.Println("recieved signal", result)
|
||||
case newState := <-vm.StateChangedNotify():
|
||||
if newState == vz.VirtualMachineStateRunning {
|
||||
log.Println("start VM is running")
|
||||
}
|
||||
if newState == vz.VirtualMachineStateStopped {
|
||||
log.Println("stopped successfully")
|
||||
return
|
||||
}
|
||||
case err := <-errCh:
|
||||
log.Println("in start:", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// https://developer.apple.com/documentation/virtualization/running_linux_in_a_virtual_machine?language=objc#:~:text=Configure%20the%20Serial%20Port%20Device%20for%20Standard%20In%20and%20Out
|
||||
func setRawMode(f *os.File) {
|
||||
var attr unix.Termios
|
||||
|
||||
// Get settings for terminal
|
||||
termios.Tcgetattr(f.Fd(), &attr)
|
||||
|
||||
// Put stdin into raw mode, disabling local echo, input canonicalization,
|
||||
// and CR-NL mapping.
|
||||
attr.Iflag &^= syscall.ICRNL
|
||||
attr.Lflag &^= syscall.ICANON | syscall.ECHO
|
||||
|
||||
// Set minimum characters when reading = 1 char
|
||||
attr.Cc[syscall.VMIN] = 1
|
||||
|
||||
// set timeout when reading as non-canonical mode
|
||||
attr.Cc[syscall.VTIME] = 0
|
||||
|
||||
// reflects the changed settings
|
||||
termios.Tcsetattr(f.Fd(), termios.TCSANOW, &attr)
|
||||
}
|
||||
|
||||
func checkFileType(infile string) (string, error) {
|
||||
file, err := os.Open(infile)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
b := make([]byte, 512)
|
||||
|
||||
if _, err = file.Read(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return http.DetectContentType(b), nil
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package util
|
||||
|
2
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/.gitignore
generated
vendored
Normal file
2
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
virtualization
|
||||
*.log
|
21
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/LICENSE
generated
vendored
Normal file
21
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 codehex
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
52
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/README.md
generated
vendored
Normal file
52
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/README.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
vz - Go binding with Apple [Virtualization.framework](https://developer.apple.com/documentation/virtualization?language=objc)
|
||||
=======
|
||||
|
||||
vz provides the power of the Apple Virtualization.framework in Go. Put here is block quote of overreview which is written what is Virtualization.framework from the document.
|
||||
|
||||
> The Virtualization framework provides high-level APIs for creating and managing virtual machines on Apple silicon and Intel-based Mac computers. Use this framework to boot and run a Linux-based operating system in a custom environment that you define. The framework supports the Virtio specification, which defines standard interfaces for many device types, including network, socket, serial port, storage, entropy, and memory-balloon devices.
|
||||
|
||||
## USAGE
|
||||
|
||||
Please see the example directory.
|
||||
|
||||
## REQUIREMENTS
|
||||
|
||||
- Higher or equal to macOS Big Sur (11.0.0)
|
||||
- If you're M1 Mac User need higher or equal to Go 1.16
|
||||
|
||||
## IMPORTANT
|
||||
|
||||
For binaries used in this package, you need to create an entitlements file like the one below and apply the following command.
|
||||
|
||||
<details>
|
||||
<summary>vz.entitlements</summary>
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.virtualization</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
```sh
|
||||
$ codesign --entitlements vz.entitlements -s - <YOUR BINARY PATH>
|
||||
```
|
||||
|
||||
> A process must have the com.apple.security.virtualization entitlement to use the Virtualization APIs.
|
||||
|
||||
If you want to use [`VZBridgedNetworkDeviceAttachment`](https://developer.apple.com/documentation/virtualization/vzbridgednetworkdeviceattachment?language=objc), you need to add also `com.apple.vm.networking` entitlement.
|
||||
|
||||
## TODO
|
||||
|
||||
- [x] [VZMACAddress](https://developer.apple.com/documentation/virtualization/vzmacaddress?language=objc)
|
||||
- [ ] [VZVirtioSocketDeviceConfiguration](https://developer.apple.com/documentation/virtualization/sockets?language=objc)
|
||||
|
||||
## LICENSE
|
||||
|
||||
MIT License
|
89
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/bootloader.go
generated
vendored
Normal file
89
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/bootloader.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// BootLoader is the interface of boot loader definitions.
|
||||
// see: LinuxBootLoader
|
||||
type BootLoader interface {
|
||||
NSObject
|
||||
|
||||
bootLoader()
|
||||
}
|
||||
|
||||
type baseBootLoader struct{}
|
||||
|
||||
func (*baseBootLoader) bootLoader() {}
|
||||
|
||||
var _ BootLoader = (*LinuxBootLoader)(nil)
|
||||
|
||||
// LinuxBootLoader Boot loader configuration for a Linux kernel.
|
||||
type LinuxBootLoader struct {
|
||||
vmlinuzPath string
|
||||
initrdPath string
|
||||
cmdLine string
|
||||
pointer
|
||||
|
||||
*baseBootLoader
|
||||
}
|
||||
|
||||
func (b *LinuxBootLoader) String() string {
|
||||
return fmt.Sprintf(
|
||||
"vmlinuz: %q, initrd: %q, command-line: %q",
|
||||
b.vmlinuzPath,
|
||||
b.initrdPath,
|
||||
b.cmdLine,
|
||||
)
|
||||
}
|
||||
|
||||
type LinuxBootLoaderOption func(b *LinuxBootLoader)
|
||||
|
||||
// WithCommandLine sets the command-line parameters.
|
||||
// see: https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
|
||||
func WithCommandLine(cmdLine string) LinuxBootLoaderOption {
|
||||
return func(b *LinuxBootLoader) {
|
||||
b.cmdLine = cmdLine
|
||||
cs := charWithGoString(cmdLine)
|
||||
defer cs.Free()
|
||||
C.setCommandLineVZLinuxBootLoader(b.Ptr(), cs.CString())
|
||||
}
|
||||
}
|
||||
|
||||
// WithInitrd sets the optional initial RAM disk.
|
||||
func WithInitrd(initrdPath string) LinuxBootLoaderOption {
|
||||
return func(b *LinuxBootLoader) {
|
||||
b.initrdPath = initrdPath
|
||||
cs := charWithGoString(initrdPath)
|
||||
defer cs.Free()
|
||||
C.setInitialRamdiskURLVZLinuxBootLoader(b.Ptr(), cs.CString())
|
||||
}
|
||||
}
|
||||
|
||||
// NewLinuxBootLoader creates a LinuxBootLoader with the Linux kernel passed as Path.
|
||||
func NewLinuxBootLoader(vmlinuz string, opts ...LinuxBootLoaderOption) *LinuxBootLoader {
|
||||
vmlinuzPath := charWithGoString(vmlinuz)
|
||||
defer vmlinuzPath.Free()
|
||||
bootLoader := &LinuxBootLoader{
|
||||
vmlinuzPath: vmlinuz,
|
||||
pointer: pointer{
|
||||
ptr: C.newVZLinuxBootLoader(
|
||||
vmlinuzPath.CString(),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(bootLoader, func(self *LinuxBootLoader) {
|
||||
self.Release()
|
||||
})
|
||||
for _, opt := range opts {
|
||||
opt(bootLoader)
|
||||
}
|
||||
return bootLoader
|
||||
}
|
137
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/configuration.go
generated
vendored
Normal file
137
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/configuration.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import "runtime"
|
||||
|
||||
// VirtualMachineConfiguration defines the configuration of a VirtualMachine.
|
||||
//
|
||||
// The following properties must be configured before creating a virtual machine:
|
||||
// - bootLoader
|
||||
//
|
||||
// The configuration of devices is often done in two parts:
|
||||
// - Device configuration
|
||||
// - Device attachment
|
||||
//
|
||||
// The device configuration defines the characteristics of the emulated hardware device.
|
||||
// For example, for a network device, the device configuration defines the type of network adapter present
|
||||
// in the virtual machine and its MAC address.
|
||||
//
|
||||
// The device attachment defines the host machine's resources that are exposed by the virtual device.
|
||||
// For example, for a network device, the device attachment can be virtual network interface with a NAT
|
||||
// to the real network.
|
||||
//
|
||||
// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement.
|
||||
// A VirtualMachineConfiguration is considered invalid if the application does not have the entitlement.
|
||||
//
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachineconfiguration?language=objc
|
||||
type VirtualMachineConfiguration struct {
|
||||
cpuCount uint
|
||||
memorySize uint64
|
||||
pointer
|
||||
}
|
||||
|
||||
// NewVirtualMachineConfiguration creates a new configuration.
|
||||
//
|
||||
// - bootLoader parameter is used when the virtual machine starts.
|
||||
// - cpu parameter is The number of CPUs must be a value between
|
||||
// VZVirtualMachineConfiguration.minimumAllowedCPUCount and VZVirtualMachineConfiguration.maximumAllowedCPUCount.
|
||||
// - memorySize parameter represents memory size in bytes.
|
||||
// The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between
|
||||
// VZVirtualMachineConfiguration.minimumAllowedMemorySize and VZVirtualMachineConfiguration.maximumAllowedMemorySize.
|
||||
func NewVirtualMachineConfiguration(bootLoader BootLoader, cpu uint, memorySize uint64) *VirtualMachineConfiguration {
|
||||
config := &VirtualMachineConfiguration{
|
||||
cpuCount: cpu,
|
||||
memorySize: memorySize,
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtualMachineConfiguration(
|
||||
bootLoader.Ptr(),
|
||||
C.uint(cpu),
|
||||
C.ulonglong(memorySize),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtualMachineConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
||||
|
||||
// Validate the configuration.
|
||||
//
|
||||
// Return true if the configuration is valid.
|
||||
// If error is not nil, assigned with the validation error if the validation failed.
|
||||
func (v *VirtualMachineConfiguration) Validate() (bool, error) {
|
||||
nserr := newNSErrorAsNil()
|
||||
nserrPtr := nserr.Ptr()
|
||||
ret := C.validateVZVirtualMachineConfiguration(v.Ptr(), &nserrPtr)
|
||||
err := newNSError(nserrPtr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return (bool)(ret), nil
|
||||
}
|
||||
|
||||
// SetEntropyDevicesVirtualMachineConfiguration sets list of entropy devices. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetEntropyDevicesVirtualMachineConfiguration(cs []*VirtioEntropyDeviceConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setEntropyDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
||||
|
||||
// SetMemoryBalloonDevicesVirtualMachineConfiguration sets list of memory balloon devices. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetMemoryBalloonDevicesVirtualMachineConfiguration(cs []MemoryBalloonDeviceConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setMemoryBalloonDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
||||
|
||||
// SetNetworkDevicesVirtualMachineConfiguration sets list of network adapters. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetNetworkDevicesVirtualMachineConfiguration(cs []*VirtioNetworkDeviceConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setNetworkDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
||||
|
||||
// SetSerialPortsVirtualMachineConfiguration sets list of serial ports. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetSerialPortsVirtualMachineConfiguration(cs []*VirtioConsoleDeviceSerialPortConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setSerialPortsVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
||||
|
||||
// SetSocketDevicesVirtualMachineConfiguration sets list of socket devices. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetSocketDevicesVirtualMachineConfiguration(cs []SocketDeviceConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setSocketDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
||||
|
||||
// SetStorageDevicesVirtualMachineConfiguration sets list of disk devices. Empty by default.
|
||||
func (v *VirtualMachineConfiguration) SetStorageDevicesVirtualMachineConfiguration(cs []StorageDeviceConfiguration) {
|
||||
ptrs := make([]NSObject, len(cs))
|
||||
for i, val := range cs {
|
||||
ptrs[i] = val
|
||||
}
|
||||
array := convertToNSMutableArray(ptrs)
|
||||
C.setStorageDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
|
||||
}
|
123
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/console.go
generated
vendored
Normal file
123
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/console.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// SerialPortAttachment interface for a serial port attachment.
|
||||
//
|
||||
// A serial port attachment defines how the virtual machine's serial port interfaces with the host system.
|
||||
type SerialPortAttachment interface {
|
||||
NSObject
|
||||
|
||||
serialPortAttachment()
|
||||
}
|
||||
|
||||
type baseSerialPortAttachment struct{}
|
||||
|
||||
func (*baseSerialPortAttachment) serialPortAttachment() {}
|
||||
|
||||
var _ SerialPortAttachment = (*FileHandleSerialPortAttachment)(nil)
|
||||
|
||||
// FileHandleSerialPortAttachment defines a serial port attachment from a file handle.
|
||||
//
|
||||
// Data written to fileHandleForReading goes to the guest. Data sent from the guest appears on fileHandleForWriting.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzfilehandleserialportattachment?language=objc
|
||||
type FileHandleSerialPortAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseSerialPortAttachment
|
||||
}
|
||||
|
||||
// NewFileHandleSerialPortAttachment intialize the FileHandleSerialPortAttachment from file handles.
|
||||
//
|
||||
// read parameter is an *os.File for reading from the file.
|
||||
// write parameter is an *os.File for writing to the file.
|
||||
func NewFileHandleSerialPortAttachment(read, write *os.File) *FileHandleSerialPortAttachment {
|
||||
attachment := &FileHandleSerialPortAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZFileHandleSerialPortAttachment(
|
||||
C.int(read.Fd()),
|
||||
C.int(write.Fd()),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *FileHandleSerialPortAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment
|
||||
}
|
||||
|
||||
var _ SerialPortAttachment = (*FileSerialPortAttachment)(nil)
|
||||
|
||||
// FileSerialPortAttachment defines a serial port attachment from a file.
|
||||
//
|
||||
// Any data sent by the guest on the serial interface is written to the file.
|
||||
// No data is sent to the guest over serial with this attachment.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzfileserialportattachment?language=objc
|
||||
type FileSerialPortAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseSerialPortAttachment
|
||||
}
|
||||
|
||||
// NewFileSerialPortAttachment initialize the FileSerialPortAttachment from a path of a file.
|
||||
// If error is not nil, used to report errors if intialization fails.
|
||||
//
|
||||
// - path of the file for the attachment on the local file system.
|
||||
// - shouldAppend True if the file should be opened in append mode, false otherwise.
|
||||
// When a file is opened in append mode, writing to that file will append to the end of it.
|
||||
func NewFileSerialPortAttachment(path string, shouldAppend bool) (*FileSerialPortAttachment, error) {
|
||||
cpath := charWithGoString(path)
|
||||
defer cpath.Free()
|
||||
|
||||
nserr := newNSErrorAsNil()
|
||||
nserrPtr := nserr.Ptr()
|
||||
attachment := &FileSerialPortAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZFileSerialPortAttachment(
|
||||
cpath.CString(),
|
||||
C.bool(shouldAppend),
|
||||
&nserrPtr,
|
||||
),
|
||||
},
|
||||
}
|
||||
if err := newNSError(nserrPtr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *FileSerialPortAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment, nil
|
||||
}
|
||||
|
||||
// VirtioConsoleDeviceSerialPortConfiguration represents Virtio Console Serial Port Device.
|
||||
//
|
||||
// The device creates a console which enables communication between the host and the guest through the Virtio interface.
|
||||
// The device sets up a single port on the Virtio console device.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtioconsoledeviceserialportconfiguration?language=objc
|
||||
type VirtioConsoleDeviceSerialPortConfiguration struct {
|
||||
pointer
|
||||
}
|
||||
|
||||
// NewVirtioConsoleDeviceSerialPortConfiguration creates a new NewVirtioConsoleDeviceSerialPortConfiguration.
|
||||
func NewVirtioConsoleDeviceSerialPortConfiguration(attachment SerialPortAttachment) *VirtioConsoleDeviceSerialPortConfiguration {
|
||||
config := &VirtioConsoleDeviceSerialPortConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioConsoleDeviceSerialPortConfiguration(
|
||||
attachment.Ptr(),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioConsoleDeviceSerialPortConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
31
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/entropy.go
generated
vendored
Normal file
31
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/entropy.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import "runtime"
|
||||
|
||||
// VirtioEntropyDeviceConfiguration is used to expose a source of entropy for the guest operating system’s random-number generator.
|
||||
// When you create this object and add it to your virtual machine’s configuration, the virtual machine configures a Virtio-compliant
|
||||
// entropy device. The guest operating system uses this device as a seed to generate random numbers.
|
||||
//
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtioentropydeviceconfiguration?language=objc
|
||||
type VirtioEntropyDeviceConfiguration struct {
|
||||
pointer
|
||||
}
|
||||
|
||||
// NewVirtioEntropyDeviceConfiguration creates a new Virtio Entropy Device confiuration.
|
||||
func NewVirtioEntropyDeviceConfiguration() *VirtioEntropyDeviceConfiguration {
|
||||
config := &VirtioEntropyDeviceConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioEntropyDeviceConfiguration(),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioEntropyDeviceConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
5
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/go.mod
generated
vendored
Normal file
5
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/go.mod
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module github.com/Code-Hex/vz
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/rs/xid v1.2.1
|
2
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/go.sum
generated
vendored
Normal file
2
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/go.sum
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
44
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/memory_balloon.go
generated
vendored
Normal file
44
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/memory_balloon.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import "runtime"
|
||||
|
||||
// MemoryBalloonDeviceConfiguration for a memory balloon device configuration.
|
||||
type MemoryBalloonDeviceConfiguration interface {
|
||||
NSObject
|
||||
|
||||
memoryBalloonDeviceConfiguration()
|
||||
}
|
||||
|
||||
type baseMemoryBalloonDeviceConfiguration struct{}
|
||||
|
||||
func (*baseMemoryBalloonDeviceConfiguration) memoryBalloonDeviceConfiguration() {}
|
||||
|
||||
var _ MemoryBalloonDeviceConfiguration = (*VirtioTraditionalMemoryBalloonDeviceConfiguration)(nil)
|
||||
|
||||
// VirtioTraditionalMemoryBalloonDeviceConfiguration is a configuration of the Virtio traditional memory balloon device.
|
||||
//
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtiotraditionalmemoryballoondeviceconfiguration?language=objc
|
||||
type VirtioTraditionalMemoryBalloonDeviceConfiguration struct {
|
||||
pointer
|
||||
|
||||
*baseMemoryBalloonDeviceConfiguration
|
||||
}
|
||||
|
||||
// NewVirtioTraditionalMemoryBalloonDeviceConfiguration creates a new VirtioTraditionalMemoryBalloonDeviceConfiguration.
|
||||
func NewVirtioTraditionalMemoryBalloonDeviceConfiguration() *VirtioTraditionalMemoryBalloonDeviceConfiguration {
|
||||
config := &VirtioTraditionalMemoryBalloonDeviceConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioTraditionalMemoryBalloonDeviceConfiguration(),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioTraditionalMemoryBalloonDeviceConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
211
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/network.go
generated
vendored
Normal file
211
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/network.go
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// BridgedNetwork defines a network interface that bridges a physical interface with a virtual machine.
|
||||
//
|
||||
// A bridged interface is shared between the virtual machine and the host system. Both host and
|
||||
// virtual machine send and receive packets on the same physical interface but have distinct network layers.
|
||||
//
|
||||
// The BridgedNetwork can be used with a BridgedNetworkDeviceAttachment to set up a network device NetworkDeviceConfiguration.
|
||||
// TODO(codehex): implement...
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzbridgednetworkinterface?language=objc
|
||||
type BridgedNetwork interface {
|
||||
NSObject
|
||||
|
||||
// NetworkInterfaces returns the list of network interfaces available for bridging.
|
||||
NetworkInterfaces() []BridgedNetwork
|
||||
|
||||
// Identifier returns the unique identifier for this interface.
|
||||
// The identifier is the BSD name associated with the interface (e.g. "en0").
|
||||
Identifier() string
|
||||
|
||||
// LocalizedDisplayName returns a display name if available (e.g. "Ethernet").
|
||||
LocalizedDisplayName() string
|
||||
}
|
||||
|
||||
// Network device attachment using network address translation (NAT) with outside networks.
|
||||
//
|
||||
// Using the NAT attachment type, the host serves as router and performs network address translation
|
||||
// for accesses to outside networks.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vznatnetworkdeviceattachment?language=objc
|
||||
type NATNetworkDeviceAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseNetworkDeviceAttachment
|
||||
}
|
||||
|
||||
var _ NetworkDeviceAttachment = (*NATNetworkDeviceAttachment)(nil)
|
||||
|
||||
// NewNATNetworkDeviceAttachment creates a new NATNetworkDeviceAttachment.
|
||||
func NewNATNetworkDeviceAttachment() *NATNetworkDeviceAttachment {
|
||||
attachment := &NATNetworkDeviceAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZNATNetworkDeviceAttachment(),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *NATNetworkDeviceAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment
|
||||
}
|
||||
|
||||
// BridgedNetworkDeviceAttachment represents a physical interface on the host computer.
|
||||
//
|
||||
// Use this struct when configuring a network interface for your virtual machine.
|
||||
// A bridged network device sends and receives packets on the same physical interface
|
||||
// as the host computer, but does so using a different network layer.
|
||||
//
|
||||
// To use this attachment, your app must have the com.apple.vm.networking entitlement.
|
||||
// If it doesn’t, the use of this attachment point results in an invalid VZVirtualMachineConfiguration object in objective-c.
|
||||
//
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzbridgednetworkdeviceattachment?language=objc
|
||||
type BridgedNetworkDeviceAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseNetworkDeviceAttachment
|
||||
}
|
||||
|
||||
var _ NetworkDeviceAttachment = (*BridgedNetworkDeviceAttachment)(nil)
|
||||
|
||||
// NewBridgedNetworkDeviceAttachment creates a new BridgedNetworkDeviceAttachment with networkInterface.
|
||||
func NewBridgedNetworkDeviceAttachment(networkInterface BridgedNetwork) *BridgedNetworkDeviceAttachment {
|
||||
attachment := &BridgedNetworkDeviceAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZBridgedNetworkDeviceAttachment(
|
||||
networkInterface.Ptr(),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *BridgedNetworkDeviceAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment
|
||||
}
|
||||
|
||||
// FileHandleNetworkDeviceAttachment sending raw network packets over a file handle.
|
||||
//
|
||||
// The file handle attachment transmits the raw packets/frames between the virtual network interface and a file handle.
|
||||
// The data transmitted through this attachment is at the level of the data link layer.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzfilehandlenetworkdeviceattachment?language=objc
|
||||
type FileHandleNetworkDeviceAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseNetworkDeviceAttachment
|
||||
}
|
||||
|
||||
var _ NetworkDeviceAttachment = (*FileHandleNetworkDeviceAttachment)(nil)
|
||||
|
||||
// NewFileHandleNetworkDeviceAttachment initialize the attachment with a file handle.
|
||||
//
|
||||
// file parameter is holding a connected datagram socket.
|
||||
func NewFileHandleNetworkDeviceAttachment(file *os.File) *FileHandleNetworkDeviceAttachment {
|
||||
attachment := &FileHandleNetworkDeviceAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZFileHandleNetworkDeviceAttachment(
|
||||
C.int(file.Fd()),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *FileHandleNetworkDeviceAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment
|
||||
}
|
||||
|
||||
// NetworkDeviceAttachment for a network device attachment.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vznetworkdeviceattachment?language=objc
|
||||
type NetworkDeviceAttachment interface {
|
||||
NSObject
|
||||
|
||||
networkDeviceAttachment()
|
||||
}
|
||||
|
||||
type baseNetworkDeviceAttachment struct{}
|
||||
|
||||
func (*baseNetworkDeviceAttachment) networkDeviceAttachment() {}
|
||||
|
||||
// VirtioNetworkDeviceConfiguration is configuration of a paravirtualized network device of type Virtio Network Device.
|
||||
//
|
||||
// The communication channel used on the host is defined through the attachment.
|
||||
// It is set with the VZNetworkDeviceConfiguration.attachment property in objective-c.
|
||||
//
|
||||
// The configuration is only valid with valid MACAddress and attachment.
|
||||
//
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtionetworkdeviceconfiguration?language=objc
|
||||
type VirtioNetworkDeviceConfiguration struct {
|
||||
pointer
|
||||
}
|
||||
|
||||
// NewVirtioNetworkDeviceConfiguration creates a new VirtioNetworkDeviceConfiguration with NetworkDeviceAttachment.
|
||||
func NewVirtioNetworkDeviceConfiguration(attachment NetworkDeviceAttachment) *VirtioNetworkDeviceConfiguration {
|
||||
config := &VirtioNetworkDeviceConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioNetworkDeviceConfiguration(
|
||||
attachment.Ptr(),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioNetworkDeviceConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
||||
|
||||
func (v *VirtioNetworkDeviceConfiguration) SetMacAddress(macAddress *MACAddress) {
|
||||
C.setNetworkDevicesVZMACAddress(v.Ptr(), macAddress.Ptr())
|
||||
}
|
||||
|
||||
// MACAddress represents a media access control address (MAC address), the 48-bit ethernet address.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzmacaddress?language=objc
|
||||
type MACAddress struct {
|
||||
pointer
|
||||
}
|
||||
|
||||
// NewMACAddress creates a new MACAddress with net.HardwareAddr (MAC address).
|
||||
func NewMACAddress(macAddr net.HardwareAddr) *MACAddress {
|
||||
macAddrChar := charWithGoString(macAddr.String())
|
||||
defer macAddrChar.Free()
|
||||
ma := &MACAddress{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZMACAddress(macAddrChar.CString()),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(ma, func(self *MACAddress) {
|
||||
self.Release()
|
||||
})
|
||||
return ma
|
||||
}
|
||||
|
||||
// NewRandomLocallyAdministeredMACAddress creates a valid, random, unicast, locally administered address.
|
||||
func NewRandomLocallyAdministeredMACAddress() *MACAddress {
|
||||
ma := &MACAddress{
|
||||
pointer: pointer{
|
||||
ptr: C.newRandomLocallyAdministeredVZMACAddress(),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(ma, func(self *MACAddress) {
|
||||
self.Release()
|
||||
})
|
||||
return ma
|
||||
}
|
||||
|
||||
func (m *MACAddress) String() string {
|
||||
cstring := (*char)(C.getVZMACAddressString(m.Ptr()))
|
||||
return cstring.String()
|
||||
}
|
||||
|
||||
func (m *MACAddress) HardwareAddr() net.HardwareAddr {
|
||||
hw, _ := net.ParseMAC(m.String())
|
||||
return hw
|
||||
}
|
206
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/objcutil.go
generated
vendored
Normal file
206
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/objcutil.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
|
||||
const char *getNSErrorLocalizedDescription(void *err)
|
||||
{
|
||||
NSString *ld = (NSString *)[(NSError *)err localizedDescription];
|
||||
return [ld UTF8String];
|
||||
}
|
||||
|
||||
const char *getNSErrorDomain(void *err)
|
||||
{
|
||||
const char *ret;
|
||||
@autoreleasepool {
|
||||
NSString *domain = (NSString *)[(NSError *)err domain];
|
||||
ret = [domain UTF8String];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *getNSErrorUserInfo(void *err)
|
||||
{
|
||||
NSDictionary<NSErrorUserInfoKey, id> *ui = [(NSError *)err userInfo];
|
||||
NSString *uis = [NSString stringWithFormat:@"%@", ui];
|
||||
return [uis UTF8String];
|
||||
}
|
||||
|
||||
NSInteger getNSErrorCode(void *err)
|
||||
{
|
||||
return (NSInteger)[(NSError *)err code];
|
||||
}
|
||||
|
||||
void *makeNSMutableArray(unsigned long cap)
|
||||
{
|
||||
return [[NSMutableArray alloc] initWithCapacity:(NSUInteger)cap];
|
||||
}
|
||||
|
||||
void addNSMutableArrayVal(void *ary, void *val)
|
||||
{
|
||||
[(NSMutableArray *)ary addObject:(NSObject *)val];
|
||||
}
|
||||
|
||||
void *newNSError()
|
||||
{
|
||||
NSError *err = nil;
|
||||
return err;
|
||||
}
|
||||
|
||||
bool hasError(void *err)
|
||||
{
|
||||
return (NSError *)err != nil;
|
||||
}
|
||||
|
||||
void *minimumAlloc()
|
||||
{
|
||||
return [[NSMutableData dataWithLength:1] mutableBytes];
|
||||
}
|
||||
|
||||
void releaseNSObject(void* o)
|
||||
{
|
||||
@autoreleasepool {
|
||||
[(NSObject*)o release];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void startNSThread()
|
||||
{
|
||||
[[NSThread new] start]; // put the runtime into multi-threaded mode
|
||||
}
|
||||
|
||||
static inline void releaseDispatch(void *queue)
|
||||
{
|
||||
dispatch_release((dispatch_queue_t)queue);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// startNSThread starts NSThread.
|
||||
func startNSThread() {
|
||||
C.startNSThread()
|
||||
}
|
||||
|
||||
// releaseDispatch releases allocated dispatch_queue_t
|
||||
func releaseDispatch(p unsafe.Pointer) {
|
||||
C.releaseDispatch(p)
|
||||
}
|
||||
|
||||
// CharWithGoString makes *Char which is *C.Char wrapper from Go string.
|
||||
func charWithGoString(s string) *char {
|
||||
return (*char)(unsafe.Pointer(C.CString(s)))
|
||||
}
|
||||
|
||||
// Char is a wrapper of C.char
|
||||
type char C.char
|
||||
|
||||
// CString converts *C.char from *Char
|
||||
func (c *char) CString() *C.char {
|
||||
return (*C.char)(c)
|
||||
}
|
||||
|
||||
// String converts Go string from *Char
|
||||
func (c *char) String() string {
|
||||
return C.GoString((*C.char)(c))
|
||||
}
|
||||
|
||||
// Free frees allocated *C.char in Go code
|
||||
func (c *char) Free() {
|
||||
C.free(unsafe.Pointer(c))
|
||||
}
|
||||
|
||||
// pointer indicates any pointers which are allocated in objective-c world.
|
||||
type pointer struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
// Release releases allocated resources in objective-c world.
|
||||
func (p *pointer) Release() {
|
||||
C.releaseNSObject(p.Ptr())
|
||||
runtime.KeepAlive(p)
|
||||
}
|
||||
|
||||
// Ptr returns raw pointer.
|
||||
func (o *pointer) Ptr() unsafe.Pointer {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
return o.ptr
|
||||
}
|
||||
|
||||
// NSObject indicates NSObject
|
||||
type NSObject interface {
|
||||
Ptr() unsafe.Pointer
|
||||
}
|
||||
|
||||
// NSError indicates NSError.
|
||||
type NSError struct {
|
||||
Domain string
|
||||
Code int
|
||||
LocalizedDescription string
|
||||
UserInfo string
|
||||
pointer
|
||||
}
|
||||
|
||||
// newNSErrorAsNil makes nil NSError in objective-c world.
|
||||
func newNSErrorAsNil() *pointer {
|
||||
p := &pointer{
|
||||
ptr: unsafe.Pointer(C.newNSError()),
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// hasNSError checks passed pointer is NSError or not.
|
||||
func hasNSError(nserrPtr unsafe.Pointer) bool {
|
||||
return (bool)(C.hasError(nserrPtr))
|
||||
}
|
||||
|
||||
func (n *NSError) Error() string {
|
||||
if n == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"Error Domain=%s Code=%d Description=%q UserInfo=%s",
|
||||
n.Domain,
|
||||
n.Code,
|
||||
n.LocalizedDescription,
|
||||
n.UserInfo,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO(codehex): improvement (3 times called C functions now)
|
||||
func newNSError(p unsafe.Pointer) *NSError {
|
||||
if !hasNSError(p) {
|
||||
return nil
|
||||
}
|
||||
domain := (*char)(C.getNSErrorDomain(p))
|
||||
description := (*char)(C.getNSErrorLocalizedDescription(p))
|
||||
userInfo := (*char)(C.getNSErrorUserInfo(p))
|
||||
return &NSError{
|
||||
Domain: domain.String(),
|
||||
Code: int(C.getNSErrorCode(p)),
|
||||
LocalizedDescription: description.String(),
|
||||
UserInfo: userInfo.String(), // NOTE(codehex): maybe we can convert to map[string]interface{}
|
||||
}
|
||||
}
|
||||
|
||||
// convertToNSMutableArray converts to NSMutableArray from NSObject slice in Go world.
|
||||
func convertToNSMutableArray(s []NSObject) *pointer {
|
||||
ln := len(s)
|
||||
ary := C.makeNSMutableArray(C.ulong(ln))
|
||||
for _, v := range s {
|
||||
C.addNSMutableArrayVal(ary, v.Ptr())
|
||||
}
|
||||
p := &pointer{ptr: ary}
|
||||
runtime.SetFinalizer(p, func(self *pointer) {
|
||||
self.Release()
|
||||
})
|
||||
return p
|
||||
}
|
46
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/socket.go
generated
vendored
Normal file
46
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/socket.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import "runtime"
|
||||
|
||||
// SocketDeviceConfiguration for a socket device configuration.
|
||||
type SocketDeviceConfiguration interface {
|
||||
NSObject
|
||||
|
||||
socketDeviceConfiguration()
|
||||
}
|
||||
|
||||
type baseSocketDeviceConfiguration struct{}
|
||||
|
||||
func (*baseSocketDeviceConfiguration) socketDeviceConfiguration() {}
|
||||
|
||||
var _ SocketDeviceConfiguration = (*VirtioSocketDeviceConfiguration)(nil)
|
||||
|
||||
// VirtioSocketDeviceConfiguration is a configuration of the Virtio socket device.
|
||||
//
|
||||
// This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface.
|
||||
// Only one Virtio socket device can be used per virtual machine.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdeviceconfiguration?language=objc
|
||||
type VirtioSocketDeviceConfiguration struct {
|
||||
pointer
|
||||
|
||||
*baseSocketDeviceConfiguration
|
||||
}
|
||||
|
||||
// NewVirtioSocketDeviceConfiguration creates a new VirtioSocketDeviceConfiguration.
|
||||
func NewVirtioSocketDeviceConfiguration() *VirtioSocketDeviceConfiguration {
|
||||
config := &VirtioSocketDeviceConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioSocketDeviceConfiguration(),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioSocketDeviceConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
109
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/storage.go
generated
vendored
Normal file
109
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/storage.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import "runtime"
|
||||
|
||||
type baseStorageDeviceAttachment struct{}
|
||||
|
||||
func (*baseStorageDeviceAttachment) storageDeviceAttachment() {}
|
||||
|
||||
// StorageDeviceAttachment for a storage device attachment.
|
||||
//
|
||||
// A storage device attachment defines how a virtual machine storage device interfaces with the host system.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzstoragedeviceattachment?language=objc
|
||||
type StorageDeviceAttachment interface {
|
||||
NSObject
|
||||
|
||||
storageDeviceAttachment()
|
||||
}
|
||||
|
||||
var _ StorageDeviceAttachment = (*DiskImageStorageDeviceAttachment)(nil)
|
||||
|
||||
// DiskImageStorageDeviceAttachment is a storage device attachment using a disk image to implement the storage.
|
||||
//
|
||||
// This storage device attachment uses a disk image on the host file system as the drive of the storage device.
|
||||
// Only raw data disk images are supported.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzdiskimagestoragedeviceattachment?language=objc
|
||||
type DiskImageStorageDeviceAttachment struct {
|
||||
pointer
|
||||
|
||||
*baseStorageDeviceAttachment
|
||||
}
|
||||
|
||||
// NewDiskImageStorageDeviceAttachment initialize the attachment from a local file path.
|
||||
// Returns error is not nil, assigned with the error if the initialization failed.
|
||||
//
|
||||
// - diskPath is local file URL to the disk image in RAW format.
|
||||
// - readOnly if YES, the device attachment is read-only, otherwise the device can write data to the disk image.
|
||||
func NewDiskImageStorageDeviceAttachment(diskPath string, readOnly bool) (*DiskImageStorageDeviceAttachment, error) {
|
||||
nserr := newNSErrorAsNil()
|
||||
nserrPtr := nserr.Ptr()
|
||||
|
||||
diskPathChar := charWithGoString(diskPath)
|
||||
defer diskPathChar.Free()
|
||||
attachment := &DiskImageStorageDeviceAttachment{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZDiskImageStorageDeviceAttachment(
|
||||
diskPathChar.CString(),
|
||||
C.bool(readOnly),
|
||||
&nserrPtr,
|
||||
),
|
||||
},
|
||||
}
|
||||
if err := newNSError(nserrPtr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtime.SetFinalizer(attachment, func(self *DiskImageStorageDeviceAttachment) {
|
||||
self.Release()
|
||||
})
|
||||
return attachment, nil
|
||||
}
|
||||
|
||||
// StorageDeviceConfiguration for a storage device configuration.
|
||||
type StorageDeviceConfiguration interface {
|
||||
NSObject
|
||||
|
||||
storageDeviceConfiguration()
|
||||
}
|
||||
|
||||
type baseStorageDeviceConfiguration struct{}
|
||||
|
||||
func (*baseStorageDeviceConfiguration) storageDeviceConfiguration() {}
|
||||
|
||||
var _ StorageDeviceConfiguration = (*VirtioBlockDeviceConfiguration)(nil)
|
||||
|
||||
// VirtioBlockDeviceConfiguration is a configuration of a paravirtualized storage device of type Virtio Block Device.
|
||||
//
|
||||
// This device configuration creates a storage device using paravirtualization.
|
||||
// The emulated device follows the Virtio Block Device specification.
|
||||
//
|
||||
// The host implementation of the device is done through an attachment subclassing VZStorageDeviceAttachment
|
||||
// like VZDiskImageStorageDeviceAttachment.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtioblockdeviceconfiguration?language=objc
|
||||
type VirtioBlockDeviceConfiguration struct {
|
||||
pointer
|
||||
|
||||
*baseStorageDeviceConfiguration
|
||||
}
|
||||
|
||||
// NewVirtioBlockDeviceConfiguration initialize a VZVirtioBlockDeviceConfiguration with a device attachment.
|
||||
//
|
||||
// - attachment The storage device attachment. This defines how the virtualized device operates on the host side.
|
||||
func NewVirtioBlockDeviceConfiguration(attachment StorageDeviceAttachment) *VirtioBlockDeviceConfiguration {
|
||||
config := &VirtioBlockDeviceConfiguration{
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtioBlockDeviceConfiguration(
|
||||
attachment.Ptr(),
|
||||
),
|
||||
},
|
||||
}
|
||||
runtime.SetFinalizer(config, func(self *VirtioBlockDeviceConfiguration) {
|
||||
self.Release()
|
||||
})
|
||||
return config
|
||||
}
|
283
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.go
generated
vendored
Normal file
283
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.go
generated
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
package vz
|
||||
|
||||
/*
|
||||
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
|
||||
# include "virtualization.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/rs/xid"
|
||||
)
|
||||
|
||||
func init() {
|
||||
startNSThread()
|
||||
}
|
||||
|
||||
// VirtualMachineState represents execution state of the virtual machine.
|
||||
type VirtualMachineState int
|
||||
|
||||
const (
|
||||
// VirtualMachineStateStopped Initial state before the virtual machine is started.
|
||||
VirtualMachineStateStopped VirtualMachineState = iota
|
||||
|
||||
// VirtualMachineStateRunning Running virtual machine.
|
||||
VirtualMachineStateRunning
|
||||
|
||||
// VirtualMachineStatePaused A started virtual machine is paused.
|
||||
// This state can only be transitioned from VirtualMachineStatePausing.
|
||||
VirtualMachineStatePaused
|
||||
|
||||
// VirtualMachineStateError The virtual machine has encountered an internal error.
|
||||
VirtualMachineStateError
|
||||
|
||||
// VirtualMachineStateStarting The virtual machine is configuring the hardware and starting.
|
||||
VirtualMachineStateStarting
|
||||
|
||||
// VirtualMachineStatePausing The virtual machine is being paused.
|
||||
// This is the intermediate state between VirtualMachineStateRunning and VirtualMachineStatePaused.
|
||||
VirtualMachineStatePausing
|
||||
|
||||
// VirtualMachineStateResuming The virtual machine is being resumed.
|
||||
// This is the intermediate state between VirtualMachineStatePaused and VirtualMachineStateRunning.
|
||||
VirtualMachineStateResuming
|
||||
)
|
||||
|
||||
// VirtualMachine represents the entire state of a single virtual machine.
|
||||
//
|
||||
// A Virtual Machine is the emulation of a complete hardware machine of the same architecture as the real hardware machine.
|
||||
// When executing the Virtual Machine, the Virtualization framework uses certain hardware resources and emulates others to provide isolation
|
||||
// and great performance.
|
||||
//
|
||||
// The definition of a virtual machine starts with its configuration. This is done by setting up a VirtualMachineConfiguration struct.
|
||||
// Once configured, the virtual machine can be started with (*VirtualMachine).Start() method.
|
||||
//
|
||||
// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement.
|
||||
// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachine?language=objc
|
||||
type VirtualMachine struct {
|
||||
// id for this struct.
|
||||
id string
|
||||
|
||||
// Indicate whether or not virtualization is available.
|
||||
//
|
||||
// If virtualization is unavailable, no VirtualMachineConfiguration will validate.
|
||||
// The validation error of the VirtualMachineConfiguration provides more information about why virtualization is unavailable.
|
||||
supported bool
|
||||
|
||||
pointer
|
||||
dispatchQueue unsafe.Pointer
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type (
|
||||
machineStatus struct {
|
||||
state VirtualMachineState
|
||||
stateNotify chan VirtualMachineState
|
||||
|
||||
mu sync.RWMutex
|
||||
}
|
||||
machineHandlers struct {
|
||||
start func(error)
|
||||
pause func(error)
|
||||
resume func(error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
handlers = map[string]*machineHandlers{}
|
||||
statuses = map[string]*machineStatus{}
|
||||
)
|
||||
|
||||
// NewVirtualMachine creates a new VirtualMachine with VirtualMachineConfiguration.
|
||||
//
|
||||
// The configuration must be valid. Validation can be performed at runtime with (*VirtualMachineConfiguration).Validate() method.
|
||||
// The configuration is copied by the initializer.
|
||||
//
|
||||
// A new dispatch queue will create when called this function.
|
||||
// Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue.
|
||||
func NewVirtualMachine(config *VirtualMachineConfiguration) *VirtualMachine {
|
||||
id := xid.New().String()
|
||||
cs := charWithGoString(id)
|
||||
defer cs.Free()
|
||||
statuses[id] = &machineStatus{
|
||||
state: VirtualMachineState(0),
|
||||
stateNotify: make(chan VirtualMachineState),
|
||||
}
|
||||
handlers[id] = &machineHandlers{
|
||||
start: func(error) {},
|
||||
pause: func(error) {},
|
||||
resume: func(error) {},
|
||||
}
|
||||
dispatchQueue := C.makeDispatchQueue(cs.CString())
|
||||
v := &VirtualMachine{
|
||||
id: id,
|
||||
pointer: pointer{
|
||||
ptr: C.newVZVirtualMachineWithDispatchQueue(
|
||||
config.Ptr(),
|
||||
dispatchQueue,
|
||||
cs.CString(),
|
||||
),
|
||||
},
|
||||
dispatchQueue: dispatchQueue,
|
||||
}
|
||||
runtime.SetFinalizer(v, func(self *VirtualMachine) {
|
||||
releaseDispatch(self.dispatchQueue)
|
||||
self.Release()
|
||||
})
|
||||
return v
|
||||
}
|
||||
|
||||
//export changeStateOnObserver
|
||||
func changeStateOnObserver(state C.int, cID *C.char) {
|
||||
id := (*char)(cID)
|
||||
// I expected it will not cause panic.
|
||||
// if caused panic, that's unexpected behavior.
|
||||
v, _ := statuses[id.String()]
|
||||
v.mu.Lock()
|
||||
newState := VirtualMachineState(state)
|
||||
v.state = newState
|
||||
// for non-blocking
|
||||
go func() { v.stateNotify <- newState }()
|
||||
statuses[id.String()] = v
|
||||
v.mu.Unlock()
|
||||
}
|
||||
|
||||
// State represents execution state of the virtual machine.
|
||||
func (v *VirtualMachine) State() VirtualMachineState {
|
||||
// I expected it will not cause panic.
|
||||
// if caused panic, that's unexpected behavior.
|
||||
val, _ := statuses[v.id]
|
||||
val.mu.RLock()
|
||||
defer val.mu.RUnlock()
|
||||
return val.state
|
||||
}
|
||||
|
||||
// StateChangedNotify gets notification is changed execution state of the virtual machine.
|
||||
func (v *VirtualMachine) StateChangedNotify() <-chan VirtualMachineState {
|
||||
// I expected it will not cause panic.
|
||||
// if caused panic, that's unexpected behavior.
|
||||
val, _ := statuses[v.id]
|
||||
val.mu.RLock()
|
||||
defer val.mu.RUnlock()
|
||||
return val.stateNotify
|
||||
}
|
||||
|
||||
// CanStart returns true if the machine is in a state that can be started.
|
||||
func (v *VirtualMachine) CanStart() bool {
|
||||
return bool(C.vmCanStart(v.Ptr(), v.dispatchQueue))
|
||||
}
|
||||
|
||||
// CanPause returns true if the machine is in a state that can be paused.
|
||||
func (v *VirtualMachine) CanPause() bool {
|
||||
return bool(C.vmCanPause(v.Ptr(), v.dispatchQueue))
|
||||
}
|
||||
|
||||
// CanResume returns true if the machine is in a state that can be resumed.
|
||||
func (v *VirtualMachine) CanResume() bool {
|
||||
return (bool)(C.vmCanResume(v.Ptr(), v.dispatchQueue))
|
||||
}
|
||||
|
||||
// CanRequestStop returns whether the machine is in a state where the guest can be asked to stop.
|
||||
func (v *VirtualMachine) CanRequestStop() bool {
|
||||
return (bool)(C.vmCanRequestStop(v.Ptr(), v.dispatchQueue))
|
||||
}
|
||||
|
||||
//export startHandler
|
||||
func startHandler(errPtr unsafe.Pointer, cid *C.char) {
|
||||
id := (*char)(cid).String()
|
||||
// If returns nil in the cgo world, the nil will not be treated as nil in the Go world
|
||||
// so this is temporarily handled (Go 1.17)
|
||||
if err := newNSError(errPtr); err != nil {
|
||||
handlers[id].start(err)
|
||||
} else {
|
||||
handlers[id].start(nil)
|
||||
}
|
||||
}
|
||||
|
||||
//export pauseHandler
|
||||
func pauseHandler(errPtr unsafe.Pointer, cid *C.char) {
|
||||
id := (*char)(cid).String()
|
||||
// see: startHandler
|
||||
if err := newNSError(errPtr); err != nil {
|
||||
handlers[id].pause(err)
|
||||
} else {
|
||||
handlers[id].pause(nil)
|
||||
}
|
||||
}
|
||||
|
||||
//export resumeHandler
|
||||
func resumeHandler(errPtr unsafe.Pointer, cid *C.char) {
|
||||
id := (*char)(cid).String()
|
||||
// see: startHandler
|
||||
if err := newNSError(errPtr); err != nil {
|
||||
handlers[id].resume(err)
|
||||
} else {
|
||||
handlers[id].resume(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func makeHandler(fn func(error)) (func(error), chan struct{}) {
|
||||
done := make(chan struct{})
|
||||
return func(err error) {
|
||||
fn(err)
|
||||
close(done)
|
||||
}, done
|
||||
}
|
||||
|
||||
// Start a virtual machine that is in either Stopped or Error state.
|
||||
//
|
||||
// - fn parameter called after the virtual machine has been successfully started or on error.
|
||||
// The error parameter passed to the block is null if the start was successful.
|
||||
func (v *VirtualMachine) Start(fn func(error)) {
|
||||
h, done := makeHandler(fn)
|
||||
handlers[v.id].start = h
|
||||
cid := charWithGoString(v.id)
|
||||
defer cid.Free()
|
||||
C.startWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString())
|
||||
<-done
|
||||
}
|
||||
|
||||
// Pause a virtual machine that is in Running state.
|
||||
//
|
||||
// - fn parameter called after the virtual machine has been successfully paused or on error.
|
||||
// The error parameter passed to the block is null if the start was successful.
|
||||
func (v *VirtualMachine) Pause(fn func(error)) {
|
||||
h, done := makeHandler(fn)
|
||||
handlers[v.id].pause = h
|
||||
cid := charWithGoString(v.id)
|
||||
defer cid.Free()
|
||||
C.pauseWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString())
|
||||
<-done
|
||||
}
|
||||
|
||||
// Resume a virtual machine that is in the Paused state.
|
||||
//
|
||||
// - fn parameter called after the virtual machine has been successfully resumed or on error.
|
||||
// The error parameter passed to the block is null if the resumption was successful.
|
||||
func (v *VirtualMachine) Resume(fn func(error)) {
|
||||
h, done := makeHandler(fn)
|
||||
handlers[v.id].resume = h
|
||||
cid := charWithGoString(v.id)
|
||||
defer cid.Free()
|
||||
C.resumeWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString())
|
||||
<-done
|
||||
}
|
||||
|
||||
// RequestStop requests that the guest turns itself off.
|
||||
//
|
||||
// If returned error is not nil, assigned with the error if the request failed.
|
||||
// Returens true if the request was made successfully.
|
||||
func (v *VirtualMachine) RequestStop() (bool, error) {
|
||||
nserr := newNSErrorAsNil()
|
||||
nserrPtr := nserr.Ptr()
|
||||
ret := (bool)(C.requestStopVirtualMachine(v.Ptr(), v.dispatchQueue, &nserrPtr))
|
||||
if err := newNSError(nserrPtr); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
74
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.h
generated
vendored
Normal file
74
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.h
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// virtualization.h
|
||||
//
|
||||
// Created by codehex.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Virtualization/Virtualization.h>
|
||||
|
||||
/* exported from cgo */
|
||||
void startHandler(void *err, char *id);
|
||||
void pauseHandler(void *err, char *id);
|
||||
void resumeHandler(void *err, char *id);
|
||||
void changeStateOnObserver(int state, char *id);
|
||||
|
||||
@interface Observer : NSObject
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
|
||||
@end
|
||||
|
||||
/* BootLoader */
|
||||
void *newVZLinuxBootLoader(const char *kernelPath);
|
||||
void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine);
|
||||
void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramdiskPath);
|
||||
|
||||
/* VirtualMachineConfiguration */
|
||||
bool validateVZVirtualMachineConfiguration(void *config, void **error);
|
||||
void *newVZVirtualMachineConfiguration(void *bootLoader,
|
||||
unsigned int CPUCount,
|
||||
unsigned long long memorySize);
|
||||
void setEntropyDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *entropyDevices);
|
||||
void setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *memoryBalloonDevices);
|
||||
void setNetworkDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *networkDevices);
|
||||
void setSerialPortsVZVirtualMachineConfiguration(void *config,
|
||||
void *serialPorts);
|
||||
void setSocketDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *socketDevices);
|
||||
void setStorageDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *storageDevices);
|
||||
|
||||
/* Configurations */
|
||||
void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor);
|
||||
void *newVZFileSerialPortAttachment(const char *filePath, bool shouldAppend, void **error);
|
||||
void *newVZVirtioConsoleDeviceSerialPortConfiguration(void *attachment);
|
||||
void *newVZBridgedNetworkDeviceAttachment(void *networkInterface);
|
||||
void *newVZNATNetworkDeviceAttachment(void);
|
||||
void *newVZFileHandleNetworkDeviceAttachment(int fileDescriptor);
|
||||
void *newVZVirtioNetworkDeviceConfiguration(void *attachment);
|
||||
void setNetworkDevicesVZMACAddress(void *config, void *macAddress);
|
||||
void *newVZVirtioEntropyDeviceConfiguration(void);
|
||||
void *newVZVirtioBlockDeviceConfiguration(void *attachment);
|
||||
void *newVZDiskImageStorageDeviceAttachment(const char *diskPath, bool readOnly, void **error);
|
||||
void *newVZVirtioTraditionalMemoryBalloonDeviceConfiguration();
|
||||
void *newVZVirtioSocketDeviceConfiguration();
|
||||
void *newVZMACAddress(const char *macAddress);
|
||||
void *newRandomLocallyAdministeredVZMACAddress();
|
||||
const char *getVZMACAddressString(void *macAddress);
|
||||
|
||||
/* VirtualMachine */
|
||||
void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, const char *vmid);
|
||||
bool requestStopVirtualMachine(void *machine, void *queue, void **error);
|
||||
void startWithCompletionHandler(void *machine, void *queue, const char *vmid);
|
||||
void pauseWithCompletionHandler(void *machine, void *queue, const char *vmid);
|
||||
void resumeWithCompletionHandler(void *machine, void *queue, const char *vmid);
|
||||
bool vmCanStart(void *machine, void *queue);
|
||||
bool vmCanPause(void *machine, void *queue);
|
||||
bool vmCanResume(void *machine, void *queue);
|
||||
bool vmCanRequestStop(void *machine, void *queue);
|
||||
|
||||
void *makeDispatchQueue(const char *label);
|
570
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.m
generated
vendored
Normal file
570
src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.m
generated
vendored
Normal file
@@ -0,0 +1,570 @@
|
||||
//
|
||||
// virtualization.m
|
||||
//
|
||||
// Created by codehex.
|
||||
//
|
||||
|
||||
#import "virtualization.h"
|
||||
|
||||
char *copyCString(NSString *nss)
|
||||
{
|
||||
const char *cc = [nss UTF8String];
|
||||
char *c = calloc([nss length]+1, 1);
|
||||
strncpy(c, cc, [nss length]);
|
||||
return c;
|
||||
}
|
||||
|
||||
@implementation Observer
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
|
||||
{
|
||||
|
||||
@autoreleasepool {
|
||||
if ([keyPath isEqualToString:@"state"]) {
|
||||
int newState = (int)[change[NSKeyValueChangeNewKey] integerValue];
|
||||
char *vmid = copyCString((NSString *)context);
|
||||
changeStateOnObserver(newState, vmid);
|
||||
free(vmid);
|
||||
} else {
|
||||
// bool canVal = (bool)[change[NSKeyValueChangeNewKey] boolValue];
|
||||
// char *vmid = copyCString((NSString *)context);
|
||||
// char *key = copyCString(keyPath);
|
||||
// changeCanPropertyOnObserver(canVal, vmid, key);
|
||||
// free(vmid);
|
||||
// free(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract Create a VZLinuxBootLoader with the Linux kernel passed as URL.
|
||||
@param kernelPath Path of Linux kernel on the local file system.
|
||||
*/
|
||||
void *newVZLinuxBootLoader(const char *kernelPath)
|
||||
{
|
||||
VZLinuxBootLoader *ret;
|
||||
@autoreleasepool {
|
||||
NSString *kernelPathNSString = [NSString stringWithUTF8String:kernelPath];
|
||||
NSURL *kernelURL = [NSURL fileURLWithPath:kernelPathNSString];
|
||||
ret = [[VZLinuxBootLoader alloc] initWithKernelURL:kernelURL];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Set the command-line parameters.
|
||||
@param bootLoader VZLinuxBootLoader
|
||||
@param commandLine The command-line parameters passed to the kernel on boot.
|
||||
@link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
|
||||
*/
|
||||
void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine)
|
||||
{
|
||||
VZLinuxBootLoader *bootLoader = (VZLinuxBootLoader *)bootLoaderPtr;
|
||||
@autoreleasepool {
|
||||
NSString *commandLineNSString = [NSString stringWithUTF8String:commandLine];
|
||||
[bootLoader setCommandLine:commandLineNSString];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Set the optional initial RAM disk.
|
||||
@param bootLoader VZLinuxBootLoader
|
||||
@param ramdiskPath The RAM disk is mapped into memory before booting the kernel.
|
||||
@link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
|
||||
*/
|
||||
void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramdiskPath)
|
||||
{
|
||||
VZLinuxBootLoader *bootLoader = (VZLinuxBootLoader *)bootLoaderPtr;
|
||||
@autoreleasepool {
|
||||
NSString *ramdiskPathNSString = [NSString stringWithUTF8String:ramdiskPath];
|
||||
NSURL *ramdiskURL = [NSURL fileURLWithPath:ramdiskPathNSString];
|
||||
[bootLoader setInitialRamdiskURL:ramdiskURL];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@abstract Validate the configuration.
|
||||
@param config Virtual machine configuration.
|
||||
@param error If not nil, assigned with the validation error if the validation failed.
|
||||
@return true if the configuration is valid.
|
||||
*/
|
||||
bool validateVZVirtualMachineConfiguration(void *config, void **error)
|
||||
{
|
||||
return (bool)[(VZVirtualMachineConfiguration *)config
|
||||
validateWithError:(NSError * _Nullable * _Nullable)error];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Virtual machine configuration.
|
||||
@param bootLoader Boot loader used when the virtual machine starts.
|
||||
|
||||
@param CPUCount Number of CPUs.
|
||||
@discussion
|
||||
The number of CPUs must be a value between VZVirtualMachineConfiguration.minimumAllowedCPUCount
|
||||
and VZVirtualMachineConfiguration.maximumAllowedCPUCount.
|
||||
|
||||
@see VZVirtualMachineConfiguration.minimumAllowedCPUCount
|
||||
@see VZVirtualMachineConfiguration.maximumAllowedCPUCount
|
||||
|
||||
@param memorySize Virtual machine memory size in bytes.
|
||||
@discussion
|
||||
The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between VZVirtualMachineConfiguration.minimumAllowedMemorySize
|
||||
and VZVirtualMachineConfiguration.maximumAllowedMemorySize.
|
||||
|
||||
The memorySize represents the total physical memory seen by a guest OS running in the virtual machine.
|
||||
Not all memory is allocated on start, the virtual machine allocates memory on demand.
|
||||
@see VZVirtualMachineConfiguration.minimumAllowedMemorySize
|
||||
@see VZVirtualMachineConfiguration.maximumAllowedMemorySize
|
||||
*/
|
||||
void *newVZVirtualMachineConfiguration(void *bootLoaderPtr,
|
||||
unsigned int CPUCount,
|
||||
unsigned long long memorySize)
|
||||
{
|
||||
VZVirtualMachineConfiguration *config = [[VZVirtualMachineConfiguration alloc] init];
|
||||
[config setBootLoader:(VZLinuxBootLoader *)bootLoaderPtr];
|
||||
[config setCPUCount:(NSUInteger)CPUCount];
|
||||
[config setMemorySize:memorySize];
|
||||
return config;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract List of entropy devices. Empty by default.
|
||||
@see VZVirtioEntropyDeviceConfiguration
|
||||
*/
|
||||
void setEntropyDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *entropyDevices)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setEntropyDevices:[(NSMutableArray *)entropyDevices copy]];
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@abstract List of memory balloon devices. Empty by default.
|
||||
@see VZVirtioTraditionalMemoryBalloonDeviceConfiguration
|
||||
*/
|
||||
void setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *memoryBalloonDevices)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setMemoryBalloonDevices:[(NSMutableArray *)memoryBalloonDevices copy]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract List of network adapters. Empty by default.
|
||||
@see VZVirtioNetworkDeviceConfiguration
|
||||
*/
|
||||
void setNetworkDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *networkDevices)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setNetworkDevices:[(NSMutableArray *)networkDevices copy]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract List of serial ports. Empty by default.
|
||||
@see VZVirtioConsoleDeviceSerialPortConfiguration
|
||||
*/
|
||||
void setSerialPortsVZVirtualMachineConfiguration(void *config,
|
||||
void *serialPorts)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setSerialPorts:[(NSMutableArray *)serialPorts copy]];
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@abstract List of socket devices. Empty by default.
|
||||
@see VZVirtioSocketDeviceConfiguration
|
||||
*/
|
||||
void setSocketDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *socketDevices)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setSocketDevices:[(NSMutableArray *)socketDevices copy]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract List of disk devices. Empty by default.
|
||||
@see VZVirtioBlockDeviceConfiguration
|
||||
*/
|
||||
void setStorageDevicesVZVirtualMachineConfiguration(void *config,
|
||||
void *storageDevices)
|
||||
{
|
||||
[(VZVirtualMachineConfiguration *)config setStorageDevices:[(NSMutableArray *)storageDevices copy]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Intialize the VZFileHandleSerialPortAttachment from file descriptors.
|
||||
@param readFileDescriptor File descriptor for reading from the file.
|
||||
@param writeFileDescriptor File descriptor for writing to the file.
|
||||
@discussion
|
||||
Each file descriptor must a valid.
|
||||
*/
|
||||
void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor)
|
||||
{
|
||||
VZFileHandleSerialPortAttachment *ret;
|
||||
@autoreleasepool {
|
||||
NSFileHandle *fileHandleForReading = [[NSFileHandle alloc] initWithFileDescriptor:readFileDescriptor];
|
||||
NSFileHandle *fileHandleForWriting = [[NSFileHandle alloc] initWithFileDescriptor:writeFileDescriptor];
|
||||
ret = [[VZFileHandleSerialPortAttachment alloc]
|
||||
initWithFileHandleForReading:fileHandleForReading
|
||||
fileHandleForWriting:fileHandleForWriting];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Initialize the VZFileSerialPortAttachment from a URL of a file.
|
||||
@param filePath The path of the file for the attachment on the local file system.
|
||||
@param shouldAppend True if the file should be opened in append mode, false otherwise.
|
||||
When a file is opened in append mode, writing to that file will append to the end of it.
|
||||
@param error If not nil, used to report errors if intialization fails.
|
||||
@return A VZFileSerialPortAttachment on success. Nil otherwise and the error parameter is populated if set.
|
||||
*/
|
||||
void *newVZFileSerialPortAttachment(const char *filePath, bool shouldAppend, void **error)
|
||||
{
|
||||
VZFileSerialPortAttachment *ret;
|
||||
@autoreleasepool {
|
||||
NSString *filePathNSString = [NSString stringWithUTF8String:filePath];
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:filePathNSString];
|
||||
ret = [[VZFileSerialPortAttachment alloc]
|
||||
initWithURL:fileURL append:(BOOL)shouldAppend error:(NSError * _Nullable * _Nullable)error];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Virtio Console Serial Port Device configuration
|
||||
@param attachment Base class for a serial port attachment.
|
||||
@discussion
|
||||
The device creates a console which enables communication between the host and the guest through the Virtio interface.
|
||||
|
||||
The device sets up a single port on the Virtio console device.
|
||||
*/
|
||||
void *newVZVirtioConsoleDeviceSerialPortConfiguration(void *attachment)
|
||||
{
|
||||
VZVirtioConsoleDeviceSerialPortConfiguration *config = [[VZVirtioConsoleDeviceSerialPortConfiguration alloc] init];
|
||||
[config setAttachment:(VZSerialPortAttachment *)attachment];
|
||||
return config;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Network device attachment bridging a host physical interface with a virtual network device.
|
||||
@param networkInterface a network interface that bridges a physical interface.
|
||||
@discussion
|
||||
A bridged network allows the virtual machine to use the same physical interface as the host. Both host and virtual machine
|
||||
send and receive packets on the same physical interface but have distinct network layers.
|
||||
|
||||
The bridge network device attachment is used with a VZNetworkDeviceConfiguration to define a virtual network device.
|
||||
|
||||
Using a VZBridgedNetworkDeviceAttachment requires the app to have the "com.apple.vm.networking" entitlement.
|
||||
|
||||
@see VZBridgedNetworkInterface
|
||||
@see VZNetworkDeviceConfiguration
|
||||
@see VZVirtioNetworkDeviceConfiguration
|
||||
*/
|
||||
void *newVZBridgedNetworkDeviceAttachment(void *networkInterface)
|
||||
{
|
||||
return [[VZBridgedNetworkDeviceAttachment alloc] initWithInterface:(VZBridgedNetworkInterface *)networkInterface];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Network device attachment using network address translation (NAT) with outside networks.
|
||||
@discussion
|
||||
Using the NAT attachment type, the host serves as router and performs network address translation for accesses to outside networks.
|
||||
|
||||
@see VZNetworkDeviceConfiguration
|
||||
@see VZVirtioNetworkDeviceConfiguration
|
||||
*/
|
||||
void *newVZNATNetworkDeviceAttachment()
|
||||
{
|
||||
return [[VZNATNetworkDeviceAttachment alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Network device attachment sending raw network packets over a file handle.
|
||||
@discussion
|
||||
The file handle attachment transmits the raw packets/frames between the virtual network interface and a file handle.
|
||||
The data transmitted through this attachment is at the level of the data link layer.
|
||||
|
||||
The file handle must hold a connected datagram socket.
|
||||
|
||||
@see VZNetworkDeviceConfiguration
|
||||
@see VZVirtioNetworkDeviceConfiguration
|
||||
*/
|
||||
void *newVZFileHandleNetworkDeviceAttachment(int fileDescriptor)
|
||||
{
|
||||
VZFileHandleNetworkDeviceAttachment *ret;
|
||||
@autoreleasepool {
|
||||
NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor];
|
||||
ret = [[VZFileHandleNetworkDeviceAttachment alloc] initWithFileHandle:fileHandle];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Configuration of a paravirtualized network device of type Virtio Network Device.
|
||||
@discussion
|
||||
The communication channel used on the host is defined through the attachment. It is set with the VZNetworkDeviceConfiguration.attachment property.
|
||||
|
||||
The configuration is only valid with valid MACAddress and attachment.
|
||||
|
||||
@see VZVirtualMachineConfiguration.networkDevices
|
||||
|
||||
@param attachment Base class for a network device attachment.
|
||||
@discussion
|
||||
A network device attachment defines how a virtual network device interfaces with the host system.
|
||||
|
||||
VZNetworkDeviceAttachment should not be instantiated directly. One of its subclasses should be used instead.
|
||||
|
||||
Common attachment types include:
|
||||
- VZNATNetworkDeviceAttachment
|
||||
- VZFileHandleNetworkDeviceAttachment
|
||||
|
||||
@see VZBridgedNetworkDeviceAttachment
|
||||
@see VZFileHandleNetworkDeviceAttachment
|
||||
@see VZNATNetworkDeviceAttachment
|
||||
*/
|
||||
void *newVZVirtioNetworkDeviceConfiguration(void *attachment)
|
||||
{
|
||||
VZVirtioNetworkDeviceConfiguration *config = [[VZVirtioNetworkDeviceConfiguration alloc] init];
|
||||
[config setAttachment:(VZNetworkDeviceAttachment *)attachment];
|
||||
return config;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a new Virtio Entropy Device confiuration
|
||||
@discussion The device exposes a source of entropy for the guest's random number generator.
|
||||
*/
|
||||
void *newVZVirtioEntropyDeviceConfiguration()
|
||||
{
|
||||
return [[VZVirtioEntropyDeviceConfiguration alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Initialize a VZVirtioBlockDeviceConfiguration with a device attachment.
|
||||
@param attachment The storage device attachment. This defines how the virtualized device operates on the host side.
|
||||
@see VZDiskImageStorageDeviceAttachment
|
||||
*/
|
||||
void *newVZVirtioBlockDeviceConfiguration(void *attachment)
|
||||
{
|
||||
return [[VZVirtioBlockDeviceConfiguration alloc] initWithAttachment:(VZStorageDeviceAttachment *)attachment];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Initialize the attachment from a local file url.
|
||||
@param diskPath Local file path to the disk image in RAW format.
|
||||
@param readOnly If YES, the device attachment is read-only, otherwise the device can write data to the disk image.
|
||||
@param error If not nil, assigned with the error if the initialization failed.
|
||||
@return A VZDiskImageStorageDeviceAttachment on success. Nil otherwise and the error parameter is populated if set.
|
||||
*/
|
||||
void *newVZDiskImageStorageDeviceAttachment(const char *diskPath, bool readOnly, void **error)
|
||||
{
|
||||
VZDiskImageStorageDeviceAttachment *ret;
|
||||
@autoreleasepool {
|
||||
NSString *diskPathNSString = [NSString stringWithUTF8String:diskPath];
|
||||
NSURL *diskURL = [NSURL fileURLWithPath:diskPathNSString];
|
||||
ret = [[VZDiskImageStorageDeviceAttachment alloc]
|
||||
initWithURL:diskURL
|
||||
readOnly:(BOOL)readOnly
|
||||
error:(NSError * _Nullable * _Nullable)error];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@abstract Create a configuration of the Virtio traditional memory balloon device.
|
||||
@discussion
|
||||
This configuration creates a Virtio traditional memory balloon device which allows for managing guest memory.
|
||||
Only one Virtio traditional memory balloon device can be used per virtual machine.
|
||||
@see VZVirtioTraditionalMemoryBalloonDevice
|
||||
*/
|
||||
void *newVZVirtioTraditionalMemoryBalloonDeviceConfiguration()
|
||||
{
|
||||
return [[VZVirtioTraditionalMemoryBalloonDeviceConfiguration alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a configuration of the Virtio socket device.
|
||||
@discussion
|
||||
This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface.
|
||||
|
||||
Only one Virtio socket device can be used per virtual machine.
|
||||
@see VZVirtioSocketDevice
|
||||
*/
|
||||
void *newVZVirtioSocketDeviceConfiguration()
|
||||
{
|
||||
return [[VZVirtioSocketDeviceConfiguration alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Initialize the virtual machine.
|
||||
@param config The configuration of the virtual machine.
|
||||
The configuration must be valid. Validation can be performed at runtime with [VZVirtualMachineConfiguration validateWithError:].
|
||||
The configuration is copied by the initializer.
|
||||
@param queue The serial queue on which the virtual machine operates.
|
||||
Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue.
|
||||
If the queue is not serial, the behavior is undefined.
|
||||
*/
|
||||
void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, const char *vmid)
|
||||
{
|
||||
VZVirtualMachine *vm = [[VZVirtualMachine alloc]
|
||||
initWithConfiguration:(VZVirtualMachineConfiguration *)config
|
||||
queue:(dispatch_queue_t)queue];
|
||||
@autoreleasepool {
|
||||
Observer *o = [[Observer alloc] init];
|
||||
NSString *str = [NSString stringWithUTF8String:vmid];
|
||||
[vm addObserver:o forKeyPath:@"state"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:[str copy]];
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Initialize the VZMACAddress from a string representation of a MAC address.
|
||||
@param string
|
||||
The string should be formatted representing the 6 bytes in hexadecimal separated by a colon character.
|
||||
e.g. "01:23:45:ab:cd:ef"
|
||||
|
||||
The alphabetical characters can appear lowercase or uppercase.
|
||||
@return A VZMACAddress or nil if the string is not formatted correctly.
|
||||
*/
|
||||
void *newVZMACAddress(const char *macAddress)
|
||||
{
|
||||
VZMACAddress *ret;
|
||||
@autoreleasepool {
|
||||
NSString *str = [NSString stringWithUTF8String:macAddress];
|
||||
ret = [[VZMACAddress alloc] initWithString:str];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Create a valid, random, unicast, locally administered address.
|
||||
@discussion The generated address is not guaranteed to be unique.
|
||||
*/
|
||||
void *newRandomLocallyAdministeredVZMACAddress()
|
||||
{
|
||||
return [VZMACAddress randomLocallyAdministeredAddress];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Sets the media access control address of the device.
|
||||
*/
|
||||
void setNetworkDevicesVZMACAddress(void *config, void *macAddress)
|
||||
{
|
||||
[(VZNetworkDeviceConfiguration *)config setMACAddress:[(VZMACAddress *)macAddress copy]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract The address represented as a string.
|
||||
@discussion
|
||||
The 6 bytes are represented in hexadecimal form, separated by a colon character.
|
||||
Alphabetical characters are lowercase.
|
||||
|
||||
The address is compatible with the parameter of -[VZMACAddress initWithString:].
|
||||
*/
|
||||
const char *getVZMACAddressString(void *macAddress)
|
||||
{
|
||||
return [[(VZMACAddress *)macAddress string] UTF8String];
|
||||
}
|
||||
|
||||
/*!
|
||||
@abstract Request that the guest turns itself off.
|
||||
@param error If not nil, assigned with the error if the request failed.
|
||||
@return YES if the request was made successfully.
|
||||
*/
|
||||
bool requestStopVirtualMachine(void *machine, void *queue, void **error)
|
||||
{
|
||||
__block BOOL ret;
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
ret = [(VZVirtualMachine *)machine requestStopWithError:(NSError * _Nullable *_Nullable)error];
|
||||
});
|
||||
return (bool)ret;
|
||||
}
|
||||
|
||||
void *makeDispatchQueue(const char *label)
|
||||
{
|
||||
//dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
|
||||
dispatch_queue_t queue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL);
|
||||
//dispatch_retain(queue);
|
||||
return queue;
|
||||
}
|
||||
|
||||
typedef void (^handler_t)(NSError *);
|
||||
|
||||
handler_t generateHandler(const char *vmid, void handler(void *, char *))
|
||||
{
|
||||
handler_t ret;
|
||||
@autoreleasepool {
|
||||
NSString *str = [NSString stringWithUTF8String:vmid];
|
||||
ret = Block_copy(^(NSError *err){
|
||||
handler(err, copyCString(str));
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void startWithCompletionHandler(void *machine, void *queue, const char *vmid)
|
||||
{
|
||||
handler_t handler = generateHandler(vmid, startHandler);
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
[(VZVirtualMachine *)machine startWithCompletionHandler:handler];
|
||||
});
|
||||
Block_release(handler);
|
||||
}
|
||||
|
||||
void pauseWithCompletionHandler(void *machine, void *queue, const char *vmid)
|
||||
{
|
||||
handler_t handler = generateHandler(vmid, pauseHandler);
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
[(VZVirtualMachine *)machine pauseWithCompletionHandler:handler];
|
||||
});
|
||||
Block_release(handler);
|
||||
}
|
||||
|
||||
void resumeWithCompletionHandler(void *machine, void *queue, const char *vmid)
|
||||
{
|
||||
handler_t handler = generateHandler(vmid, pauseHandler);
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
[(VZVirtualMachine *)machine resumeWithCompletionHandler:handler];
|
||||
});
|
||||
Block_release(handler);
|
||||
}
|
||||
|
||||
// TODO(codehex): use KVO
|
||||
bool vmCanStart(void *machine, void *queue)
|
||||
{
|
||||
__block BOOL result;
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
result = ((VZVirtualMachine *)machine).canStart;
|
||||
});
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
bool vmCanPause(void *machine, void *queue)
|
||||
{
|
||||
__block BOOL result;
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
result = ((VZVirtualMachine *)machine).canPause;
|
||||
});
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
bool vmCanResume(void *machine, void *queue)
|
||||
{
|
||||
__block BOOL result;
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
result = ((VZVirtualMachine *)machine).canResume;
|
||||
});
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
bool vmCanRequestStop(void *machine, void *queue)
|
||||
{
|
||||
__block BOOL result;
|
||||
dispatch_sync((dispatch_queue_t)queue, ^{
|
||||
result = ((VZVirtualMachine *)machine).canRequestStop;
|
||||
});
|
||||
return (bool)result;
|
||||
}
|
||||
// --- TODO end
|
10
src/cmd/linuxkit/vendor/github.com/pkg/term/LICENSE
generated
vendored
Normal file
10
src/cmd/linuxkit/vendor/github.com/pkg/term/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
Copyright (c) 2014, David Cheney
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/doc.go
generated
vendored
Normal file
4
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/doc.go
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
// Package termios implements the low level termios(3) terminal line discipline facilities.
|
||||
//
|
||||
// For a higher level interface please use the github.com/pkg/term package.
|
||||
package termios
|
16
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl.go
generated
vendored
Normal file
16
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// +build !windows,!solaris
|
||||
|
||||
package termios
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ioctl(fd, request, argp uintptr) error {
|
||||
if _, _, e := unix.Syscall6(syscall.SYS_IOCTL, fd, request, argp, 0, 0, 0); e != 0 {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
10
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl_darwin.go
generated
vendored
Normal file
10
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
package termios
|
||||
|
||||
const (
|
||||
_IOC_PARAM_SHIFT = 13
|
||||
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
|
||||
)
|
||||
|
||||
func _IOC_PARM_LEN(ioctl uintptr) uintptr {
|
||||
return (ioctl >> 16) & _IOC_PARAM_MASK
|
||||
}
|
7
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl_solaris.go
generated
vendored
Normal file
7
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/ioctl_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package termios
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func ioctl(fd, request, argp uintptr) error {
|
||||
return unix.IoctlSetInt(int(fd), uint(request), int(argp))
|
||||
}
|
48
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty.go
generated
vendored
Normal file
48
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// +build !windows
|
||||
|
||||
package termios
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func open_device(path string) (uintptr, error) {
|
||||
fd, err := unix.Open(path, unix.O_NOCTTY|unix.O_RDWR|unix.O_CLOEXEC, 0666)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("unable to open %q: %v", path, err)
|
||||
}
|
||||
return uintptr(fd), nil
|
||||
}
|
||||
|
||||
// Pty returns a UNIX 98 pseudoterminal device.
|
||||
// Pty returns a pair of fds representing the master and slave pair.
|
||||
func Pty() (*os.File, *os.File, error) {
|
||||
ptm, err := open_pty_master()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sname, err := Ptsname(ptm)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = grantpt(ptm)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = unlockpt(ptm)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pts, err := open_device(sname)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return os.NewFile(uintptr(ptm), "ptm"), os.NewFile(uintptr(pts), sname), nil
|
||||
}
|
37
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_bsd.go
generated
vendored
Normal file
37
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// +build dragonfly openbsd
|
||||
|
||||
package termios
|
||||
|
||||
// #include<stdlib.h>
|
||||
import "C"
|
||||
|
||||
import "syscall"
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
rc := C.posix_openpt(syscall.O_NOCTTY | syscall.O_RDWR)
|
||||
if rc < 0 {
|
||||
return 0, syscall.Errno(rc)
|
||||
}
|
||||
return uintptr(rc), nil
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
slavename := C.GoString(C.ptsname(C.int(fd)))
|
||||
return slavename, nil
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
rc := C.grantpt(C.int(fd))
|
||||
if rc == 0 {
|
||||
return nil
|
||||
}
|
||||
return syscall.Errno(rc)
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
rc := C.unlockpt(C.int(fd))
|
||||
if rc == 0 {
|
||||
return nil
|
||||
}
|
||||
return syscall.Errno(rc)
|
||||
}
|
36
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_darwin.go
generated
vendored
Normal file
36
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package termios
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
return open_device("/dev/ptmx")
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
n := make([]byte, _IOC_PARM_LEN(unix.TIOCPTYGNAME))
|
||||
|
||||
err := ioctl(fd, unix.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, c := range n {
|
||||
if c == 0 {
|
||||
return string(n[:i]), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCPTYGRANT, 0)
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCPTYUNLK, 0)
|
||||
}
|
38
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_freebsd.go
generated
vendored
Normal file
38
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package termios
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func posix_openpt(oflag int) (fd uintptr, err error) {
|
||||
// Copied from debian-golang-pty/pty_freebsd.go.
|
||||
r0, _, e1 := unix.Syscall(unix.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)
|
||||
fd = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
return posix_openpt(unix.O_NOCTTY | unix.O_RDWR | unix.O_CLOEXEC)
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
var n uintptr
|
||||
err := ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("/dev/pts/%d", n), nil
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
var n uintptr
|
||||
return ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
return nil
|
||||
}
|
31
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_linux.go
generated
vendored
Normal file
31
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_linux.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package termios
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
return open_device("/dev/ptmx")
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
var n uintptr
|
||||
err := ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("/dev/pts/%d", n), nil
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
var n uintptr
|
||||
return ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
var n uintptr
|
||||
return ioctl(fd, unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&n)))
|
||||
}
|
31
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_netbsd.go
generated
vendored
Normal file
31
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package termios
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
fd, err := unix.Open("/dev/ptmx", unix.O_NOCTTY|unix.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uintptr(fd), nil
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
ptm, err := unix.IoctlGetPtmget(int(fd), unix.TIOCPTSNAME)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCGRANTPT, 0)
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
return nil
|
||||
}
|
33
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_solaris.go
generated
vendored
Normal file
33
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/pty_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package termios
|
||||
|
||||
// #include<stdlib.h>
|
||||
import "C"
|
||||
|
||||
import "syscall"
|
||||
|
||||
func open_pty_master() (uintptr, error) {
|
||||
return open_device("/dev/ptmx")
|
||||
}
|
||||
|
||||
func Ptsname(fd uintptr) (string, error) {
|
||||
slavename := C.GoString(C.ptsname(C.int(fd)))
|
||||
return slavename, nil
|
||||
}
|
||||
|
||||
func grantpt(fd uintptr) error {
|
||||
rc := C.grantpt(C.int(fd))
|
||||
if rc == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return syscall.Errno(rc)
|
||||
}
|
||||
}
|
||||
|
||||
func unlockpt(fd uintptr) error {
|
||||
rc := C.unlockpt(C.int(fd))
|
||||
if rc == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return syscall.Errno(rc)
|
||||
}
|
||||
}
|
45
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios.go
generated
vendored
Normal file
45
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// +build !windows
|
||||
|
||||
package termios
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Tiocmget returns the state of the MODEM bits.
|
||||
func Tiocmget(fd uintptr) (int, error) {
|
||||
return unix.IoctlGetInt(int(fd), unix.TIOCMGET)
|
||||
}
|
||||
|
||||
// Tiocmset sets the state of the MODEM bits.
|
||||
func Tiocmset(fd uintptr, status int) error {
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCMSET, status)
|
||||
}
|
||||
|
||||
// Tiocmbis sets the indicated modem bits.
|
||||
func Tiocmbis(fd uintptr, status int) error {
|
||||
return unix.IoctlSetPointerInt(int(fd), unix.TIOCMBIS, status)
|
||||
}
|
||||
|
||||
// Tiocmbic clears the indicated modem bits.
|
||||
func Tiocmbic(fd uintptr, status int) error {
|
||||
return unix.IoctlSetPointerInt(int(fd), unix.TIOCMBIC, status)
|
||||
}
|
||||
|
||||
// Cfmakecbreak modifies attr for cbreak mode.
|
||||
func Cfmakecbreak(attr *unix.Termios) {
|
||||
attr.Lflag &^= unix.ECHO | unix.ICANON
|
||||
attr.Cc[unix.VMIN] = 1
|
||||
attr.Cc[unix.VTIME] = 0
|
||||
}
|
||||
|
||||
// Cfmakeraw modifies attr for raw mode.
|
||||
func Cfmakeraw(attr *unix.Termios) {
|
||||
attr.Iflag &^= unix.BRKINT | unix.ICRNL | unix.INPCK | unix.ISTRIP | unix.IXON
|
||||
attr.Oflag &^= unix.OPOST
|
||||
attr.Cflag &^= unix.CSIZE | unix.PARENB
|
||||
attr.Cflag |= unix.CS8
|
||||
attr.Lflag &^= unix.ECHO | unix.ICANON | unix.IEXTEN | unix.ISIG
|
||||
attr.Cc[unix.VMIN] = 1
|
||||
attr.Cc[unix.VTIME] = 0
|
||||
}
|
89
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_bsd.go
generated
vendored
Normal file
89
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
|
||||
package termios
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
FREAD = 0x0001
|
||||
FWRITE = 0x0002
|
||||
|
||||
IXON = 0x00000200
|
||||
IXOFF = 0x00000400
|
||||
IXANY = 0x00000800
|
||||
CCTS_OFLOW = 0x00010000
|
||||
CRTS_IFLOW = 0x00020000
|
||||
CRTSCTS = CCTS_OFLOW | CRTS_IFLOW
|
||||
)
|
||||
|
||||
// Tcgetattr gets the current serial port settings.
|
||||
func Tcgetattr(fd uintptr, argp *unix.Termios) error {
|
||||
return unix.IoctlSetTermios(int(fd), unix.TIOCGETA, argp)
|
||||
}
|
||||
|
||||
// Tcsetattr sets the current serial port settings.
|
||||
func Tcsetattr(fd, opt uintptr, argp *unix.Termios) error {
|
||||
switch opt {
|
||||
case TCSANOW:
|
||||
opt = unix.TIOCSETA
|
||||
case TCSADRAIN:
|
||||
opt = unix.TIOCSETAW
|
||||
case TCSAFLUSH:
|
||||
opt = unix.TIOCSETAF
|
||||
default:
|
||||
return unix.EINVAL
|
||||
}
|
||||
return unix.IoctlSetTermios(int(fd), uint(opt), argp)
|
||||
}
|
||||
|
||||
// Tcsendbreak function transmits a continuous stream of zero-valued bits for
|
||||
// four-tenths of a second to the terminal referenced by fildes. The duration
|
||||
// parameter is ignored in this implementation.
|
||||
func Tcsendbreak(fd, duration uintptr) error {
|
||||
if err := unix.IoctlSetInt(int(fd), unix.TIOCSBRK, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(4 / 10 * time.Second)
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCCBRK, 0)
|
||||
}
|
||||
|
||||
// Tcdrain waits until all output written to the terminal referenced by fd has been transmitted to the terminal.
|
||||
func Tcdrain(fd uintptr) error {
|
||||
return unix.IoctlSetInt(int(fd), unix.TIOCDRAIN, 0)
|
||||
}
|
||||
|
||||
// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of which.
|
||||
func Tcflush(fd, which uintptr) error {
|
||||
var com int
|
||||
switch which {
|
||||
case unix.TCIFLUSH:
|
||||
com = FREAD
|
||||
case unix.TCOFLUSH:
|
||||
com = FWRITE
|
||||
case unix.TCIOFLUSH:
|
||||
com = FREAD | FWRITE
|
||||
default:
|
||||
return unix.EINVAL
|
||||
}
|
||||
return unix.IoctlSetPointerInt(int(fd), unix.TIOCFLUSH, com)
|
||||
}
|
||||
|
||||
// Cfgetispeed returns the input baud rate stored in the termios structure.
|
||||
func Cfgetispeed(attr *unix.Termios) uint32 { return uint32(attr.Ispeed) }
|
||||
|
||||
// Cfgetospeed returns the output baud rate stored in the termios structure.
|
||||
func Cfgetospeed(attr *unix.Termios) uint32 { return uint32(attr.Ospeed) }
|
||||
|
||||
// Tiocinq returns the number of bytes in the input buffer.
|
||||
func Tiocinq(fd uintptr) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Tiocoutq return the number of bytes in the output buffer.
|
||||
func Tiocoutq(fd uintptr) (int, error) {
|
||||
return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ)
|
||||
}
|
13
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_const.go
generated
vendored
Normal file
13
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_const.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build !windows,!solaris
|
||||
|
||||
package termios
|
||||
|
||||
const (
|
||||
TCIFLUSH = 0
|
||||
TCOFLUSH = 1
|
||||
TCIOFLUSH = 2
|
||||
|
||||
TCSANOW = 0
|
||||
TCSADRAIN = 1
|
||||
TCSAFLUSH = 2
|
||||
)
|
14
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_const_solaris.go
generated
vendored
Normal file
14
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_const_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
package termios
|
||||
|
||||
// #include<termios.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
TCIFLUSH = C.TCIFLUSH
|
||||
TCOFLUSH = C.TCOFLUSH
|
||||
TCIOFLUSH = C.TCIOFLUSH
|
||||
|
||||
TCSANOW = C.TCSANOW
|
||||
TCSADRAIN = C.TCSADRAIN
|
||||
TCSAFLUSH = C.TCSAFLUSH
|
||||
)
|
80
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_linux.go
generated
vendored
Normal file
80
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_linux.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
package termios
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
TCSETS = 0x5402
|
||||
TCSETSW = 0x5403
|
||||
TCSETSF = 0x5404
|
||||
TCFLSH = 0x540B
|
||||
TCSBRK = 0x5409
|
||||
TCSBRKP = 0x5425
|
||||
|
||||
IXON = 0x00000400
|
||||
IXANY = 0x00000800
|
||||
IXOFF = 0x00001000
|
||||
CRTSCTS = 0x80000000
|
||||
)
|
||||
|
||||
// Tcgetattr gets the current serial port settings.
|
||||
func Tcgetattr(fd uintptr, argp *unix.Termios) error {
|
||||
return unix.IoctlSetTermios(int(fd), unix.TCGETS, argp)
|
||||
}
|
||||
|
||||
// Tcsetattr sets the current serial port settings.
|
||||
func Tcsetattr(fd, action uintptr, argp *unix.Termios) error {
|
||||
var request uintptr
|
||||
switch action {
|
||||
case TCSANOW:
|
||||
request = TCSETS
|
||||
case TCSADRAIN:
|
||||
request = TCSETSW
|
||||
case TCSAFLUSH:
|
||||
request = TCSETSF
|
||||
default:
|
||||
return unix.EINVAL
|
||||
}
|
||||
return unix.IoctlSetTermios(int(fd), uint(request), argp)
|
||||
}
|
||||
|
||||
// Tcsendbreak transmits a continuous stream of zero-valued bits for a specific
|
||||
// duration, if the terminal is using asynchronous serial data transmission. If
|
||||
// duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds.
|
||||
// If duration is not zero, it sends zero-valued bits for some
|
||||
// implementation-defined length of time.
|
||||
func Tcsendbreak(fd, duration uintptr) error {
|
||||
return ioctl(fd, TCSBRKP, duration)
|
||||
}
|
||||
|
||||
// Tcdrain waits until all output written to the object referred to by fd has been transmitted.
|
||||
func Tcdrain(fd uintptr) error {
|
||||
// simulate drain with TCSADRAIN
|
||||
var attr unix.Termios
|
||||
if err := Tcgetattr(fd, &attr); err != nil {
|
||||
return err
|
||||
}
|
||||
return Tcsetattr(fd, TCSADRAIN, &attr)
|
||||
}
|
||||
|
||||
// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector.
|
||||
func Tcflush(fd, selector uintptr) error {
|
||||
return ioctl(fd, TCFLSH, selector)
|
||||
}
|
||||
|
||||
// Tiocinq returns the number of bytes in the input buffer.
|
||||
func Tiocinq(fd uintptr) (int, error) {
|
||||
return unix.IoctlGetInt(int(fd), unix.TIOCINQ)
|
||||
}
|
||||
|
||||
// Tiocoutq return the number of bytes in the output buffer.
|
||||
func Tiocoutq(fd uintptr) (int, error) {
|
||||
return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ)
|
||||
}
|
||||
|
||||
// Cfgetispeed returns the input baud rate stored in the termios structure.
|
||||
func Cfgetispeed(attr *unix.Termios) uint32 { return attr.Ispeed }
|
||||
|
||||
// Cfgetospeed returns the output baud rate stored in the termios structure.
|
||||
func Cfgetospeed(attr *unix.Termios) uint32 { return attr.Ospeed }
|
124
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_solaris.go
generated
vendored
Normal file
124
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
package termios
|
||||
|
||||
// #include <termios.h>
|
||||
// typedef struct termios termios_t;
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
TCSETS = 0x5402
|
||||
TCSETSW = 0x5403
|
||||
TCSETSF = 0x5404
|
||||
TCFLSH = 0x540B
|
||||
TCSBRK = 0x5409
|
||||
TCSBRKP = 0x5425
|
||||
|
||||
IXON = 0x00000400
|
||||
IXANY = 0x00000800
|
||||
IXOFF = 0x00001000
|
||||
CRTSCTS = 0x80000000
|
||||
)
|
||||
|
||||
// See /usr/include/sys/termios.h
|
||||
const FIORDCHK = C.FIORDCHK
|
||||
|
||||
// Tcgetattr gets the current serial port settings.
|
||||
func Tcgetattr(fd uintptr, argp *unix.Termios) error {
|
||||
termios, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
||||
*argp = *(tiosTounix(termios))
|
||||
return err
|
||||
}
|
||||
|
||||
// Tcsetattr sets the current serial port settings.
|
||||
func Tcsetattr(fd, action uintptr, argp *unix.Termios) error {
|
||||
return unix.IoctlSetTermios(int(fd), uint(action), tiosToUnix(argp))
|
||||
}
|
||||
|
||||
// Tcsendbreak transmits a continuous stream of zero-valued bits for a specific
|
||||
// duration, if the terminal is using asynchronous serial data transmission. If
|
||||
// duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds.
|
||||
// If duration is not zero, it sends zero-valued bits for some
|
||||
// implementation-defined length of time.
|
||||
func Tcsendbreak(fd, duration uintptr) error {
|
||||
return ioctl(fd, TCSBRKP, duration)
|
||||
}
|
||||
|
||||
// Tcdrain waits until all output written to the object referred to by fd has been transmitted.
|
||||
func Tcdrain(fd uintptr) error {
|
||||
// simulate drain with TCSADRAIN
|
||||
var attr unix.Termios
|
||||
if err := Tcgetattr(fd, &attr); err != nil {
|
||||
return err
|
||||
}
|
||||
return Tcsetattr(fd, TCSADRAIN, &attr)
|
||||
}
|
||||
|
||||
// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector.
|
||||
func Tcflush(fd, selector uintptr) error {
|
||||
return ioctl(fd, TCFLSH, selector)
|
||||
}
|
||||
|
||||
// Tiocinq returns the number of bytes in the input buffer.
|
||||
func Tiocinq(fd uintptr, argp *int) (err error) {
|
||||
*argp, err = unix.IoctlGetInt(int(fd), FIORDCHK)
|
||||
return err
|
||||
}
|
||||
|
||||
// Tiocoutq return the number of bytes in the output buffer.
|
||||
func Tiocoutq(fd uintptr, argp *int) error {
|
||||
return ioctl(fd, unix.TIOCOUTQ, uintptr(unsafe.Pointer(argp)))
|
||||
}
|
||||
|
||||
// Cfgetispeed returns the input baud rate stored in the termios structure.
|
||||
func Cfgetispeed(attr *unix.Termios) uint32 {
|
||||
solTermios := tiosToUnix(attr)
|
||||
return uint32(C.cfgetispeed((*C.termios_t)(unsafe.Pointer(solTermios))))
|
||||
}
|
||||
|
||||
// Cfsetispeed sets the input baud rate stored in the termios structure.
|
||||
func Cfsetispeed(attr *unix.Termios, speed uintptr) error {
|
||||
solTermios := tiosToUnix(attr)
|
||||
_, err := C.cfsetispeed((*C.termios_t)(unsafe.Pointer(solTermios)), C.speed_t(speed))
|
||||
return err
|
||||
}
|
||||
|
||||
// Cfgetospeed returns the output baud rate stored in the termios structure.
|
||||
func Cfgetospeed(attr *unix.Termios) uint32 {
|
||||
solTermios := tiosToUnix(attr)
|
||||
return uint32(C.cfgetospeed((*C.termios_t)(unsafe.Pointer(solTermios))))
|
||||
}
|
||||
|
||||
// Cfsetospeed sets the output baud rate stored in the termios structure.
|
||||
func Cfsetospeed(attr *unix.Termios, speed uintptr) error {
|
||||
solTermios := tiosToUnix(attr)
|
||||
_, err := C.cfsetospeed((*C.termios_t)(unsafe.Pointer(solTermios)), C.speed_t(speed))
|
||||
return err
|
||||
}
|
||||
|
||||
// tiosToUnix copies a unix.Termios to a x/sys/unix.Termios.
|
||||
// This is needed since type conversions between the two fail due to
|
||||
// more recent x/sys/unix.Termios renaming the padding field.
|
||||
func tiosToUnix(st *unix.Termios) *unix.Termios {
|
||||
return &unix.Termios{
|
||||
Iflag: st.Iflag,
|
||||
Oflag: st.Oflag,
|
||||
Cflag: st.Cflag,
|
||||
Lflag: st.Lflag,
|
||||
Cc: st.Cc,
|
||||
}
|
||||
}
|
||||
|
||||
// tiosTounix copies a x/sys/unix.Termios to a unix.Termios.
|
||||
func tiosTounix(ut *unix.Termios) *unix.Termios {
|
||||
return &unix.Termios{
|
||||
Iflag: ut.Iflag,
|
||||
Oflag: ut.Oflag,
|
||||
Cflag: ut.Cflag,
|
||||
Lflag: ut.Lflag,
|
||||
Cc: ut.Cc,
|
||||
}
|
||||
}
|
1
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_windows.go
generated
vendored
Normal file
1
src/cmd/linuxkit/vendor/github.com/pkg/term/termios/termios_windows.go
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
package termios
|
27
src/cmd/linuxkit/vendor/github.com/rs/xid/.appveyor.yml
generated
vendored
Normal file
27
src/cmd/linuxkit/vendor/github.com/rs/xid/.appveyor.yml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
version: 1.0.0.{build}
|
||||
|
||||
platform: x64
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\rs\xid
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
install:
|
||||
- echo %PATH%
|
||||
- echo %GOPATH%
|
||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||
- go version
|
||||
- go env
|
||||
- go get -t .
|
||||
|
||||
build_script:
|
||||
- go build
|
||||
|
||||
test_script:
|
||||
- go test
|
||||
|
8
src/cmd/linuxkit/vendor/github.com/rs/xid/.travis.yml
generated
vendored
Normal file
8
src/cmd/linuxkit/vendor/github.com/rs/xid/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- "1.9"
|
||||
- "1.10"
|
||||
- "master"
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: "master"
|
19
src/cmd/linuxkit/vendor/github.com/rs/xid/LICENSE
generated
vendored
Normal file
19
src/cmd/linuxkit/vendor/github.com/rs/xid/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015 Olivier Poitrey <rs@dailymotion.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
116
src/cmd/linuxkit/vendor/github.com/rs/xid/README.md
generated
vendored
Normal file
116
src/cmd/linuxkit/vendor/github.com/rs/xid/README.md
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
# Globally Unique ID Generator
|
||||
|
||||
[](https://godoc.org/github.com/rs/xid) [](https://raw.githubusercontent.com/rs/xid/master/LICENSE) [](https://travis-ci.org/rs/xid) [](http://gocover.io/github.com/rs/xid)
|
||||
|
||||
Package xid is a globally unique id generator library, ready to safely be used directly in your server code.
|
||||
|
||||
Xid uses the Mongo Object ID algorithm to generate globally unique ids with a different serialization (base64) to make it shorter when transported as a string:
|
||||
https://docs.mongodb.org/manual/reference/object-id/
|
||||
|
||||
- 4-byte value representing the seconds since the Unix epoch,
|
||||
- 3-byte machine identifier,
|
||||
- 2-byte process id, and
|
||||
- 3-byte counter, starting with a random value.
|
||||
|
||||
The binary representation of the id is compatible with Mongo 12 bytes Object IDs.
|
||||
The string representation is using base32 hex (w/o padding) for better space efficiency
|
||||
when stored in that form (20 bytes). The hex variant of base32 is used to retain the
|
||||
sortable property of the id.
|
||||
|
||||
Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an
|
||||
issue when transported as a string between various systems. Base36 wasn't retained either
|
||||
because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned)
|
||||
and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long,
|
||||
all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`).
|
||||
|
||||
UUIDs are 16 bytes (128 bits) and 36 chars as string representation. Twitter Snowflake
|
||||
ids are 8 bytes (64 bits) but require machine/data-center configuration and/or central
|
||||
generator servers. xid stands in between with 12 bytes (96 bits) and a more compact
|
||||
URL-safe string representation (20 chars). No configuration or central generator server
|
||||
is required so it can be used directly in server's code.
|
||||
|
||||
| Name | Binary Size | String Size | Features
|
||||
|-------------|-------------|----------------|----------------
|
||||
| [UUID] | 16 bytes | 36 chars | configuration free, not sortable
|
||||
| [shortuuid] | 16 bytes | 22 chars | configuration free, not sortable
|
||||
| [Snowflake] | 8 bytes | up to 20 chars | needs machine/DC configuration, needs central server, sortable
|
||||
| [MongoID] | 12 bytes | 24 chars | configuration free, sortable
|
||||
| xid | 12 bytes | 20 chars | configuration free, sortable
|
||||
|
||||
[UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||
[shortuuid]: https://github.com/stochastic-technologies/shortuuid
|
||||
[Snowflake]: https://blog.twitter.com/2010/announcing-snowflake
|
||||
[MongoID]: https://docs.mongodb.org/manual/reference/object-id/
|
||||
|
||||
Features:
|
||||
|
||||
- Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
|
||||
- Base32 hex encoded by default (20 chars when transported as printable string, still sortable)
|
||||
- Non configured, you don't need set a unique machine and/or data center id
|
||||
- K-ordered
|
||||
- Embedded time with 1 second precision
|
||||
- Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
|
||||
- Lock-free (i.e.: unlike UUIDv1 and v2)
|
||||
|
||||
Best used with [zerolog](https://github.com/rs/zerolog)'s
|
||||
[RequestIDHandler](https://godoc.org/github.com/rs/zerolog/hlog#RequestIDHandler).
|
||||
|
||||
Notes:
|
||||
|
||||
- Xid is dependent on the system time, a monotonic counter and so is not cryptographically secure. If unpredictability of IDs is important, you should not use Xids. It is worth noting that most other UUID-like implementations are also not cryptographically secure. You should use libraries that rely on cryptographically secure sources (like /dev/urandom on unix, crypto/rand in golang), if you want a truly random ID generator.
|
||||
|
||||
References:
|
||||
|
||||
- http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems
|
||||
- https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||
- https://blog.twitter.com/2010/announcing-snowflake
|
||||
- Python port by [Graham Abbott](https://github.com/graham): https://github.com/graham/python_xid
|
||||
- Scala port by [Egor Kolotaev](https://github.com/kolotaev): https://github.com/kolotaev/ride
|
||||
- Rust port by [Jérôme Renard](https://github.com/jeromer/): https://github.com/jeromer/libxid
|
||||
- Ruby port by [Valar](https://github.com/valarpirai/): https://github.com/valarpirai/ruby_xid
|
||||
- Java port by [0xShamil](https://github.com/0xShamil/): https://github.com/0xShamil/java-xid
|
||||
- Dart port by [Peter Bwire](https://github.com/pitabwire): https://pub.dev/packages/xid
|
||||
|
||||
## Install
|
||||
|
||||
go get github.com/rs/xid
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
guid := xid.New()
|
||||
|
||||
println(guid.String())
|
||||
// Output: 9m4e2mr0ui3e8a215n4g
|
||||
```
|
||||
|
||||
Get `xid` embedded info:
|
||||
|
||||
```go
|
||||
guid.Machine()
|
||||
guid.Pid()
|
||||
guid.Time()
|
||||
guid.Counter()
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
|
||||
Benchmark against Go [Maxim Bublis](https://github.com/satori)'s [UUID](https://github.com/satori/go.uuid).
|
||||
|
||||
```
|
||||
BenchmarkXID 20000000 91.1 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkXID-2 20000000 55.9 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkXID-4 50000000 32.3 ns/op 32 B/op 1 allocs/op
|
||||
BenchmarkUUIDv1 10000000 204 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkUUIDv1-2 10000000 160 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkUUIDv1-4 10000000 195 ns/op 48 B/op 1 allocs/op
|
||||
BenchmarkUUIDv4 1000000 1503 ns/op 64 B/op 2 allocs/op
|
||||
BenchmarkUUIDv4-2 1000000 1427 ns/op 64 B/op 2 allocs/op
|
||||
BenchmarkUUIDv4-4 1000000 1452 ns/op 64 B/op 2 allocs/op
|
||||
```
|
||||
|
||||
Note: UUIDv1 requires a global lock, hence the performance degradation as we add more CPUs.
|
||||
|
||||
## Licenses
|
||||
|
||||
All source code is licensed under the [MIT License](https://raw.github.com/rs/xid/master/LICENSE).
|
11
src/cmd/linuxkit/vendor/github.com/rs/xid/error.go
generated
vendored
Normal file
11
src/cmd/linuxkit/vendor/github.com/rs/xid/error.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package xid
|
||||
|
||||
const (
|
||||
// ErrInvalidID is returned when trying to unmarshal an invalid ID.
|
||||
ErrInvalidID strErr = "xid: invalid ID"
|
||||
)
|
||||
|
||||
// strErr allows declaring errors as constants.
|
||||
type strErr string
|
||||
|
||||
func (err strErr) Error() string { return string(err) }
|
3
src/cmd/linuxkit/vendor/github.com/rs/xid/go.mod
generated
vendored
Normal file
3
src/cmd/linuxkit/vendor/github.com/rs/xid/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/rs/xid
|
||||
|
||||
go 1.12
|
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_darwin.go
generated
vendored
Normal file
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build darwin
|
||||
|
||||
package xid
|
||||
|
||||
import "syscall"
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
return syscall.Sysctl("kern.uuid")
|
||||
}
|
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_fallback.go
generated
vendored
Normal file
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_fallback.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build !darwin,!linux,!freebsd,!windows
|
||||
|
||||
package xid
|
||||
|
||||
import "errors"
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_freebsd.go
generated
vendored
Normal file
9
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build freebsd
|
||||
|
||||
package xid
|
||||
|
||||
import "syscall"
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
return syscall.Sysctl("kern.hostuuid")
|
||||
}
|
13
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
Normal file
13
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_linux.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build linux
|
||||
|
||||
package xid
|
||||
|
||||
import "io/ioutil"
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
b, err := ioutil.ReadFile("/etc/machine-id")
|
||||
if err != nil || len(b) == 0 {
|
||||
b, err = ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
|
||||
}
|
||||
return string(b), err
|
||||
}
|
38
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_windows.go
generated
vendored
Normal file
38
src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_windows.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// +build windows
|
||||
|
||||
package xid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func readPlatformMachineID() (string, error) {
|
||||
// source: https://github.com/shirou/gopsutil/blob/master/host/host_syscall.go
|
||||
var h syscall.Handle
|
||||
err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, syscall.KEY_READ|syscall.KEY_WOW64_64KEY, &h)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer syscall.RegCloseKey(h)
|
||||
|
||||
const syscallRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16
|
||||
const uuidLen = 36
|
||||
|
||||
var regBuf [syscallRegBufLen]uint16
|
||||
bufLen := uint32(syscallRegBufLen)
|
||||
var valType uint32
|
||||
err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hostID := syscall.UTF16ToString(regBuf[:])
|
||||
hostIDLen := len(hostID)
|
||||
if hostIDLen != uuidLen {
|
||||
return "", fmt.Errorf("HostID incorrect: %q\n", hostID)
|
||||
}
|
||||
|
||||
return hostID, nil
|
||||
}
|
392
src/cmd/linuxkit/vendor/github.com/rs/xid/id.go
generated
vendored
Normal file
392
src/cmd/linuxkit/vendor/github.com/rs/xid/id.go
generated
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
// Package xid is a globally unique id generator suited for web scale
|
||||
//
|
||||
// Xid is using Mongo Object ID algorithm to generate globally unique ids:
|
||||
// https://docs.mongodb.org/manual/reference/object-id/
|
||||
//
|
||||
// - 4-byte value representing the seconds since the Unix epoch,
|
||||
// - 3-byte machine identifier,
|
||||
// - 2-byte process id, and
|
||||
// - 3-byte counter, starting with a random value.
|
||||
//
|
||||
// The binary representation of the id is compatible with Mongo 12 bytes Object IDs.
|
||||
// The string representation is using base32 hex (w/o padding) for better space efficiency
|
||||
// when stored in that form (20 bytes). The hex variant of base32 is used to retain the
|
||||
// sortable property of the id.
|
||||
//
|
||||
// Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an
|
||||
// issue when transported as a string between various systems. Base36 wasn't retained either
|
||||
// because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned)
|
||||
// and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long,
|
||||
// all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`).
|
||||
//
|
||||
// UUID is 16 bytes (128 bits), snowflake is 8 bytes (64 bits), xid stands in between
|
||||
// with 12 bytes with a more compact string representation ready for the web and no
|
||||
// required configuration or central generation server.
|
||||
//
|
||||
// Features:
|
||||
//
|
||||
// - Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
|
||||
// - Base32 hex encoded by default (16 bytes storage when transported as printable string)
|
||||
// - Non configured, you don't need set a unique machine and/or data center id
|
||||
// - K-ordered
|
||||
// - Embedded time with 1 second precision
|
||||
// - Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
|
||||
//
|
||||
// Best used with xlog's RequestIDHandler (https://godoc.org/github.com/rs/xlog#RequestIDHandler).
|
||||
//
|
||||
// References:
|
||||
//
|
||||
// - http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems
|
||||
// - https://en.wikipedia.org/wiki/Universally_unique_identifier
|
||||
// - https://blog.twitter.com/2010/announcing-snowflake
|
||||
package xid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Code inspired from mgo/bson ObjectId
|
||||
|
||||
// ID represents a unique request id
|
||||
type ID [rawLen]byte
|
||||
|
||||
const (
|
||||
encodedLen = 20 // string encoded len
|
||||
rawLen = 12 // binary raw len
|
||||
|
||||
// encoding stores a custom version of the base32 encoding with lower case
|
||||
// letters.
|
||||
encoding = "0123456789abcdefghijklmnopqrstuv"
|
||||
)
|
||||
|
||||
var (
|
||||
// objectIDCounter is atomically incremented when generating a new ObjectId
|
||||
// using NewObjectId() function. It's used as a counter part of an id.
|
||||
// This id is initialized with a random value.
|
||||
objectIDCounter = randInt()
|
||||
|
||||
// machineId stores machine id generated once and used in subsequent calls
|
||||
// to NewObjectId function.
|
||||
machineID = readMachineID()
|
||||
|
||||
// pid stores the current process id
|
||||
pid = os.Getpid()
|
||||
|
||||
nilID ID
|
||||
|
||||
// dec is the decoding map for base32 encoding
|
||||
dec [256]byte
|
||||
)
|
||||
|
||||
func init() {
|
||||
for i := 0; i < len(dec); i++ {
|
||||
dec[i] = 0xFF
|
||||
}
|
||||
for i := 0; i < len(encoding); i++ {
|
||||
dec[encoding[i]] = byte(i)
|
||||
}
|
||||
|
||||
// If /proc/self/cpuset exists and is not /, we can assume that we are in a
|
||||
// form of container and use the content of cpuset xor-ed with the PID in
|
||||
// order get a reasonable machine global unique PID.
|
||||
b, err := ioutil.ReadFile("/proc/self/cpuset")
|
||||
if err == nil && len(b) > 1 {
|
||||
pid ^= int(crc32.ChecksumIEEE(b))
|
||||
}
|
||||
}
|
||||
|
||||
// readMachineId generates machine id and puts it into the machineId global
|
||||
// variable. If this function fails to get the hostname, it will cause
|
||||
// a runtime error.
|
||||
func readMachineID() []byte {
|
||||
id := make([]byte, 3)
|
||||
hid, err := readPlatformMachineID()
|
||||
if err != nil || len(hid) == 0 {
|
||||
hid, err = os.Hostname()
|
||||
}
|
||||
if err == nil && len(hid) != 0 {
|
||||
hw := md5.New()
|
||||
hw.Write([]byte(hid))
|
||||
copy(id, hw.Sum(nil))
|
||||
} else {
|
||||
// Fallback to rand number if machine id can't be gathered
|
||||
if _, randErr := rand.Reader.Read(id); randErr != nil {
|
||||
panic(fmt.Errorf("xid: cannot get hostname nor generate a random number: %v; %v", err, randErr))
|
||||
}
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// randInt generates a random uint32
|
||||
func randInt() uint32 {
|
||||
b := make([]byte, 3)
|
||||
if _, err := rand.Reader.Read(b); err != nil {
|
||||
panic(fmt.Errorf("xid: cannot generate random number: %v;", err))
|
||||
}
|
||||
return uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])
|
||||
}
|
||||
|
||||
// New generates a globally unique ID
|
||||
func New() ID {
|
||||
return NewWithTime(time.Now())
|
||||
}
|
||||
|
||||
// NewWithTime generates a globally unique ID with the passed in time
|
||||
func NewWithTime(t time.Time) ID {
|
||||
var id ID
|
||||
// Timestamp, 4 bytes, big endian
|
||||
binary.BigEndian.PutUint32(id[:], uint32(t.Unix()))
|
||||
// Machine, first 3 bytes of md5(hostname)
|
||||
id[4] = machineID[0]
|
||||
id[5] = machineID[1]
|
||||
id[6] = machineID[2]
|
||||
// Pid, 2 bytes, specs don't specify endianness, but we use big endian.
|
||||
id[7] = byte(pid >> 8)
|
||||
id[8] = byte(pid)
|
||||
// Increment, 3 bytes, big endian
|
||||
i := atomic.AddUint32(&objectIDCounter, 1)
|
||||
id[9] = byte(i >> 16)
|
||||
id[10] = byte(i >> 8)
|
||||
id[11] = byte(i)
|
||||
return id
|
||||
}
|
||||
|
||||
// FromString reads an ID from its string representation
|
||||
func FromString(id string) (ID, error) {
|
||||
i := &ID{}
|
||||
err := i.UnmarshalText([]byte(id))
|
||||
return *i, err
|
||||
}
|
||||
|
||||
// String returns a base32 hex lowercased with no padding representation of the id (char set is 0-9, a-v).
|
||||
func (id ID) String() string {
|
||||
text := make([]byte, encodedLen)
|
||||
encode(text, id[:])
|
||||
return *(*string)(unsafe.Pointer(&text))
|
||||
}
|
||||
|
||||
// Encode encodes the id using base32 encoding, writing 20 bytes to dst and return it.
|
||||
func (id ID) Encode(dst []byte) []byte {
|
||||
encode(dst, id[:])
|
||||
return dst
|
||||
}
|
||||
|
||||
// MarshalText implements encoding/text TextMarshaler interface
|
||||
func (id ID) MarshalText() ([]byte, error) {
|
||||
text := make([]byte, encodedLen)
|
||||
encode(text, id[:])
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements encoding/json Marshaler interface
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
if id.IsNil() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
text := make([]byte, encodedLen+2)
|
||||
encode(text[1:encodedLen+1], id[:])
|
||||
text[0], text[encodedLen+1] = '"', '"'
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// encode by unrolling the stdlib base32 algorithm + removing all safe checks
|
||||
func encode(dst, id []byte) {
|
||||
_ = dst[19]
|
||||
_ = id[11]
|
||||
|
||||
dst[19] = encoding[(id[11]<<4)&0x1F]
|
||||
dst[18] = encoding[(id[11]>>1)&0x1F]
|
||||
dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F]
|
||||
dst[16] = encoding[id[10]>>3]
|
||||
dst[15] = encoding[id[9]&0x1F]
|
||||
dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F]
|
||||
dst[13] = encoding[(id[8]>>2)&0x1F]
|
||||
dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F]
|
||||
dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F]
|
||||
dst[10] = encoding[(id[6]>>1)&0x1F]
|
||||
dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F]
|
||||
dst[8] = encoding[id[5]>>3]
|
||||
dst[7] = encoding[id[4]&0x1F]
|
||||
dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F]
|
||||
dst[5] = encoding[(id[3]>>2)&0x1F]
|
||||
dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F]
|
||||
dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F]
|
||||
dst[2] = encoding[(id[1]>>1)&0x1F]
|
||||
dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F]
|
||||
dst[0] = encoding[id[0]>>3]
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding/text TextUnmarshaler interface
|
||||
func (id *ID) UnmarshalText(text []byte) error {
|
||||
if len(text) != encodedLen {
|
||||
return ErrInvalidID
|
||||
}
|
||||
for _, c := range text {
|
||||
if dec[c] == 0xFF {
|
||||
return ErrInvalidID
|
||||
}
|
||||
}
|
||||
if !decode(id, text) {
|
||||
return ErrInvalidID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements encoding/json Unmarshaler interface
|
||||
func (id *ID) UnmarshalJSON(b []byte) error {
|
||||
s := string(b)
|
||||
if s == "null" {
|
||||
*id = nilID
|
||||
return nil
|
||||
}
|
||||
// Check the slice length to prevent panic on passing it to UnmarshalText()
|
||||
if len(b) < 2 {
|
||||
return ErrInvalidID
|
||||
}
|
||||
return id.UnmarshalText(b[1 : len(b)-1])
|
||||
}
|
||||
|
||||
// decode by unrolling the stdlib base32 algorithm + customized safe check.
|
||||
func decode(id *ID, src []byte) bool {
|
||||
_ = src[19]
|
||||
_ = id[11]
|
||||
|
||||
id[11] = dec[src[17]]<<6 | dec[src[18]]<<1 | dec[src[19]]>>4
|
||||
id[10] = dec[src[16]]<<3 | dec[src[17]]>>2
|
||||
id[9] = dec[src[14]]<<5 | dec[src[15]]
|
||||
id[8] = dec[src[12]]<<7 | dec[src[13]]<<2 | dec[src[14]]>>3
|
||||
id[7] = dec[src[11]]<<4 | dec[src[12]]>>1
|
||||
id[6] = dec[src[9]]<<6 | dec[src[10]]<<1 | dec[src[11]]>>4
|
||||
id[5] = dec[src[8]]<<3 | dec[src[9]]>>2
|
||||
id[4] = dec[src[6]]<<5 | dec[src[7]]
|
||||
id[3] = dec[src[4]]<<7 | dec[src[5]]<<2 | dec[src[6]]>>3
|
||||
id[2] = dec[src[3]]<<4 | dec[src[4]]>>1
|
||||
id[1] = dec[src[1]]<<6 | dec[src[2]]<<1 | dec[src[3]]>>4
|
||||
id[0] = dec[src[0]]<<3 | dec[src[1]]>>2
|
||||
|
||||
// Validate that there are no discarer bits (padding) in src that would
|
||||
// cause the string-encoded id not to equal src.
|
||||
var check [4]byte
|
||||
|
||||
check[3] = encoding[(id[11]<<4)&0x1F]
|
||||
check[2] = encoding[(id[11]>>1)&0x1F]
|
||||
check[1] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F]
|
||||
check[0] = encoding[id[10]>>3]
|
||||
return bytes.Equal([]byte(src[16:20]), check[:])
|
||||
}
|
||||
|
||||
// Time returns the timestamp part of the id.
|
||||
// It's a runtime error to call this method with an invalid id.
|
||||
func (id ID) Time() time.Time {
|
||||
// First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch.
|
||||
secs := int64(binary.BigEndian.Uint32(id[0:4]))
|
||||
return time.Unix(secs, 0)
|
||||
}
|
||||
|
||||
// Machine returns the 3-byte machine id part of the id.
|
||||
// It's a runtime error to call this method with an invalid id.
|
||||
func (id ID) Machine() []byte {
|
||||
return id[4:7]
|
||||
}
|
||||
|
||||
// Pid returns the process id part of the id.
|
||||
// It's a runtime error to call this method with an invalid id.
|
||||
func (id ID) Pid() uint16 {
|
||||
return binary.BigEndian.Uint16(id[7:9])
|
||||
}
|
||||
|
||||
// Counter returns the incrementing value part of the id.
|
||||
// It's a runtime error to call this method with an invalid id.
|
||||
func (id ID) Counter() int32 {
|
||||
b := id[9:12]
|
||||
// Counter is stored as big-endian 3-byte value
|
||||
return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
|
||||
}
|
||||
|
||||
// Value implements the driver.Valuer interface.
|
||||
func (id ID) Value() (driver.Value, error) {
|
||||
if id.IsNil() {
|
||||
return nil, nil
|
||||
}
|
||||
b, err := id.MarshalText()
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface.
|
||||
func (id *ID) Scan(value interface{}) (err error) {
|
||||
switch val := value.(type) {
|
||||
case string:
|
||||
return id.UnmarshalText([]byte(val))
|
||||
case []byte:
|
||||
return id.UnmarshalText(val)
|
||||
case nil:
|
||||
*id = nilID
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("xid: scanning unsupported type: %T", value)
|
||||
}
|
||||
}
|
||||
|
||||
// IsNil Returns true if this is a "nil" ID
|
||||
func (id ID) IsNil() bool {
|
||||
return id == nilID
|
||||
}
|
||||
|
||||
// NilID returns a zero value for `xid.ID`.
|
||||
func NilID() ID {
|
||||
return nilID
|
||||
}
|
||||
|
||||
// Bytes returns the byte array representation of `ID`
|
||||
func (id ID) Bytes() []byte {
|
||||
return id[:]
|
||||
}
|
||||
|
||||
// FromBytes convert the byte array representation of `ID` back to `ID`
|
||||
func FromBytes(b []byte) (ID, error) {
|
||||
var id ID
|
||||
if len(b) != rawLen {
|
||||
return id, ErrInvalidID
|
||||
}
|
||||
copy(id[:], b)
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// Compare returns an integer comparing two IDs. It behaves just like `bytes.Compare`.
|
||||
// The result will be 0 if two IDs are identical, -1 if current id is less than the other one,
|
||||
// and 1 if current id is greater than the other.
|
||||
func (id ID) Compare(other ID) int {
|
||||
return bytes.Compare(id[:], other[:])
|
||||
}
|
||||
|
||||
type sorter []ID
|
||||
|
||||
func (s sorter) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s sorter) Less(i, j int) bool {
|
||||
return s[i].Compare(s[j]) < 0
|
||||
}
|
||||
|
||||
func (s sorter) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// Sort sorts an array of IDs inplace.
|
||||
// It works by wrapping `[]ID` and use `sort.Sort`.
|
||||
func Sort(ids []ID) {
|
||||
sort.Sort(sorter(ids))
|
||||
}
|
9
src/cmd/linuxkit/vendor/modules.txt
vendored
9
src/cmd/linuxkit/vendor/modules.txt
vendored
@@ -37,6 +37,9 @@ github.com/Azure/go-autorest/autorest/validation
|
||||
github.com/Azure/go-autorest/logger
|
||||
# github.com/Azure/go-autorest/tracing v0.6.0
|
||||
github.com/Azure/go-autorest/tracing
|
||||
# github.com/Code-Hex/vz v0.0.4
|
||||
## explicit
|
||||
github.com/Code-Hex/vz
|
||||
# github.com/Microsoft/go-winio v0.5.2
|
||||
## explicit
|
||||
github.com/Microsoft/go-winio
|
||||
@@ -427,6 +430,9 @@ github.com/opencontainers/runtime-spec/specs-go
|
||||
github.com/packethost/packngo
|
||||
# github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/errors
|
||||
# github.com/pkg/term v1.1.0
|
||||
## explicit
|
||||
github.com/pkg/term/termios
|
||||
# github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/pmezard/go-difflib/difflib
|
||||
# github.com/prometheus/client_golang v1.12.1
|
||||
@@ -468,6 +474,8 @@ github.com/radu-matei/azure-vhd-utils/vhdcore/writer
|
||||
# github.com/rn/iso9660wrap v0.0.0-20171120145750-baf8d62ad315
|
||||
## explicit
|
||||
github.com/rn/iso9660wrap
|
||||
# github.com/rs/xid v1.4.0
|
||||
github.com/rs/xid
|
||||
# github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6
|
||||
## explicit
|
||||
github.com/scaleway/scaleway-sdk-go/api/instance/v1
|
||||
@@ -610,6 +618,7 @@ golang.org/x/oauth2/jwt
|
||||
golang.org/x/sync/errgroup
|
||||
golang.org/x/sync/semaphore
|
||||
# golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
## explicit
|
||||
golang.org/x/sys/cpu
|
||||
golang.org/x/sys/execabs
|
||||
golang.org/x/sys/internal/unsafeheader
|
||||
|
Reference in New Issue
Block a user