Skip to content

Commit 5087718

Browse files
authored
Merge pull request #870 from Mirantis/ivan4th/debian-image-ext-e2e
Add a CircleCI e2e job based on Debian image
2 parents 3bcd031 + 042367c commit 5087718

16 files changed

+151
-22
lines changed

.circleci/config.yml

+31-10
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,23 @@ e2e: &e2e
204204
command: |
205205
build/portforward.sh 8080&
206206
mkdir -p ~/junit
207-
skip_focus=("-ginkgo.skip=\[Heavy\]|\[MultiCNI\]|\[Disruptive\]|\[Flaky\]")
207+
e2e_opts=("-ginkgo.skip=\[Heavy\]|\[MultiCNI\]|\[Disruptive\]|\[Flaky\]")
208208
if [[ ${CIRCLE_JOB} = e2e_multi_cni ]]; then
209209
# per-node config test requires an additional worker node
210-
skip_focus="-ginkgo.skip=\[Heavy\]|\[Disruptive\]|\[Flaky\]|Per-node configuration"
210+
e2e_opts="-ginkgo.skip=\[Heavy\]|\[Disruptive\]|\[Flaky\]|Per-node configuration"
211211
fi
212212
if [[ ${E2E_FOCUS:-} ]]; then
213-
skip_focus+=("-ginkgo.focus=${E2E_FOCUS}")
213+
e2e_opts+=("-ginkgo.focus=${E2E_FOCUS}")
214214
fi
215-
_output/virtlet-e2e-tests -test.v "${skip_focus[@]}" -junitOutput ~/junit/junit.xml -include-unsafe-tests=true
215+
if [[ ${CIRCLE_JOB} = e2e_debian ]]; then
216+
e2e_opts+=(-image cdimage.debian.org/cdimage/openstack/archive/9.8.0/debian-9.8.0-openstack-amd64.qcow2
217+
-sshuser debian
218+
-memoryLimit 256
219+
-use-dhcp-network-config)
220+
fi
221+
_output/virtlet-e2e-tests -test.v "${e2e_opts[@]}" \
222+
-junitOutput ~/junit/junit.xml \
223+
-include-unsafe-tests=true
216224
217225
- store_test_results:
218226
path: ~/junit
@@ -394,6 +402,9 @@ jobs:
394402
e2e_1_12:
395403
<<: *e2e
396404

405+
e2e_debian:
406+
<<: *e2e
407+
397408
push_branch:
398409
<<: *push_images
399410

@@ -518,20 +529,29 @@ workflows:
518529
only: /^master$|^.*-net$/
519530
tags:
520531
only: /^v[0-9].*/
521-
- e2e_multi_cni:
532+
# XXX: temporarily disabled, to be fixed
533+
# - e2e_multi_cni:
534+
# requires:
535+
# - build
536+
# filters:
537+
# branches:
538+
# only: /^master$|^.*-net$|^.*-ext-e2e$/
539+
# tags:
540+
# only: /^v[0-9].*/
541+
- e2e_1_12:
522542
requires:
523543
- build
524544
filters:
525545
branches:
526-
only: /^master$|^.*-net$/
546+
ignore: /^.*-docs$/
527547
tags:
528548
only: /^v[0-9].*/
529-
- e2e_1_12:
549+
- e2e_debian:
530550
requires:
531551
- build
532552
filters:
533553
branches:
534-
ignore: /^.*-docs$/
554+
only: /^master$|^.*-ext-e2e$/
535555
tags:
536556
only: /^v[0-9].*/
537557
- push_branch:
@@ -547,8 +567,10 @@ workflows:
547567
- e2e_calico
548568
- e2e_flannel
549569
- e2e_weave
550-
- e2e_multi_cni
570+
# XXX: temporarily disabled, to be fixed
571+
# - e2e_multi_cni
551572
- e2e_1_12
573+
- e2e_debian
552574
- integration
553575
filters:
554576
branches:
@@ -566,4 +588,3 @@ workflows:
566588
- build_docs:
567589
requires:
568590
- prepare_build
569-

docs/docs/dev/virtlet-ci.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ account.
1010
There are some conventions about branch naming that are respected by
1111
CircleCI. Namely, branches with names ending with `-net` will be
1212
checked with extra e2e jobs that examine Weave, Flannel and multi-CNI
13-
based network setups. For branches with names ending with `-docs` only
14-
documentation will be built.
13+
based network setups. For branches with names ending with `-ext-e2e`,
14+
all the jobs that are run for `-net` branches are run, as well as an
15+
additional job that verifies Virtlet against a Debian OpenStack image.
16+
For branches with names ending with `-docs` only documentation will be
17+
built. For `master` branch, the same policy is used as for `-ext-e2e`
18+
branches.
1519

