cockpit/test/verify/check-openshift

509 lines
25 KiB
Python
Executable File

#!/usr/bin/python2
# -*- coding: utf-8 -*-
# This file is part of Cockpit.
#
# Copyright (C) 2015 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
import parent
from testlib import *
import os
import unittest
import time
import sys
from kubelib import *
# NOTE: Both TestOpenshift and TestRegistry are in this single file to
# prevent them from being run concurrently. Both use a 'openshift'
# machine, and we can only run a single one of those at the same time.
def wait_project(machine, project):
i = 0
found = True
while True:
try:
output = machine.execute("oc get projects")
if project not in output:
if not found:
sys.stderr.write(output)
found = True
raise Exception(output)
break
except:
if i > 60:
raise
i = i + 1
time.sleep(2)
@skipImage("Kubernetes not packaged", "debian-stable", "debian-testing", "ubuntu-1604", "ubuntu-stable", "fedora-i386")
@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic")
class TestOpenshift(MachineCase, OpenshiftCommonTests):
provision = {
"machine1": { "address": "10.111.113.1/20" },
"openshift": { "image": "openshift", "forward": { 30000: 30000, 8443: 8443 } }
}
def setUp(self):
super(TestOpenshift, self).setUp()
print "======= done setUp"
self.openshift = self.machines['openshift']
self.openshift.upload(["verify/files/mock-app-openshift.json"], "/tmp")
self.kubeconfig = os.path.join(self.tmpdir, "config")
self.openshift.download("/root/.kube/config", self.kubeconfig)
m = self.machine
m.execute("mkdir -p /home/admin/.kube")
m.upload([self.kubeconfig], "/home/admin/.kube/config")
m.execute("chown -R admin:admin /home/admin/.kube")
wait_project(self.openshift, "marmalade")
# Expect the default container user limitations during testing
self.openshift.execute("oc patch scc restricted -p '{ \"runAsUser\": { \"type\": \"MustRunAsRange\" } }'")
self.browser.wait_timeout(120)
def testConnect(self):
m = self.machine
b = self.browser
# Make sure we can write to kubeconfig
m.execute("chown -R admin:admin /home/admin/.kube")
self.login_and_go("/kubernetes")
b.wait_present("#service-list")
b.wait_in_text("#service-list", "docker-registry")
b.wait_present("a[href='#/volumes']")
b.click("a[href='#/volumes']")
b.wait_present(".pv-listing")
b.wait_in_text(".pv-listing", "No volumes are present")
b.click("a[href='#/']")
b.wait_present("#kubernetes-change-connection")
b.click("#kubernetes-change-connection")
b.wait_present("modal-dialog")
b.wait_present("#kubernetes-cluster")
b.wait_present("#kubernetes-user")
b.wait_not_present("#kubernetes-username")
b.wait_not_present("#kubernetes-password")
b.wait_not_present("#kubernetes-token")
b.wait_in_text("#kubernetes-cluster button", "10-111-112-101:8443")
b.wait_in_text("#kubernetes-user button", "system:admin/10-111-112-101:8443")
b.wait_in_text("modal-dialog", "Client Certificate")
b.click("#kubernetes-user button")
b.click("#kubernetes-user ul li:last-child a")
b.wait_in_text("#kubernetes-user button", "Add New User")
b.wait_not_present("#kubernetes-token")
b.wait_val("#kubernetes-username", "")
b.wait_val("#kubernetes-password", "")
b.set_val("#kubernetes-username", "new-user")
b.set_val("#kubernetes-password", "new-user")
b.click("modal-dialog div.modal-footer button.btn-primary")
b.wait_not_present("modal-dialog")
# scruffy isn't a admin
b.wait_present("#service-list")
b.wait_not_in_text("#service-list", "docker-registry")
b.wait_present("a[href='#/volumes']")
b.click("a[href='#/volumes']")
b.wait_present(".pv-listing")
b.wait_in_text(".pv-listing", "cannot watch all")
b.click("a[href='#/']")
b.wait_present("#kubernetes-change-connection")
b.click("#kubernetes-change-connection")
b.wait_present("modal-dialog")
b.wait_present("#kubernetes-cluster")
b.wait_present("#kubernetes-user")
b.wait_not_present("#kubernetes-username")
b.wait_not_present("#kubernetes-password")
b.wait_present("#kubernetes-token")
b.wait_in_text("#kubernetes-cluster button", "10-111-112-101:8443")
b.wait_in_text("#kubernetes-user button", "new-user/10-111-112-101:8443")
b.wait_not_in_text("modal-dialog", "Client Certificate")
self.assertFalse(b.val("#kubernetes-token") == "")
b.logout()
# Test the saved kube config file
m.execute("rm /home/admin/.kube/config")
m.upload([self.kubeconfig], "/home/admin/.kube/config")
m.execute("chown -R admin:admin /home/admin/.kube")
self.login_and_go("/kubernetes")
b.wait_present("#service-list")
b.wait_in_text("#service-list", "docker-registry")
@unittest.skipIf(True, "Nulecule deploys temporarily removed.")
def testDeployDialog(self):
b = self.browser
m = self.machine
b.wait_timeout(240)
m.execute("systemctl start docker")
# m.execute("docker pull submod/helloapache")
tmpfile = os.path.join(self.tmpdir, "oc")
self.openshift.download("/usr/bin/oc", tmpfile)
m.upload([tmpfile], "/usr/local/bin")
self.login_and_go("/kubernetes")
b.wait_present("#service-list")
b.wait_in_text("#service-list", "registry")
# 1)check atomic version
output = m.execute("atomic -v 2>&1")
self.assertTrue(float(output) >= 1.1)
# 2)check provider is supported
m.execute("mkdir /var/tmp/invalid-app1")
m.execute("""echo -e '
FROM busybox
MAINTAINER cockpit
LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
io.projectatomic.nulecule.providers="kubernetes" \
io.projectatomic.nulecule.specversion=0.0.2 \
io.projectatomic.nulecule.atomicappversion="0.1.11"
' > /var/tmp/invalid-app1/Dockerfile""")
m.execute("docker build -t test/invalid-app1 /var/tmp/invalid-app1")
m.execute("rm -rf /var/tmp/invalid-app1")
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "test/invalid-app1")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.is_visible(".modal-footer .alert")
self.assertEqual(b.text(".modal-footer .alert") ,"No supported providers found.")
b.dialog_cancel("#deploy-app-dialog")
# 3)check atomicappversion is supported
m.execute("mkdir /var/tmp/invalid-app2")
m.execute("""echo -e '
FROM busybox
MAINTAINER cockpit
LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
io.projectatomic.nulecule.providers="kubernetes,openshift" \
io.projectatomic.nulecule.specversion=0.0.2 \
io.projectatomic.nulecule.atomicappversion="0.0.11"
' > /var/tmp/invalid-app2/Dockerfile""")
m.execute("docker build -t test/invalid-app2 /var/tmp/invalid-app2")
m.execute("rm -rf /var/tmp/invalid-app2")
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "test/invalid-app2")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.is_visible(".modal-footer .alert")
self.assertEqual(b.text(".modal-footer .alert") ,"atomicapp version 0.0.11 is not supported.")
b.dialog_cancel("#deploy-app-dialog")
# 5)check for all metadata
m.execute("mkdir /var/tmp/invalid-app4")
m.execute("""echo -e '
FROM busybox
MAINTAINER cockpit
LABEL io.projectatomic.nulecule.providers="kubernetes,openshift"
' > /var/tmp/invalid-app4/Dockerfile""")
m.execute("docker build -t test/invalid-app4 /var/tmp/invalid-app4")
m.execute("rm -rf /var/tmp/invalid-app4")
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "test/invalid-app4")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.is_visible(".modal-footer .alert")
self.assertEqual(b.text(".modal-footer .alert") ,"This image is not a supported Nulecule image")
b.dialog_cancel("#deploy-app-dialog")
# 6)check when atomicapp is not available
m.execute("mkdir /var/tmp/invalid-app5")
m.execute("""echo -e '
FROM busybox
MAINTAINER cockpit
LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
io.projectatomic.nulecule.providers="kubernetes,openshift" \
io.projectatomic.nulecule.specversion=0.0.2 \
io.projectatomic.nulecule.atomicappversion="0.1.11"
' > /var/tmp/invalid-app5/Dockerfile""")
m.execute("docker build -t test/invalid-app5 /var/tmp/invalid-app5")
m.execute("rm -rf /var/tmp/invalid-app5")
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "test/invalid-app5")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.is_visible(".modal-footer .alert")
self.assertEqual(b.text(".modal-footer .alert") ,"Image failed to install.")
b.dialog_cancel("#deploy-app-dialog")
# 7) fail when Unable to pull Nulecule app
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "submod/helloapache1")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.is_visible(".modal-footer .alert")
self.assertEqual(b.text(".modal-footer .alert") ,"Unable to pull Nulecule app image.")
b.dialog_cancel("#deploy-app-dialog")
# 8) check if app can be deployed
b.click("#deploy-app")
b.wait_popup("deploy-app-dialog")
b.set_val("#deploy-app-type", "nulecule")
b.set_val("#deploy-app-nulecule-image", "submod/helloapache:0.1.11")
b.set_val("#deploy-app-namespace", "mynamespace")
b.click("#deploy-app-start")
self.allow_journal_messages('Could not find any image matching "submod/helloapache:0.1.11".')
b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
b.click("#deploy-app-start")
b.wait_popdown("deploy-app-dialog")
b.click("a[href='#/list']")
b.wait_present("#content .details-listing")
b.wait_present(".details-listing tbody[data-id='pods/default/helloapache'] th")
self.assertEqual(b.text(".details-listing tbody[data-id='pods/default/helloapache'] th"), "helloapache")
def testReconnectChangeCert(self):
m = self.machine
b = self.browser
# Try to connect with an old and non-matching client cert
old_cert = ('LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lCQnpBTkJna3Foa2'
'lHOXcwQkFRc0ZBREFtTVNRd0lnWURWUVFEREJ0dmNHVnUKYzJocFpuUXRjMmxuYm1WeVFERTBPVEEy'
'T0RFMk16RXdIaGNOTVRjd016STRNRFl4TXpVeVdoY05NVGt3TXpJNApNRFl4TXpVeldqQTNNUjR3SE'
'FZRFZRUUtFeFZ6ZVhOMFpXMDZZMngxYzNSbGNpMWhaRzFwYm5NeEZUQVRCZ05WCkJBTVRESE41YzNS'
'bGJUcGhaRzFwYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUIKQU5Rel'
'J5SzUzQUhmdlZnME5GTHRSSENhMTEyK3l5a0xXdG14bjAxb2JTMy85VmovQU1UdmZwNVRkUlhKNjF'
'WcAo3L0N1L1pkQ3RDc1pyNnJpYVMxbUJGcmtTSkZJdmFjN2NNa3k2M0tVVXNaQmU5ZGFLdG1OMmhY'
'TUt0VitESStvCjJFQVJNWlV5YTZIMzJXZUpzRGM0L1lscUR5TFAxYVR3NWNwRTJPY3dWQTdoQ1dCS'
'ysyajIvZTl6RDhrYzM2R24KNG0wZWd3YWxlZ2UwTXFaUk1BbTFkenRpS3I1UWZ4MG9ZVUY3Z0JIYm'
'RjM253cGZ6a3M2K1F4Tkl6V0hlRmN2WApxcXpsMGxnT2ZGeWc0VWptYzhFcTBiKy9ER3lYSGlHNXN'
'vVmw1RGlVa1RKRjNrcURCZVVjZWNZaEx1VDd4emxzClk0bldYVFprc3lJMXVoZFJmS2NnbVZjQ0F3'
'RUFBYU0xTURNd0RnWURWUjBQQVFIL0JBUURBZ1dnTUJNR0ExVWQKSlFRTU1Bb0dDQ3NHQVFVRkJ3T'
'UNNQXdHQTFVZEV3RUIvd1FDTUFBd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRy9rTElnQ2YwK2'
'1MZ1VXcWZjS2NLN0Nmdm9PbS9qL0FUSW1MR0YvSUtvQTRCWGhqMG5EcEszeVd3ZGt4d0hZCmxxUDh'
'xZ1NyQ1FaNkVoSlpMSWtjQWovTUlTUEUvSlJPa3R5TWFTMis4OGhqeGpxdUhucnZ5ODA5ZlJ5QzhF'
'R2kKeVIyRzhtNGJ5MEJrOWhENkVxbDYxb21VU0MzL2ozR3lPUGNZWDJEQjZsU2h4ZlFJVEpqUWNKQ'
'0oyMnNDdlBBOApVeU9EaUgrNllZSVdtVFN5a2kzazk0Q3NOZXlRbERjNzh3a1BseUdrN0p1anFIK2p'
'KaURXSDQ2TXE3TTNaVVArCmowQWxhd3dtdllsRjBVZEIwdGRCenZWR21RbTRudEwwSkhVMGFqRnUy'
'QTYvTjJmT3VrZWI0TDR6elBzSkJFNHIKaUUyNWRJUlAvWHRoM0tjRFYyYkxtMUk9Ci0tLS0tRU5EI'
'ENFUlRJRklDQVRFLS0tLS0K')
old_key = ('LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBMUROSElybmNBZC'
's5V0RRMFV1MUVjSnJYWGI3TEtRdGEyYkdmVFdodExmLzFXUDhBCnhPOStubE4xRmNuclZXbnY4Szc5'
'bDBLMEt4bXZxdUpwTFdZRVd1UklrVWk5cHp0d3lUTHJjcFJTeGtGNzExb3EKMlkzYUZjd3ExWDRNa'
'jZqWVFCRXhsVEpyb2ZmWlo0bXdOemo5aVdvUElzL1ZwUERseWtUWTV6QlVEdUVKWUVyNwphUGI5Nz'
'NNUHlSemZvYWZpYlI2REJxVjZCN1F5cGxFd0NiVjNPMklxdmxCL0hTaGhRWHVBRWR0MXplZkNsL09'
'TCnpyNURFMGpOWWQ0Vnk5ZXFyT1hTV0E1OFhLRGhTT1p6d1NyUnY3OE1iSmNlSWJteWhXWGtPSlNS'
'TWtYZVNvTUYKNVJ4NXhpRXU1UHZIT1d4amlkWmRObVN6SWpXNkYxRjhweUNaVndJREFRQUJBb0lCQ'
'UNxbjNDYlk0YWJteVBNUQpHMnlJRVhmcFNGMnAyc0QzYlYzUlhNcDhzV1hMekJBRndxdlQwTW9XME'
'xSK2tIWHRBN1NJR0tYdFhMWkZSWkMrClRwSTNyYXh2c3o2eE5wNkZUbGpEaVp6UXdBcm1ZdlNaUlg'
'vU0NnTFR0ZENRdEFtMDBUT2Z3UzNTb3R3K0xFK3AKMStoaDVtVlhFby9XNDRWeWYxNjNsRHAwOXBD'
'K3dpS0ZEa2JHVExBdnA1bnFaMnhtZDRyNzhyMi9TZmZ2YUplZQpJSlpwbENMYzMyQkVZaE4yeDRIa'
'HpqQkhOdTJwYkFXS2twUDVjWkZNS3QwSUkrRTN0UUNWMlkrYVZvNTY0TzRGCjZxMmFUUzVxMnRuaW'
'VBTS9uay8zN3hkNUVoNjRpMU8vQTU2YzdoZmxkMDVQMC9PdU9OY2dsaVVYRG44cnFvOUoKdXpFQ1F'
'ORUNnWUVBN0xOeWRQQlhkdEZRZ3NrWG56UlVYM3hhYWFCYU8xYnJYZzVmUnlMVm5DY2thWlRORXlE'
'dAp3eURxSGRUOGtRNXNIcXZ3WDNxNXR1elZBZ3NJUlhvcTZIUGtxRWdLeFZIclhTNzY1OFhLUnR1S'
'GswbE11ZkQxCnVPVVBaTTJYNVR4NXRmTmh1Zlh3dXZqTkdyN0E3ZEw4VUFiY3ZtS2VuSnF2bDNJZX'
'I0cVpkdDBDZ1lFQTVZQncKZ2pNTGJRZStEUzd1QmdsOFVmdGl5YnZCbDdTSEQ4T2RWamVOdzNEZjJ'
'uckltQVdLTVhNTk5GWldwbmhhc0g3Swp1bWtMQWdMNWFEWXJhaFJHN2ZwMGd0YnN0RVE5Uit2dFVp'
'azMxaFNHUS83dFBENU1LaU1jcFpnazhYUXI5UnlFCkVEN285bWFvUEZibnJKbFl5VXNQY0FCN3Y1W'
'FNxaVdqeFZMODI4TUNnWUVBNUhoSk1DcVVvZkZqL3ZsUFBiSnIKQmtlbmxYRGI1NDc4WEtzT3VFRW'
'RZajQ5M1ZOdHB0c1A1RnF1MytDbmNQUTAxRjR1QkZzWFMwUEtUdENMU1ZTawplZjd6WktNMUVrVUN'
'JODJuRFhSU3pKWTFoS3NwemdpUmhjaERWWTlFNEZYQlBTa1EyVWhVOW9RVXBZNGQ5dkRCCjdoVFJt'
'VXJqd2xGa3o0K3RvczdyVmxrQ2dZRUF4RW8vY0V5aVNDV29HblI2Sm5XMGZCWUxuMGxVUWlHb3B3W'
'UQKS3Z1bTUzTkNNd1p6VFByb0FIVkw1T2kzZ2ZoTWNNcHhNRkNwbHBYZXBaQTNQNnFLSS83ajZnaF'
'RPYmRueG56MgpaU0JWM21kOWt1aVdGY0dldVNlQTErMHlJOFhkMXU0RjBqTk1ZM3JZQjR1NDZQbmJ'
'ZNGNzYy9vbDNXNFNXVzZLCkRUcDJoS3NDZ1lCSlpMQys3Uy9zRGVqdkl0MTZ2Q3JzbDJlWlFsb1p0'
'clNoVCtTb0hmR1NPRXZkMXp1NStBL3UKaVVDYyt1SHdUa1c0RVpMTEdBYkUzTG1xSllJcXNkNVpUW'
'UkxWTZ1TGoyV1NGWFZYUXVLanVlTDZJdGttc1dvZgpyMHFtQU93RHdFVDFvRXlNVUJoOTJVMmhxSHR'
'aamlMdkxQdDc5aUhacDNtTnlLVjc5QXY3dVE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=')
m.execute("sed -i '/client-certificate-data:/ s/:.*$/: %s/; /client-key-data:/ s/:.*$/: %s/' /home/admin/.kube/config" % (
old_cert, old_key))
m.execute("chown -R admin:admin /home/admin/.kube")
self.login_and_go("/kubernetes")
b.wait_present(".curtains-ct")
b.wait_visible(".curtains-ct")
b.wait_in_text(".curtains-ct", "Couldn't connect to server")
b.wait_in_text(".curtains-ct", "Unauthorized")
b.wait_present(".curtains-ct #kubernetes-reconnect")
# now provide a good certificate, and reconnect
m.upload([self.kubeconfig], "/home/admin/.kube/config")
m.execute("chown -R admin:admin /home/admin/.kube")
b.click("#kubernetes-reconnect")
b.wait_present("#service-list")
def bootstrapKubevirt(self):
o = self.openshift
o.execute("/root/nested-kvm") # not enabled by default; for troubleshooting use "virt-host-validate qemu"
o.execute("(cat /sys/module/kvm_intel/parameters/nested || cat /sys/module/kvm_amd/parameters/nested) | grep -q Y")
o.execute("oc project kube-system")
o.execute("oc create serviceaccount -n kube-system kubevirt")
o.execute("oc adm policy add-scc-to-user privileged -n kube-system -z kubevirt")
o.execute("oc adm policy add-scc-to-user privileged -n kube-system -z kubevirt-admin")
o.execute("oc adm policy add-scc-to-user privileged -n kube-system -z default")
o.execute("oc apply -f /kubevirt/kubevirt.yaml") # finalize installation of kubevirt
wait(lambda: "Running" in o.execute("oc get pods | grep virt-controller"), delay=2) # is it deployed and up?
wait(lambda: "No resources found" in o.execute("oc get vm 2>&1"), delay=2) # No VM created yet
def testKubevirtEnvironment(self):
self.bootstrapKubevirt()
o = self.openshift
o.execute("oc create -f /kubevirt/iscsi-demo-target.yaml") # disk for test VM
o.execute("oc create -f /kubevirt/vm.yaml") # let's create a VM
wait(lambda: "testvm" in o.execute("oc get vm"), delay=1)
wait(lambda: "virt-launcher-testvm" in o.execute("oc get pods"))
wait(lambda: "Running" in o.execute("oc get pods | grep virt-launcher-testvm"))
def testVirtualMachinesTabPresent(self):
self.bootstrapKubevirt()
b = self.browser
self.login_and_go("/kubernetes")
b.wait_present("#kubernetes-navigation")
self.assertTrue(b.is_present("#vms-menu-link"))
def testVirtualMachinesListed(self):
self.bootstrapKubevirt()
o = self.openshift
# *.yaml files comes from kubevirt distribution, see tarball extraction in bots/images/script/lib/kubevirt.setup
o.execute("oc create -f /kubevirt/iscsi-demo-target.yaml") # disk for test VM
o.execute("oc create -f /kubevirt/vm.yaml") # let's create a VM
wait(lambda: "testvm" in o.execute("oc get vm"), msg='Deployment of virtual machine "testvm" failed.')
b = self.browser
self.login_and_go("/kubernetes")
b.wait_present("#vms-menu-link")
b.click("#vms-menu-link")
b.wait_present("tr[data-row-id='vm-testvm']")
self.assertTrue(b.text("tr[data-row-id='vm-testvm'] th") == 'testvm')
def testVirtualMachineRowExpansion(self):
self.bootstrapKubevirt()
o = self.openshift
o.execute("oc create -f /kubevirt/iscsi-demo-target.yaml") # disk for test VM
o.execute("oc create -f /kubevirt/vm.yaml") # let's create a VM
wait(lambda: "testvm" in o.execute("oc get vm"), msg='Deployment of virtual machine "testvm" failed.')
b = self.browser
self.login_and_go("/kubernetes")
b.wait_present("#vms-menu-link")
b.click("#vms-menu-link")
b.wait_present("tr[data-row-id='vm-testvm']")
b.click("tr[data-row-id='vm-testvm']")
b.wait_present("tr[data-row-id='vm-testvm'] + tr.listing-ct-panel")
self.assertTrue('Node' in b.text("tr[data-row-id='vm-testvm'] + tr.listing-ct-panel"))
def testVirtualMachineLinkToNode(self):
print 'start'
self.bootstrapKubevirt()
print 'kubevirt installed'
o = self.openshift
o.execute("oc create -f /kubevirt/iscsi-demo-target.yaml") # disk for test VM
o.execute("oc create -f /kubevirt/vm.yaml") # let's create a VM
wait(lambda: "testvm" in o.execute("oc get vm"), msg='Deployment of virtual machine "testvm" failed.')
b = self.browser
self.login_and_go("/kubernetes")
b.wait_present("#vms-menu-link")
b.click("#vms-menu-link")
b.wait_present("tr[data-row-id='vm-testvm']")
b.click("tr[data-row-id='vm-testvm']")
b.wait_present("tr[data-row-id='vm-testvm'] + tr.listing-ct-panel .vm-node")
node_not_assigned = '-'
node_name = b.text("tr[data-row-id='vm-testvm'] + tr.listing-ct-panel .vm-node").strip()
if node_name != node_not_assigned:
b.click("tr[data-row-id='vm-testvm'] + tr.listing-ct-panel .vm-node a")
b.wait_js_cond('window.location.hash === "#/nodes/%s"' % (node_name,))
@skipImage("Kubernetes not packaged", "debian-stable", "debian-testing", "ubuntu-1604", "ubuntu-stable", "fedora-i386")
@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic")
class TestRegistry(MachineCase, RegistryTests):
provision = {
"machine1": { "address": "10.111.113.1/20" },
"openshift": { "image": "openshift" }
}
registry_root = "/kubernetes/registry"
def setup_user(self, user, password):
tmpfile = os.path.join(self.tmpdir, "kubeconfig")
self.openshift.execute('printf "{0}\r\n{1}\r\n" | oc login'.format(user, password))
self.openshift.download("/root/.kube/config", tmpfile)
with open(tmpfile, "r") as f:
self.machine.execute("mkdir -p /home/admin/.kube && cat > /home/admin/.kube/config", input=f.read())
def setUp(self):
super(TestRegistry, self).setUp()
self.openshift = self.machines['openshift']
# Sync over the kube config file
tmpfile = os.path.join(self.tmpdir, "config")
self.openshift.download("/root/.kube/config", tmpfile)
with open(tmpfile, "r") as f:
self.machine.execute("mkdir -p /home/admin/.kube && cat > /home/admin/.kube/config", input=f.read())
wait_project(self.openshift, "marmalade")
self.browser.wait_timeout(120)
if __name__ == '__main__':
test_main()