diff --git a/.gitignore b/.gitignore index f707d8594197..85f67442726e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ cluster/local/certs _out vendor/**/*_test.go **/polarion.xml +tools/manifest-templator/manifest-templator +tools/vms-generator/vms-generator diff --git a/cluster/examples/vm-ephemeral.yaml b/cluster/examples/vm-ephemeral.yaml new file mode 100644 index 000000000000..4248da85ee70 --- /dev/null +++ b/cluster/examples/vm-ephemeral.yaml @@ -0,0 +1,24 @@ +apiVersion: kubevirt.io/v1alpha1 +kind: VirtualMachine +metadata: + creationTimestamp: null + name: vm-ephemeral +spec: + domain: + devices: + disks: + - disk: + bus: virtio + name: registrydisk + volumeName: registryvolume + machine: + type: "" + resources: + requests: + memory: 64M + terminationGracePeriodSeconds: 0 + volumes: + - name: registryvolume + registryDisk: + image: kubevirt/cirros-registry-disk-demo:devel +status: {} diff --git a/cluster/examples/vm-fedora.yaml b/cluster/examples/vm-fedora.yaml new file mode 100644 index 000000000000..94c5af52df40 --- /dev/null +++ b/cluster/examples/vm-fedora.yaml @@ -0,0 +1,31 @@ +apiVersion: kubevirt.io/v1alpha1 +kind: VirtualMachine +metadata: + creationTimestamp: null + name: vm-fedora +spec: + domain: + devices: + disks: + - disk: + bus: virtio + name: registrydisk + volumeName: registryvolume + - disk: + bus: virtio + name: cloudinitdisk + volumeName: cloudinitvolume + machine: + type: "" + resources: + requests: + memory: 1024M + terminationGracePeriodSeconds: 0 + volumes: + - name: registryvolume + registryDisk: + image: kubevirt/fedora-cloud-registry-disk-demo:devel + - cloudInitNoCloud: + userDataBase64: IyEvYmluL3NoCgplY2hvICdwcmludGVkIGZyb20gY2xvdWQtaW5pdCB1c2VyZGF0YScK + name: cloudinitvolume +status: {} diff --git a/cluster/examples/vm-flavor-small.yaml b/cluster/examples/vm-flavor-small.yaml new file mode 100644 index 000000000000..6031e2f6aea4 --- /dev/null +++ b/cluster/examples/vm-flavor-small.yaml @@ -0,0 +1,26 @@ +apiVersion: kubevirt.io/v1alpha1 +kind: VirtualMachine +metadata: + creationTimestamp: null + labels: + kubevirt.io/flavor: small + name: vm-flavor-small +spec: + domain: + devices: + disks: + - disk: + bus: virtio + name: registrydisk + volumeName: registryvolume + machine: + type: "" + resources: + requests: + memory: 64M + terminationGracePeriodSeconds: 0 + volumes: + - name: registryvolume + registryDisk: + image: kubevirt/cirros-registry-disk-demo:devel +status: {} diff --git a/cluster/examples/vm-nocloud.yaml b/cluster/examples/vm-nocloud.yaml new file mode 100644 index 000000000000..3a7a8d816f91 --- /dev/null +++ b/cluster/examples/vm-nocloud.yaml @@ -0,0 +1,38 @@ +apiVersion: kubevirt.io/v1alpha1 +kind: VirtualMachine +metadata: + creationTimestamp: null + name: vm-nocloud +spec: + domain: + devices: + disks: + - disk: + bus: virtio + name: registrydisk + volumeName: registryvolume + - disk: + bus: virtio + name: cloudinitdisk + volumeName: cloudinitvolume + - disk: + bus: virtio + name: emptydisk + volumeName: emptydiskvolume + machine: + type: "" + resources: + requests: + memory: 64M + terminationGracePeriodSeconds: 0 + volumes: + - name: registryvolume + registryDisk: + image: kubevirt/cirros-registry-disk-demo:devel + - cloudInitNoCloud: + userDataBase64: IyEvYmluL3NoCgplY2hvICdwcmludGVkIGZyb20gY2xvdWQtaW5pdCB1c2VyZGF0YScK + name: cloudinitvolume + - emptyDisk: + capacity: 2Gi + name: emptydiskvolume +status: {} diff --git a/cluster/vm-pvc.yaml b/cluster/examples/vm-pvc.yaml similarity index 55% rename from cluster/vm-pvc.yaml rename to cluster/examples/vm-pvc.yaml index d31ce7fe5209..ff5b8d9b7b8d 100644 --- a/cluster/vm-pvc.yaml +++ b/cluster/examples/vm-pvc.yaml @@ -1,20 +1,24 @@ apiVersion: kubevirt.io/v1alpha1 kind: VirtualMachine metadata: + creationTimestamp: null name: vm-pvc spec: - terminationGracePeriodSeconds: 0 domain: - resources: - requests: - memory: 64M devices: disks: - - name: mydisk + - disk: + bus: virtio + name: pvcdisk volumeName: pvcvolume - disk: - dev: vda + machine: + type: "" + resources: + requests: + memory: 64M + terminationGracePeriodSeconds: 0 volumes: - - name: pvcvolume - persistentVolumeClaim: - claimName: disk-alpine + - name: pvcvolume + persistentVolumeClaim: + claimName: disk-alpine +status: {} diff --git a/cluster/examples/vm-sata.yaml b/cluster/examples/vm-sata.yaml new file mode 100644 index 000000000000..20965e871175 --- /dev/null +++ b/cluster/examples/vm-sata.yaml @@ -0,0 +1,24 @@ +apiVersion: kubevirt.io/v1alpha1 +kind: VirtualMachine +metadata: + creationTimestamp: null + name: vm-sata +spec: + domain: + devices: + disks: + - disk: + bus: sata + name: registrydisk + volumeName: registryvolume + machine: + type: "" + resources: + requests: + memory: 64M + terminationGracePeriodSeconds: 0 + volumes: + - name: registryvolume + registryDisk: + image: kubevirt/cirros-registry-disk-demo:devel +status: {} diff --git a/cluster/windows-demo.yaml b/cluster/examples/vm-windows.yaml similarity index 68% rename from cluster/windows-demo.yaml rename to cluster/examples/vm-windows.yaml index efded26d2eb6..0edd78eefe29 100644 --- a/cluster/windows-demo.yaml +++ b/cluster/examples/vm-windows.yaml @@ -1,42 +1,46 @@ apiVersion: kubevirt.io/v1alpha1 kind: VirtualMachine metadata: - name: windows2012r2 + creationTimestamp: null + name: vm-windows spec: - terminationGracePeriodSeconds: 0 domain: + clock: + timer: + hpet: + present: false + hyperv: {} + pit: + tickPolicy: delay + rtc: + tickPolicy: catchup + utc: {} cpu: cores: 2 + devices: + disks: + - disk: + bus: sata + name: pvcdisk + volumeName: pvcvolume features: acpi: {} apic: {} hyperv: relaxed: {} - vapic: {} spinlocks: spinlocks: 8191 - clock: - utc: {} - timer: - hpet: - present: false - pit: - tickPolicy: delay - rtc: - tickPolicy: catchup - hyperv: {} + vapic: {} firmware: uuid: 5d307ca9-b3ef-428c-8861-06e72d69f223 + machine: + type: "" resources: requests: - memory: 512M - devices: - disks: - - name: server2012r2 - volumeName: server2012r2 - disk: - dev: vda + memory: 2Gi + terminationGracePeriodSeconds: 0 volumes: - - name: server2012r2 - persistentVolumeClaim: - claimName: my-windows-image + - name: pvcvolume + persistentVolumeClaim: + claimName: disk-windows +status: {} diff --git a/cluster/vm-dev-sata.yaml b/cluster/vm-dev-sata.yaml deleted file mode 100644 index cf47eb85d2c2..000000000000 --- a/cluster/vm-dev-sata.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: testvm-sata -spec: - terminationGracePeriodSeconds: 0 - domain: - resources: - requests: - memory: 64M - devices: - disks: - - name: mydisk - volumeName: myvolume - disk: - bus: sata - volumes: - - name: myvolume - registryDisk: - image: kubevirt/cirros-registry-disk-demo:devel diff --git a/cluster/vm-ephemeral.yaml b/cluster/vm-ephemeral.yaml deleted file mode 100644 index 863ffcbbb41d..000000000000 --- a/cluster/vm-ephemeral.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: testvm-ephemeral -spec: - domain: - resources: - requests: - memory: 64M - devices: - disks: - - name: registrydisk - volumeName: registryvolume - disk: - bus: virtio - volumes: - - name: registryvolume - registryDisk: - image: kubevirt/cirros-registry-disk-demo:devel diff --git a/cluster/vm-fedora.yaml b/cluster/vm-fedora.yaml deleted file mode 100644 index 3655586e5e54..000000000000 --- a/cluster/vm-fedora.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: fedora-ephemeral -spec: - terminationGracePeriodSeconds: 0 - domain: - resources: - requests: - memory: 1024M - devices: - disks: - - name: registrydisk - volumeName: registryvolume - disk: - bus: virtio - - name: cloudinitdisk - volumeName: cloudinitvolume - disk: - bus: virtio - volumes: - - name: registryvolume - registryDisk: - image: kubevirt/fedora-cloud-registry-disk-demo:devel - - name: cloudinitvolume - cloudInitNoCloud: - userDataBase64: I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg== - diff --git a/cluster/vm-nocloud.yaml b/cluster/vm-nocloud.yaml deleted file mode 100644 index 9d569272fba3..000000000000 --- a/cluster/vm-nocloud.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: testvm-nocloud -spec: - terminationGracePeriodSeconds: 5 - domain: - resources: - requests: - memory: 64M - devices: - disks: - - name: registrydisk - volumeName: registryvolume - disk: - bus: virtio - - name: cloudinitdisk - volumeName: cloudinitvolume - disk: - bus: virtio - - name: emptydisk - volumeName: emptydiskvolume - disk: - bus: virtio - volumes: - - name: registryvolume - registryDisk: - image: kubevirt/cirros-registry-disk-demo:devel - - name: cloudinitvolume - cloudInitNoCloud: - userDataBase64: I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg== - - name: emptydiskvolume - emptyDisk: - capacity: 2Gi diff --git a/cluster/vm-small.yaml b/cluster/vm-small.yaml deleted file mode 100644 index 21a16fd343ac..000000000000 --- a/cluster/vm-small.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: smallvm - labels: - kubevirt.io/flavor: small -spec: - terminationGracePeriodSeconds: 0 - domain: - devices: - disks: - - name: registrydisk - volumeName: registryvolume - disk: - bus: virtio - volumes: - - name: registryvolume - registryDisk: - image: kubevirt/cirros-registry-disk-demo:devel diff --git a/cluster/vm.yaml b/cluster/vm.yaml deleted file mode 100644 index 66b1310bb407..000000000000 --- a/cluster/vm.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: kubevirt.io/v1alpha1 -kind: VirtualMachine -metadata: - name: testvm -spec: - domain: - resources: - requests: - memory: 64M - devices: - disks: - - name: registrydisk - volumeName: registryvolume - disk: - bus: virtio - volumes: - - name: registryvolume - registryDisk: - image: kubevirt/cirros-registry-disk-demo:devel diff --git a/docs/getting-started.md b/docs/getting-started.md index 881e7332773a..efad4e1a6d34 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,65 +2,38 @@ A quick start guide to get KubeVirt up and running inside Vagrant. -**Note**: This guide was tested on Fedora 23 and Fedora 25. - -**Note:** Fedora 24 is known to have a bug which affects our vagrant setup. - ## Building The KubeVirt build system runs completely inside docker. In order to build KubeVirt you need to have `docker` and `rsync` installed. -### Vagrant - -[Vagrant](https://www.vagrantup.com/) is used to bring up a development and -demo environment: - -```bash - sudo dnf install vagrant vagrant-libvirt - sudo systemctl enable --now libvirtd - sudo systemctl restart virtlogd # Work around rpm packaging bug -``` - -On some systems Vagrant will always ask you for your sudo password when you try -to do something with a VM. To avoid retyping your password all the time you can -add yourself to the `libvirt` group. - -```bash -sudo gpasswd -a ${USER} libvirt -newgrp libvirt -``` - -On CentOS/RHEL 7 you might also need to change the libvirt connection string to be able to see all libvirt information: +### Dockerizied environment -``` -export LIBVIRT_DEFAULT_URI=qemu:///system -``` +Runs master and nodes containers, when each one of them run virtual machine via QEMU. +In additional it runs dnsmasq and docker registry containers. ### Compile and run it Build all required artifacts and launch the -Vagrant environment: +dockerizied environment: ```bash # Building and deploying kubevirt in Vagrant + export PROVIDER=k8s-1.9.3 make cluster-up make cluster-sync ``` -This will create a VM called `master` which acts as Kubernetes master and then -deploy Kubevirt there. To create one or more nodes which will register +This will create a VM called `node01` which acts as Kubernetes master and then +deploy KubeVirt there. To create one or more nodes which will register themselves on master, you can use the `VAGRANT_NUM_NODES` environment variable. This would create a master and one node: ```bash - VAGRANT_NUM_NODES=1 make cluster-up + export VAGRANT_NUM_NODES=1 + make cluster-up ``` -If you decide to use separate nodes, pass `VAGRANT_NUM_NODES` variable to all -vagrant interacting commands. However, just running `master` is enough for most -development tasks. - You could also run some build steps individually: ```bash @@ -92,8 +65,8 @@ After a successful build you can run the *unit tests*: make test ``` -They don't require vagrant. To run the *functional tests*, make sure you have set -up [Vagrant](#vagrant). Then run +They don't real environment. To run the *functional tests*, make sure you have set +up dockerizied environment. Then run ```bash make cluster-sync # synchronize with your code, if necessary @@ -106,30 +79,21 @@ Congratulations you are still with us and you have build KubeVirt. Now it's time to get hands on and give it a try. -### Cockpit - -Cockpit is exposed on -The default login is `root:vagrant` - -It can be used to view the cluster and verify the running state of -components within the cluster. -More information can be found on that [project's site](http://cockpit-project.org/guide/latest/feature-kubernetes.html). - ### Create a first Virtual Machine -Finally start a VM called `testvm`: +Finally start a VM called `vm-ephemeral`: ```bash # This can be done from your GIT repo, no need to log into a vagrant VM # Create a VM - ./cluster/kubectl.sh create -f cluster/vm.yaml + ./cluster/kubectl.sh create -f cluster/examples/vm-ephemeral.yaml # Sure? Let's list all created VMs ./cluster/kubectl.sh get vms # Enough, let's get rid of it - ./cluster/kubectl.sh delete -f cluster/vm.yaml + ./cluster/kubectl.sh delete -f cluster/examples/vm-ephemeral.yaml # You can actually use kubelet.sh to introspect the cluster in general @@ -142,19 +106,19 @@ tap networking device attached. #### Example ```bash -$ ./cluster/kubectl.sh create -f cluster/vm.yaml -vm "testvm" created +$ ./cluster/kubectl.sh create -f cluster/examples/vm-ephemeral.yaml +vm "vm-ephemeral" created $ ./cluster/kubectl.sh get pods -NAME READY STATUS RESTARTS AGE -virt-api 1/1 Running 1 10h -virt-controller 1/1 Running 1 10h -virt-handler-z90mp 1/1 Running 1 10h -virt-launcher-testvm9q7es 1/1 Running 0 10s +NAME READY STATUS RESTARTS AGE +virt-api 1/1 Running 1 10h +virt-controller 1/1 Running 1 10h +virt-handler-z90mp 1/1 Running 1 10h +virt-launcher-vm-ephemeral9q7es 1/1 Running 0 10s $ ./cluster/kubectl.sh get vms -NAME LABELS DATA -testvm kubevirt.io/nodeName=master {"apiVersion":"kubevirt.io/v1alpha1","kind":"VM","... +NAME LABELS DATA +vm-ephemera kubevirt.io/nodeName=node01 {"apiVersion":"kubevirt.io/v1alpha1","kind":"VM","... $ ./cluster/kubectl.sh get vms -o json { @@ -170,7 +134,7 @@ $ ./cluster/kubectl.sh get vms -o json "labels": { "kubevirt.io/nodeName": "master" }, - "name": "testvm", + "name": "vm-ephemeral", "namespace": "default", "resourceVersion": "102534", "selfLink": "/apis/kubevirt.io/v1alpha1/namespaces/default/virtualmachines/testvm", @@ -188,10 +152,10 @@ First make sure you have `remote-viewer` installed. On Fedora run dnf install virt-viewer ``` -Then, after you made sure that the VM `testvm` is running, type +Then, after you made sure that the VM `vm-ephemeral` is running, type ``` -cluster/kubectl.sh vnc testvm +cluster/kubectl.sh vnc vm-ephemeral ``` to start a remote session with `remote-viewer`. diff --git a/glide.lock b/glide.lock index 653d03a636f9..1c1ea614afa6 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,10 @@ -hash: 7de723d8efc0667bccdbca4c831f1cb408700b853f669b684daf054bbecb1a69 -updated: 2018-04-04T14:05:20.714355494Z +hash: bf8ae5a5691b8a1187917a88e4b23d532611fee91300dda23ddf20aed1ddbc10 +updated: 2018-04-11T10:54:40.231595613Z imports: - name: github.com/ant31/crd-validation version: eabcf70a1bd73e9296fa0c5f57de604689200a1b + subpackages: + - pkg - name: github.com/asaskevich/govalidator version: 7d2e70ef918f16bd6455529af38304d6d025c952 - name: github.com/davecgh/go-spew @@ -26,7 +28,7 @@ imports: - name: github.com/fsnotify/fsnotify version: c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9 - name: github.com/ghodss/yaml - version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee + version: 0ca9ea5df5451ffdf184b4428c902747c2c11cd7 - name: github.com/go-kit/kit version: fe6fe28ba0d54b39f27e79cddba4911b7e4fffc7 subpackages: @@ -57,7 +59,7 @@ imports: subpackages: - lru - name: github.com/golang/mock - version: 69521b3833175dfcfb1cc1fdb0c9be92e66faa81 + version: 8b2eeeb0ca5f56c78bec5efde9c4a21d9201126c subpackages: - gomock - name: github.com/golang/protobuf @@ -167,7 +169,7 @@ imports: subpackages: - cobra - name: github.com/spf13/pflag - version: 1ce0cc6db4029d97571db82f85092fccedb572ce + version: 329ebf1e04800d11a25047832495199d366580f3 - name: github.com/subgraph/libmacouflage version: 973191b8743358463d8f3abc9c6dc585f2c1e7fc - name: github.com/vishvananda/netlink @@ -274,6 +276,9 @@ imports: - storage/v1beta1 - name: k8s.io/apiextensions-apiserver version: 4b903ca6c8a2031b8f88c3d1fbefa8eb248b103c + subpackages: + - pkg/apis/apiextensions + - pkg/apis/apiextensions/v1beta1 - name: k8s.io/apimachinery version: 19e3f5aa3adca672c153d324e6b7d82ff8935f03 subpackages: diff --git a/glide.yaml b/glide.yaml index b3df522d4d34..c5f2bbd2658d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -24,6 +24,8 @@ import: version: v2.6.0 subpackages: - log +- package: github.com/ghodss/yaml + version: v1.0.0 - package: github.com/evanphx/json-patch version: ba18e35c5c1b36ef6334cad706eb681153d2d379 - package: k8s.io/client-go diff --git a/hack/generate.sh b/hack/generate.sh index 8cf5e1daec57..8f475ee32d8b 100755 --- a/hack/generate.sh +++ b/hack/generate.sh @@ -3,6 +3,7 @@ set -e source $(dirname "$0")/common.sh +source $(dirname "$0")/config.sh find ${KUBEVIRT_DIR}/pkg/ -name "*generated*.go" -exec rm {} -f \; @@ -18,3 +19,6 @@ ${KUBEVIRT_DIR}/tools/crd-generator/crd-generator --crd-type=vm >${KUBEVIRT_DIR} ${KUBEVIRT_DIR}/tools/crd-generator/crd-generator --crd-type=vmrs >${KUBEVIRT_DIR}/manifests/generated/vmrs-resource.yaml ${KUBEVIRT_DIR}/tools/crd-generator/crd-generator --crd-type=vmpreset >${KUBEVIRT_DIR}/manifests/generated/vmpreset-resource.yaml ${KUBEVIRT_DIR}/tools/crd-generator/crd-generator --crd-type=ovm >${KUBEVIRT_DIR}/manifests/generated/ovm-resource.yaml + +(cd ${KUBEVIRT_DIR}/tools/vms-generator/ && go build) +${KUBEVIRT_DIR}/tools/vms-generator/vms-generator --docker-prefix=$docker_prefix --generated-vms-dir=${KUBEVIRT_DIR}/cluster/examples diff --git a/tools/vms-generator/vms-generator.go b/tools/vms-generator/vms-generator.go new file mode 100644 index 000000000000..279785804e63 --- /dev/null +++ b/tools/vms-generator/vms-generator.go @@ -0,0 +1,297 @@ +/* + * This file is part of the KubeVirt project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2018 Red Hat, Inc. + * + */ + +package main + +import ( + "encoding/base64" + "flag" + "fmt" + "io/ioutil" + "path/filepath" + + "github.com/ghodss/yaml" + + k8sv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "kubevirt.io/kubevirt/pkg/api/v1" + "k8s.io/apimachinery/pkg/types" +) + +const ( + vmEphemeral = "vm-ephemeral" + vmFlavorSmall = "vm-flavor-small" + vmSata = "vm-sata" + vmFedora = "vm-fedora" + vmNoCloud = "vm-nocloud" + vmPvc = "vm-pvc" + vmWindows = "vm-windows" +) + +const ( + busVirtio = "virtio" + busSata = "sata" +) + +const ( + imageCirros = "cirros-registry-disk-demo" + imageFedora = "fedora-cloud-registry-disk-demo" +) + +const windowsFirmware = "5d307ca9-b3ef-428c-8861-06e72d69f223" + +var dockerPrefix = "kubevirt" +var dockerTag = "devel" + +func getBaseVm(name string) *v1.VirtualMachine { + gracePeriod := int64(0) + return &v1.VirtualMachine{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "kubevirt.io/v1alpha1", + Kind: "VirtualMachine", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v1.VirtualMachineSpec{ + TerminationGracePeriodSeconds: &gracePeriod, + Domain: v1.DomainSpec{ + Resources: v1.ResourceRequirements{ + Requests: k8sv1.ResourceList{ + k8sv1.ResourceMemory: resource.MustParse("64M"), + }, + }, + }, + }, + } +} + +func addRegistryDisk(vm *v1.VirtualMachine, image string, bus string) *v1.VirtualMachine { + vm.Spec.Domain.Devices = v1.Devices{ + Disks: []v1.Disk{ + { + Name: "registrydisk", + VolumeName: "registryvolume", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: bus, + }, + }, + }, + }, + } + vm.Spec.Volumes = []v1.Volume{ + { + Name: "registryvolume", + VolumeSource: v1.VolumeSource{ + RegistryDisk: &v1.RegistryDiskSource{ + Image: image, + }, + }, + }, + } + return vm +} + +func addNoCloudDisk(vm *v1.VirtualMachine) *v1.VirtualMachine { + vm.Spec.Domain.Devices.Disks = append(vm.Spec.Domain.Devices.Disks, v1.Disk{ + Name: "cloudinitdisk", + VolumeName: "cloudinitvolume", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: busVirtio, + }, + }, + }) + + userData := fmt.Sprint("#!/bin/sh\n\necho 'printed from cloud-init userdata'\n") + vm.Spec.Volumes = append(vm.Spec.Volumes, v1.Volume{ + Name: "cloudinitvolume", + VolumeSource: v1.VolumeSource{ + CloudInitNoCloud: &v1.CloudInitNoCloudSource{ + UserDataBase64: base64.StdEncoding.EncodeToString([]byte(userData)), + }, + }, + }) + return vm +} + +func addEmptyDisk(vm *v1.VirtualMachine, size string) *v1.VirtualMachine { + vm.Spec.Domain.Devices.Disks = append(vm.Spec.Domain.Devices.Disks, v1.Disk{ + Name: "emptydisk", + VolumeName: "emptydiskvolume", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: busVirtio, + }, + }, + }) + + vm.Spec.Volumes = append(vm.Spec.Volumes, v1.Volume{ + Name: "emptydiskvolume", + VolumeSource: v1.VolumeSource{ + EmptyDisk: &v1.EmptyDiskSource{ + Capacity: resource.MustParse(size), + }, + }, + }) + return vm +} + +func addPvcDisk(vm *v1.VirtualMachine, claimName string, bus string) *v1.VirtualMachine { + vm.Spec.Domain.Devices.Disks = append(vm.Spec.Domain.Devices.Disks, v1.Disk{ + Name: "pvcdisk", + VolumeName: "pvcvolume", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: bus, + }, + }, + }) + + vm.Spec.Volumes = append(vm.Spec.Volumes, v1.Volume{ + Name: "pvcvolume", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &k8sv1.PersistentVolumeClaimVolumeSource{ + ClaimName: claimName, + }, + }, + }) + return vm +} + +func getVmEphemeral() *v1.VirtualMachine { + vm := getBaseVm(vmEphemeral) + + addRegistryDisk(vm, fmt.Sprintf("%s/%s:%s", dockerPrefix, imageCirros, dockerTag), busVirtio) + return vm +} + +func getVmSata() *v1.VirtualMachine { + vm := getBaseVm(vmSata) + + addRegistryDisk(vm, fmt.Sprintf("%s/%s:%s", dockerPrefix, imageCirros, dockerTag), busSata) + return vm +} + +func getVmEphemeralFedora() *v1.VirtualMachine { + vm := getBaseVm(vmFedora) + vm.Spec.Domain.Resources.Requests[k8sv1.ResourceMemory] = resource.MustParse("1024M") + + addRegistryDisk(vm, fmt.Sprintf("%s/%s:%s", dockerPrefix, imageFedora, dockerTag), busVirtio) + addNoCloudDisk(vm) + return vm +} + +func getVmNoCloud() *v1.VirtualMachine { + vm := getBaseVm(vmNoCloud) + + addRegistryDisk(vm, fmt.Sprintf("%s/%s:%s", dockerPrefix, imageCirros, dockerTag), busVirtio) + addNoCloudDisk(vm) + addEmptyDisk(vm, "2Gi") + return vm +} + +func getVmFlavorSmall() *v1.VirtualMachine { + vm := getBaseVm(vmFlavorSmall) + vm.ObjectMeta.Labels = map[string]string { + "kubevirt.io/flavor": "small", + } + + addRegistryDisk(vm, fmt.Sprintf("%s/%s:%s", dockerPrefix, imageCirros, dockerTag), busVirtio) + return vm +} + +func getVmPvc() *v1.VirtualMachine { + vm := getBaseVm(vmPvc) + + addPvcDisk(vm,"disk-alpine", busVirtio) + return vm +} + +func getVmWindows() *v1.VirtualMachine { + vm := getBaseVm(vmWindows) + + gracePeriod := int64(0) + spinlocks := uint32(8191) + firmware := types.UID(windowsFirmware) + _false := false + vm.Spec = v1.VirtualMachineSpec{ + TerminationGracePeriodSeconds: &gracePeriod, + Domain: v1.DomainSpec{ + CPU: &v1.CPU{Cores: 2}, + Features: &v1.Features{ + ACPI: v1.FeatureState{}, + APIC: &v1.FeatureAPIC{}, + Hyperv: &v1.FeatureHyperv{ + Relaxed: &v1.FeatureState{}, + VAPIC: &v1.FeatureState{}, + Spinlocks: &v1.FeatureSpinlocks{Retries: &spinlocks}, + }, + }, + Clock: &v1.Clock{ + ClockOffset: v1.ClockOffset{UTC: &v1.ClockOffsetUTC{}}, + Timer: &v1.Timer{ + HPET: &v1.HPETTimer{Enabled: &_false}, + PIT: &v1.PITTimer{TickPolicy: v1.PITTickPolicyDelay}, + RTC: &v1.RTCTimer{TickPolicy: v1.RTCTickPolicyCatchup}, + Hyperv: &v1.HypervTimer{}, + }, + }, + Firmware: &v1.Firmware{UUID: firmware}, + Resources: v1.ResourceRequirements{ + Requests: k8sv1.ResourceList{ + k8sv1.ResourceMemory: resource.MustParse("2048Mi"), + }, + }, + }, + } + + addPvcDisk(vm,"disk-windows", busSata) + return vm +} + +func main() { + flag.StringVar(&dockerPrefix, "docker-prefix", dockerPrefix, "") + flag.StringVar(&dockerTag,"docker-tag", dockerTag, "") + genDir := flag.String("generated-vms-dir", "", "") + flag.Parse() + + var vms = map[string]*v1.VirtualMachine { + vmEphemeral: getVmEphemeral(), + vmFlavorSmall: getVmFlavorSmall(), + vmSata: getVmSata(), + vmFedora: getVmEphemeralFedora(), + vmNoCloud: getVmNoCloud(), + vmPvc: getVmPvc(), + vmWindows: getVmWindows(), + } + for vmName, vm := range vms { + data, err := yaml.Marshal(vm) + if err != nil { + fmt.Errorf("failed to generate yaml for vm %s", vmName) + } + + err = ioutil.WriteFile(filepath.Join(*genDir, fmt.Sprintf("%s.yaml", vmName)), data, 0644) + if err != nil { + fmt.Errorf("failed to write yaml file") + } + } +} diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md index f8f7e369549c..0200f75b4d12 100644 --- a/vendor/github.com/ghodss/yaml/README.md +++ b/vendor/github.com/ghodss/yaml/README.md @@ -4,13 +4,13 @@ ## Introduction -A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. +A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). ## Compatibility -This package uses [go-yaml v2](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). +This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). ## Caveats @@ -44,6 +44,8 @@ import "github.com/ghodss/yaml" Usage is very similar to the JSON library: ```go +package main + import ( "fmt" @@ -51,8 +53,8 @@ import ( ) type Person struct { - Name string `json:"name"` // Affects YAML field names too. - Age int `json:"name"` + Name string `json:"name"` // Affects YAML field names too. + Age int `json:"age"` } func main() { @@ -65,13 +67,13 @@ func main() { } fmt.Println(string(y)) /* Output: - name: John age: 30 + name: John */ // Unmarshal the YAML back into a Person struct. var p2 Person - err := yaml.Unmarshal(y, &p2) + err = yaml.Unmarshal(y, &p2) if err != nil { fmt.Printf("err: %v\n", err) return @@ -86,11 +88,14 @@ func main() { `yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: ```go +package main + import ( "fmt" "github.com/ghodss/yaml" ) + func main() { j := []byte(`{"name": "John", "age": 30}`) y, err := yaml.JSONToYAML(j) diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go index 0bd3c2b46267..58600740266c 100644 --- a/vendor/github.com/ghodss/yaml/fields.go +++ b/vendor/github.com/ghodss/yaml/fields.go @@ -45,7 +45,11 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te break } if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) + if v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } else { + v = reflect.New(v.Type().Elem()) + } } if v.Type().NumMethod() > 0 { if u, ok := v.Interface().(json.Unmarshaler); ok { diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go index c02beacb9a41..4fb4054a8b74 100644 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ b/vendor/github.com/ghodss/yaml/yaml.go @@ -15,12 +15,12 @@ import ( func Marshal(o interface{}) ([]byte, error) { j, err := json.Marshal(o) if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: ", err) + return nil, fmt.Errorf("error marshaling into JSON: %v", err) } y, err := JSONToYAML(j) if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: ", err) + return nil, fmt.Errorf("error converting JSON to YAML: %v", err) } return y, nil @@ -48,7 +48,7 @@ func JSONToYAML(j []byte) ([]byte, error) { var jsonObj interface{} // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshling to interface{}, it just picks float64 + // etc.) when unmarshalling to interface{}, it just picks float64 // universally. go-yaml does go through the effort of picking the right // number type, so we can preserve number type throughout this process. err := yaml.Unmarshal(j, &jsonObj) diff --git a/vendor/github.com/golang/mock/.travis.yml b/vendor/github.com/golang/mock/.travis.yml index e4d50a2f1551..1b89c05f5fcc 100644 --- a/vendor/github.com/golang/mock/.travis.yml +++ b/vendor/github.com/golang/mock/.travis.yml @@ -1,21 +1,10 @@ language: go go: - # this will flag backwards compatibility issues creeping in - - 1.6 - - 1.6.x - # we intend to support only the latest version and perhaps the previous one - - 1.7 - 1.7.x - - 1.8 - 1.8.x - - 1.9 - 1.9.x - -matrix: - allow_failures: - - go: 1.6 - - go: 1.6.x + - 1.10.x script: - go build ./... diff --git a/vendor/github.com/golang/mock/gomock/matchers.go b/vendor/github.com/golang/mock/gomock/matchers.go index e8b1ddccf03b..65ad8bab722d 100644 --- a/vendor/github.com/golang/mock/gomock/matchers.go +++ b/vendor/github.com/golang/mock/gomock/matchers.go @@ -87,6 +87,18 @@ func (n notMatcher) String() string { return "not(" + n.m.String() + ")" } +type assignableToTypeOfMatcher struct { + targetType reflect.Type +} + +func (m assignableToTypeOfMatcher) Matches(x interface{}) bool { + return reflect.TypeOf(x).AssignableTo(m.targetType) +} + +func (m assignableToTypeOfMatcher) String() string { + return "is assignable to " + m.targetType.Name() +} + // Constructors func Any() Matcher { return anyMatcher{} } func Eq(x interface{}) Matcher { return eqMatcher{x} } @@ -97,3 +109,16 @@ func Not(x interface{}) Matcher { } return notMatcher{Eq(x)} } + +// AssignableToTypeOf is a Matcher that matches if the parameter to the mock +// function is assignable to the type of the parameter to this function. +// +// Example usage: +// +// dbMock.EXPECT(). +// Insert(gomock.AssignableToTypeOf(&EmployeeRecord{})). +// Return(errors.New("DB error")) +// +func AssignableToTypeOf(x interface{}) Matcher { + return assignableToTypeOfMatcher{reflect.TypeOf(x)} +} diff --git a/vendor/github.com/golang/mock/mockgen/mockgen.go b/vendor/github.com/golang/mock/mockgen/mockgen.go index 5a88fa8542e0..67481a6428f5 100644 --- a/vendor/github.com/golang/mock/mockgen/mockgen.go +++ b/vendor/github.com/golang/mock/mockgen/mockgen.go @@ -231,7 +231,15 @@ func (g *generator) Generate(pkg *model.Package, pkgName string, outputPackagePa // Get all required imports, and generate unique names for them all. im := pkg.Imports() im[gomockImportPath] = true - im["reflect"] = true + + // Only import reflect if it's used. We only use reflect in mocked methods + // so only import if any of the mocked interfaces have methods. + for _, intf := range pkg.Interfaces { + if len(intf.Methods) > 0 { + im["reflect"] = true + break + } + } // Sort keys to make import alias generation predictable sorted_paths := make([]string, len(im), len(im)) diff --git a/vendor/github.com/golang/mock/mockgen/parse.go b/vendor/github.com/golang/mock/mockgen/parse.go index 794e749d943d..3060c481bf8b 100644 --- a/vendor/github.com/golang/mock/mockgen/parse.go +++ b/vendor/github.com/golang/mock/mockgen/parse.go @@ -444,13 +444,13 @@ func importsOfFile(file *ast.File) map[string]string { pkg, err := build.Import(importPath, "", 0) if err != nil { // Fallback to import path suffix. Note that this is uncertain. - log.Printf("failed to import package by path %s: %s - fallback to import path suffix", importPath, err.Error()) _, last := path.Split(importPath) // If the last path component has dots, the first dot-delimited // field is used as the name. pkgName = strings.SplitN(last, ".", 2)[0] + } else { + pkgName = pkg.Name } - pkgName = pkg.Name } if _, ok := m[pkgName]; ok { diff --git a/vendor/github.com/golang/mock/mockgen/reflect.go b/vendor/github.com/golang/mock/mockgen/reflect.go index b09886797062..915f1331af3f 100644 --- a/vendor/github.com/golang/mock/mockgen/reflect.go +++ b/vendor/github.com/golang/mock/mockgen/reflect.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/gob" "flag" - "io" + "go/build" "io/ioutil" "os" "os/exec" @@ -32,69 +32,27 @@ import ( ) var ( - progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout.") + progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout and exit.") execOnly = flag.String("exec_only", "", "(reflect mode) If set, execute this reflection program.") buildFlags = flag.String("build_flags", "", "(reflect mode) Additional flags for go build.") ) -func Reflect(importPath string, symbols []string) (*model.Package, error) { - // TODO: sanity check arguments - - progPath := *execOnly - if *execOnly == "" { - pwd, _ := os.Getwd() - // We use TempDir instead of TempFile so we can control the filename. - // Try to place the TempDir under pwd, so that if there is some package in - // vendor directory, 'go build' can also load/mock it. - tmpDir, err := ioutil.TempDir(pwd, "gomock_reflect_") - if err != nil { - return nil, err - } - defer func() { os.RemoveAll(tmpDir) }() - const progSource = "prog.go" - var progBinary = "prog.bin" - if runtime.GOOS == "windows" { - // Windows won't execute a program unless it has a ".exe" suffix. - progBinary += ".exe" - } - - // Generate program. - var program bytes.Buffer - data := reflectData{ - ImportPath: importPath, - Symbols: symbols, - } - if err := reflectProgram.Execute(&program, &data); err != nil { - return nil, err - } - if *progOnly { - io.Copy(os.Stdout, &program) - os.Exit(0) - } - if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program.Bytes(), 0600); err != nil { - return nil, err - } - - cmdArgs := []string{} - cmdArgs = append(cmdArgs, "build") - if *buildFlags != "" { - cmdArgs = append(cmdArgs, *buildFlags) - } - cmdArgs = append(cmdArgs, "-o", progBinary, progSource) - - // Build the program. - cmd := exec.Command("go", cmdArgs...) - cmd.Dir = tmpDir - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return nil, err - } - progPath = filepath.Join(tmpDir, progBinary) +func writeProgram(importPath string, symbols []string) ([]byte, error) { + var program bytes.Buffer + data := reflectData{ + ImportPath: importPath, + Symbols: symbols, + } + if err := reflectProgram.Execute(&program, &data); err != nil { + return nil, err } + return program.Bytes(), nil +} - // Run it. - cmd := exec.Command(progPath) +// run the given command and parse the output as a model.Package. +func run(command string) (*model.Package, error) { + // Run the program. + cmd := exec.Command(command) var stdout bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = os.Stderr @@ -110,6 +68,79 @@ func Reflect(importPath string, symbols []string) (*model.Package, error) { return &pkg, nil } +// runInDir writes the given program into the given dir, runs it there, and +// parses the output as a model.Package. +func runInDir(program []byte, dir string) (*model.Package, error) { + // We use TempDir instead of TempFile so we can control the filename. + tmpDir, err := ioutil.TempDir(dir, "gomock_reflect_") + if err != nil { + return nil, err + } + defer func() { os.RemoveAll(tmpDir) }() + const progSource = "prog.go" + var progBinary = "prog.bin" + if runtime.GOOS == "windows" { + // Windows won't execute a program unless it has a ".exe" suffix. + progBinary += ".exe" + } + + if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program, 0600); err != nil { + return nil, err + } + + cmdArgs := []string{} + cmdArgs = append(cmdArgs, "build") + if *buildFlags != "" { + cmdArgs = append(cmdArgs, *buildFlags) + } + cmdArgs = append(cmdArgs, "-o", progBinary, progSource) + + // Build the program. + cmd := exec.Command("go", cmdArgs...) + cmd.Dir = tmpDir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, err + } + return run(filepath.Join(tmpDir, progBinary)) +} + +func Reflect(importPath string, symbols []string) (*model.Package, error) { + // TODO: sanity check arguments + + if *execOnly != "" { + return run(*execOnly) + } + + program, err := writeProgram(importPath, symbols) + if err != nil { + return nil, err + } + + if *progOnly { + os.Stdout.Write(program) + os.Exit(0) + } + + wd, _ := os.Getwd() + + // Try to run the program in the same directory as the input package. + if p, err := build.Import(importPath, wd, build.FindOnly); err == nil { + dir := p.Dir + if p, err := runInDir(program, dir); err == nil { + return p, nil + } + } + + // Since that didn't work, try to run it in the current working directory. + if p, err := runInDir(program, wd); err == nil { + return p, nil + } + // Since that didn't work, try to run it in a standard temp directory. + return runInDir(program, "") +} + type reflectData struct { ImportPath string Symbols []string diff --git a/vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go b/vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go index 595f679be6db..e751826dac7e 100644 --- a/vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go +++ b/vendor/github.com/golang/mock/mockgen/tests/vendor_dep/doc.go @@ -1,3 +1,4 @@ package vendor_dep //go:generate mockgen -package vendor_dep -destination mock.go github.com/golang/mock/mockgen/tests/vendor_dep VendorsDep +//go:generate mockgen -destination source_mock_package/mock.go -source=vendor_dep.go diff --git a/vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go b/vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go index ee7609a59e18..b5bde11ca5f3 100644 --- a/vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go +++ b/vendor/github.com/golang/mock/mockgen/tests/vendor_pkg/doc.go @@ -1,3 +1,3 @@ package vendor_pkg -//go:generate mockgen a Ifc +//go:generate mockgen -destination mock.go -package vendor_pkg a Ifc diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index e4e0c9448b68..e7f67797b17a 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -285,10 +285,10 @@ func (f *FlagSet) HasFlags() bool { } // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags -// definied that are not hidden or deprecated. +// that are not hidden. func (f *FlagSet) HasAvailableFlags() bool { for _, flag := range f.formal { - if !flag.Hidden && len(flag.Deprecated) == 0 { + if !flag.Hidden { return true } } @@ -398,6 +398,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error { return fmt.Errorf("deprecated message for flag %q must be set", name) } flag.Deprecated = usageMessage + flag.Hidden = true return nil } @@ -668,7 +669,7 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string { maxlen := 0 f.VisitAll(func(flag *Flag) { - if flag.Deprecated != "" || flag.Hidden { + if flag.Hidden { return } @@ -715,6 +716,9 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string { line += fmt.Sprintf(" (default %s)", flag.DefValue) } } + if len(flag.Deprecated) != 0 { + line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated) + } lines = append(lines, line) })