1620
Also, you can append `[ci skip]` to your commit message to have CI
1721
skip the particular commit/PR altogether.

docs/docs/reference/cloud-init.md

+15
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,21 @@ use the following construct in the pod annotations:
344344
VirtletCloudInitUserDataScript: "@virtlet-mount-script@"
345345
```
346346

347+
# Disabling cloud-init based network configuration
348+
349+
As the network configuration is applied only upon the first startup,
350+
it's not used when
351+
[persistent root filesystem](../volumes/#persistent-root-filesystem)
352+
is used, so new network configuration can be passed using DHCP to a
353+
new pod with the same rootfs. Moreover, in some cases it may be
354+
desirable to force Virtlet to use DHCP instead of cloud-init based
355+
network config. To do so, you need to add the following annotation
356+
to the pod:
357+
358+
```yaml
359+
VirtletForceDHCPNetworkConfig: "true"
360+
```
361+
347362
# Additional links
348363

349364
These links may help to understand some basics about cloud-init:

examples/debian-vm.yaml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: debian-vm
5+
annotations:
6+
kubernetes.io/target-runtime: virtlet.cloud
7+
VirtletSSHKeys: |
8+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaJEcFDXEK2ZbX0ZLS1EIYFZRbDAcRfuVjpstSc0De8+sV1aiu+dePxdkuDRwqFtCyk6dEZkssjOkBXtri00MECLkir6FcH3kKOJtbJ6vy3uaJc9w1ERo+wyl6SkAh/+JTJkp7QRXj8oylW5E20LsbnA/dIwWzAF51PPwF7A7FtNg9DnwPqMkxFo1Th/buOMKbP5ZA1mmNNtmzbMpMfJATvVyiv3ccsSJKOiyQr6UG+j7sc/7jMVz5Xk34Vd0l8GwcB0334MchHckmqDB142h/NCWTr8oLakDNvkfC1YneAfAO41hDkUbxPtVBG5M/o7P4fxoqiHEX+ZLfRxDtHB53 me@localhost
9+
# set root volume size
10+
VirtletRootVolumeSize: 4Gi
11+
# Debian image doesn't understand Virtlet's Cloud-Init network config currently
12+
VirtletForceDHCPNetworkConfig: "true"
13+
spec:
14+
nodeSelector:
15+
extraRuntime: virtlet
16+
17+
# This is the number of seconds Virtlet gives the VM to shut down cleanly.
18+
# The default value of 30 seconds is ok for containers but probably too
19+
# low for VM, so overriding it here is strongly advised.
20+
terminationGracePeriodSeconds: 120
21+
containers:
22+
- name: debian-vm
23+
# We use an 'archive' image so as to have a stable URL
24+
image: virtlet.cloud/cdimage.debian.org/cdimage/openstack/archive/9.8.0/debian-9.8.0-openstack-amd64.qcow2
25+
imagePullPolicy: IfNotPresent
26+
# tty and stdin required for `kubectl attach -t` to work
27+
tty: true
28+
stdin: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
meta-data:
2+
instance-id: foo.default
3+
local-hostname: foo
4+
network-config: null
5+
user-data: null

pkg/libvirttools/TestContainerLifecycle.out.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
CPUModel: ""
116116
CPUSetting: null
117117
DiskDriver: scsi
118+
ForceDHCPNetworkConfig: false
118119
InjectedFiles: null
119120
MetaData: null
120121
RootVolumeSize: 0
@@ -173,6 +174,7 @@
173174
CPUModel: ""
174175
CPUSetting: null
175176
DiskDriver: scsi
177+
ForceDHCPNetworkConfig: false
176178
InjectedFiles: null
177179
MetaData: null
178180
RootVolumeSize: 0
@@ -226,6 +228,7 @@
226228
CPUModel: ""
227229
CPUSetting: null
228230
DiskDriver: scsi
231+
ForceDHCPNetworkConfig: false
229232
InjectedFiles: null
230233
MetaData: null
231234
RootVolumeSize: 0

pkg/libvirttools/TestDomainForcedShutdown.out.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
CPUModel: ""
132132
CPUSetting: null
133133
DiskDriver: scsi
134+
ForceDHCPNetworkConfig: false
134135
InjectedFiles: null
135136
MetaData: null
136137
RootVolumeSize: 0

pkg/libvirttools/cloudinit.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,11 @@ func (g *CloudInitGenerator) generateUserData(volumeMap diskPathMap) ([]byte, er
177177
}
178178

179179
func (g *CloudInitGenerator) generateNetworkConfiguration() ([]byte, error) {
180-
if g.config.RootVolumeDevice() != nil {
181-
// We don't use network config with persistent rootfs
182-
// for now because with some cloud-init
180+
if g.config.ParsedAnnotations.ForceDHCPNetworkConfig || g.config.RootVolumeDevice() != nil {
181+
// Don't use cloud-init network config if asked not
182+
// to do so.
183+
// Also, we don't use network config with persistent
184+
// rootfs for now because with some cloud-init
183185
// implementations it's applied only once
184186
return nil, nil
185187
}

pkg/libvirttools/cloudinit_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,18 @@ func TestCloudInitGenerator(t *testing.T) {
388388
// make sure network config is null for the persistent rootfs case
389389
verifyNetworkConfig: true,
390390
},
391+
{
392+
name: "pod with forced dhcp network config",
393+
config: &types.VMConfig{
394+
PodName: "foo",
395+
PodNamespace: "default",
396+
ParsedAnnotations: &types.VirtletAnnotations{ForceDHCPNetworkConfig: true},
397+
},
398+
verifyMetaData: true,
399+
verifyUserData: true,
400+
// make sure network config is null
401+
verifyNetworkConfig: true,
402+
},
391403
{
392404
name: "injecting mount script into user data script",
393405
config: &types.VMConfig{

pkg/metadata/types/annotations.go

+13
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
sshKeysKeyName = "VirtletSSHKeys"
4646
chown9pfsMountsKeyName = "VirtletChown9pfsMounts"
4747
systemUUIDKeyName = "VirtletSystemUUID"
48+
forceDHCPNetworkConfigKeyName = "VirtletForceDHCPNetworkConfig"
4849
// CloudInitUserDataSourceKeyName is the name of user data source key in the pod annotations.
4950
CloudInitUserDataSourceKeyName = "VirtletCloudInitUserDataSource"
5051
// SSHKeySourceKeyName is the name of ssh key source key in the pod annotations.
@@ -119,6 +120,10 @@ type VirtletAnnotations struct {
119120
// SystemUUID specifies fixed SMBIOS UUID to be used for the domain.
120121
// If not set, the SMBIOS UUID will be automatically generated from the Pod ID.
121122
SystemUUID *uuid.UUID
123+
// ForceDHCPNetworkConfig prevents Virtlet from using Cloud-Init based network
124+
// configuration and makes it only provide DHCP. Note that this will
125+
// not work for multi-CNI configuration.
126+
ForceDHCPNetworkConfig bool
122127
}
123128

124129
// ExternalDataLoader is used to load extra pod data from
@@ -318,5 +323,13 @@ func (va *VirtletAnnotations) parsePodAnnotations(ns string, podAnnotations map[
318323
}
319324
}
320325

326+
if podAnnotations[chown9pfsMountsKeyName] == "true" {
327+
va.VirtletChown9pfsMounts = true
328+
}
329+
330+
if podAnnotations[forceDHCPNetworkConfigKeyName] == "true" {
331+
va.ForceDHCPNetworkConfig = true
332+
}
333+
321334
return nil
322335
}

pkg/metadata/types/annotations_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@ func TestVirtletAnnotations(t *testing.T) {
163163
CDImageType: "nocloud",
164164
},
165165
},
166+
{
167+
name: "force DHCP network config",
168+
annotations: map[string]string{
169+
"VirtletForceDHCPNetworkConfig": "true",
170+
},
171+
va: &VirtletAnnotations{
172+
VCPUCount: 1,
173+
DiskDriver: "scsi",
174+
CDImageType: "nocloud",
175+
ForceDHCPNetworkConfig: true,
176+
},
177+
},
166178
// bad metadata items follow
167179
{
168180
name: "bad vcpu count",

tests/e2e/basic_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ func itShouldHaveNetworkConnectivity(podIface func() *framework.PodInterface, ss
227227

228228
It("Should be able to access another k8s endpoint"+suffix, func(done Done) {
229229
defer close(done)
230-
cmd := fmt.Sprintf("curl -s --connect-timeout 5 http://nginx.%s.svc.cluster.local", controller.Namespace())
230+
// wget is present in CirrOS, Ubuntu and Debian images that we use, unlike curl,
231+
// so we use it here
232+
cmd := fmt.Sprintf("wget -O - -T 5 http://nginx.%s.svc.cluster.local", controller.Namespace())
231233
Eventually(func() (string, error) {
232234
return framework.RunSimple(ssh(), cmd)
233235
}, 60).Should(ContainSubstring("Thank you for using nginx."))

tests/e2e/common.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ import (
3838
const (
3939
cephContainerName = "ceph_cluster"
4040
// avoid having the loop device on top of overlay2/aufs when using k-d-c
41-
loopDeviceTestDir = "/dind/virtlet-e2e-tests"
41+
loopDeviceTestDir = "/dind/virtlet-e2e-test-dir"
42+
// The path to mkfs.ext2 may differ between the OSes. Also, on
43+
// CirrOS, mkfs.ext2 is not under the default PATH when we do
44+
// 'ssh sudo ...'
45+
mkfsCommand = `export PATH="/usr/sbin:/sbin:$PATH"; sudo mkfs.ext2 %q`
4246
)
4347

4448
var (
@@ -356,7 +360,7 @@ func makeVMWithMountAndSymlinkScript(nodeName string, PVCs []framework.PVCSpec,
356360

357361
func expectToBeUsableForFilesystem(ssh framework.Executor, devPath string) {
358362
Eventually(func() error {
359-
_, err := framework.RunSimple(ssh, fmt.Sprintf("sudo /usr/sbin/mkfs.ext2 %s", devPath))
363+
_, err := framework.RunSimple(ssh, fmt.Sprintf(mkfsCommand, devPath))
360364
return err
361365
}, 60*5, 3).Should(Succeed())
362366
do(framework.RunSimple(ssh, fmt.Sprintf("sudo mount %s /mnt", devPath)))

tests/e2e/framework/vm_interface.go

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package framework
1818

1919
import (
2020
"encoding/xml"
21+
"flag"
2122
"fmt"
2223
"regexp"
2324
"strconv"
@@ -29,6 +30,8 @@ import (
2930
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3031
)
3132

33+
var useDHCPNetworkConfig = flag.Bool("use-dhcp-network-config", false, "use DHCP network config instead of Cloud-Init-based one")
34+
3235
// VMInterface provides API to work with virtlet VM pods
3336
type VMInterface struct {
3437
controller *Controller
@@ -190,6 +193,10 @@ func (vmi *VMInterface) buildVMPod(options VMOptions) *v1.Pod {
190193
"VirtletDiskDriver": options.DiskDriver,
191194
"VirtletCloudInitUserDataOverwrite": strconv.FormatBool(options.OverwriteUserData),
192195
}
196+
if *useDHCPNetworkConfig {
197+
annotations["VirtletForceDHCPNetworkConfig"] = "true"
198+
}
199+
193200
if options.SSHKey != "" {
194201
annotations["VirtletSSHKeys"] = options.SSHKey
195202
}

tests/e2e/virtletctl_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ var _ = Describe("virtletctl", func() {
6767
_, err := controller.ConfigMaps().Create(cm)
6868
Expect(err).NotTo(HaveOccurred())
6969

70-
vm = controller.VM("virtletctl-cirros-vm")
70+
vm = controller.VM("virtletctl-test-vm")
7171
Expect(vm.CreateAndWait(VMOptions{
7272
SSHKeySource: "configmap/sshkey",
7373
}.ApplyDefaults(), time.Minute*5, nil)).To(Succeed())
@@ -99,8 +99,8 @@ var _ = Describe("virtletctl", func() {
9999
defer closeFunc()
100100
localExecutor := framework.LocalExecutor(ctx)
101101

102-
output := callVirtletctl(localExecutor, "ssh", "--namespace", controller.Namespace(), "cirros@virtletctl-cirros-vm", "--", "-i", tempfileName, "hostname")
103-
Expect(output).To(Equal("virtletctl-cirros-vm"))
102+
output := callVirtletctl(localExecutor, "ssh", "--namespace", controller.Namespace(), *sshUser+"@virtletctl-test-vm", "--", "-i", tempfileName, "hostname")
103+
Expect(output).To(Equal("virtletctl-test-vm"))
104104
}, 60)
105105

106106
It("Should dump Virtlet diagnostics on diag dump subcommand", func(done Done) {

tests/e2e/volume_mount_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,5 +243,5 @@ func addFlexvolMount(pod *framework.PodInterface, name string, mountPath string,
243243
func shouldBeMounted(ssh framework.Executor, path string) {
244244
Eventually(func() (string, error) {
245245
return framework.RunSimple(ssh, "ls -l "+path)
246-
}, 60).Should(ContainSubstring("lost+found"))
246+
}, 180, 5).Should(ContainSubstring("lost+found"))
247247
}

0 commit comments

Comments
 (0)