Example #1
0
def run_test_within_pod(test_path: str,
                        with_pv_at: Optional[str] = None,
                        new_namespace: bool = False):
    """
    run selected test from within an openshift pod

    :param test_path: relative path to the test
    :param with_pv_at: path to PV within the pod
    :param new_namespace: create new namespace and pass it via env var
    """
    config.load_kube_config()
    configuration = client.Configuration()
    assert configuration.api_key
    api = client.CoreV1Api(client.ApiClient(configuration))

    pod_name = f"test-orchestrator-{get_timestamp_now()}"

    cont_cmd = [
        "bash",
        "-c",
        "ls -lha "
        f"&& pytest-3 -vv -l -p no:cacheprovider {test_path}",
    ]

    container: Dict[str, Any] = {
        "image": TEST_IMAGE_NAME,
        "name": pod_name,
        "tty": True,  # corols
        "command": cont_cmd,
        "imagePullPolicy": "Never",
        "env": [],
    }

    test_namespace = None
    if new_namespace:
        test_namespace = f"sandcastle-tests-{get_timestamp_now()}"
        c = ["oc", "new-project", test_namespace]
        run_command(c)
        c = [
            "oc",
            "adm",
            "-n",
            test_namespace,
            "policy",
            "add-role-to-user",
            "edit",
            f"system:serviceaccount:{NAMESPACE}:default",
        ]
        run_command(c)
        container["env"] += [{
            "name": "SANDCASTLE_TESTS_NAMESPACE",
            "value": test_namespace
        }]

    spec = {"containers": [container], "restartPolicy": "Never"}

    pod_manifest = {
        "apiVersion": "v1",
        "kind": "Pod",
        "metadata": {
            "name": pod_name
        },
        "spec": spec,
    }
    if with_pv_at:
        cleaned_test_name = clean_string(test_path)
        ts = get_timestamp_now()
        volume_name = f"{cleaned_test_name}-{ts}-vol"[-63:]
        claim_name = f"{cleaned_test_name}-{ts}-pvc"[-63:]
        container["env"] = [{"name": "SANDCASTLE_PVC", "value": claim_name}]
        pvc_dict = {
            "kind": "PersistentVolumeClaim",
            "spec": {
                "accessModes": ["ReadWriteMany"],
                "resources": {
                    "requests": {
                        "storage": "1Gi"
                    }
                },
            },
            "apiVersion": "v1",
            "metadata": {
                "name": claim_name
            },
        }
        api.create_namespaced_persistent_volume_claim(NAMESPACE, pvc_dict)
        container["volumeMounts"] = [{
            "mountPath": with_pv_at,
            "name": volume_name
        }]
        spec["volumes"] = [{
            "name": volume_name,
            "persistentVolumeClaim": {
                "claimName": claim_name
            }
        }]
    try:
        api.delete_namespaced_pod(pod_name, NAMESPACE, body=V1DeleteOptions())
    except ApiException as ex:
        if ex.status != 404:
            raise

    try:
        api.create_namespaced_pod(body=pod_manifest, namespace=NAMESPACE)
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not start on time.")
            info = api.read_namespaced_pod(pod_name, NAMESPACE)
            if info.status.phase == "Running":
                break
            time.sleep(2.0)
            counter -= 1
        print(
            api.read_namespaced_pod_log(name=pod_name,
                                        namespace=NAMESPACE,
                                        follow=True))
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not finish on time.")
            info = api.read_namespaced_pod(pod_name, NAMESPACE)
            if info.status.phase == "Succeeded":
                break
            if info.status.phase == "Failed":
                raise RuntimeError("Test failed")
            time.sleep(2.0)
            counter -= 1
    finally:
        print(
            api.read_namespaced_pod_log(name=pod_name,
                                        namespace=NAMESPACE,
                                        follow=True))
        api.delete_namespaced_pod(pod_name, NAMESPACE, body=V1DeleteOptions())
        if new_namespace:
            run_command(["oc", "delete", "project", test_namespace])
        if with_pv_at:
            api.delete_namespaced_persistent_volume_claim(
                name=claim_name, namespace=NAMESPACE, body=V1DeleteOptions())
Example #2
0
def run_test_within_pod(test_path: str, with_pv_at: Optional[str] = None):
    """
    run selected test from within an openshift pod

    :param test_path: relative path to the test
    :param with_pv_at: path to PV within the pod
    """
    config.load_kube_config()
    configuration = client.Configuration()
    assert configuration.api_key
    api = client.CoreV1Api(client.ApiClient(configuration))

    container = {
        "image":
        TEST_IMAGE_NAME,
        "name":
        POD_NAME,
        "tty":
        True,  # corols
        "command": [
            "bash",
            "-c",
            "ls -lha "
            "&& id "
            "&& pytest-3 --collect-only"
            f"&& pytest-3 -vv -l -p no:cacheprovider {test_path}",
        ],
        "imagePullPolicy":
        "Never",
    }

    spec = {"containers": [container], "restartPolicy": "Never"}

    pod_manifest = {
        "apiVersion": "v1",
        "kind": "Pod",
        "metadata": {
            "name": POD_NAME
        },
        "spec": spec,
    }
    if with_pv_at:
        cleaned_test_name = clean_string(test_path)
        ts = get_timestamp_now()
        volume_name = f"{cleaned_test_name}-{ts}-vol"[-63:]
        claim_name = f"{cleaned_test_name}-{ts}-pvc"[-63:]
        container["env"] = [{"name": "SANDCASTLE_PVC", "value": claim_name}]
        pvc_dict = {
            "kind": "PersistentVolumeClaim",
            "spec": {
                "accessModes": ["ReadWriteMany"],
                "resources": {
                    "requests": {
                        "storage": "1Gi"
                    }
                },
            },
            "apiVersion": "v1",
            "metadata": {
                "name": claim_name
            },
        }
        api.create_namespaced_persistent_volume_claim(NAMESPACE, pvc_dict)
        container["volumeMounts"] = [{
            "mountPath": with_pv_at,
            "name": volume_name
        }]
        spec["volumes"] = [{
            "name": volume_name,
            "persistentVolumeClaim": {
                "claimName": claim_name
            }
        }]
    try:
        api.delete_namespaced_pod(POD_NAME, NAMESPACE, body=V1DeleteOptions())
    except ApiException as ex:
        if ex.status != 404:
            raise

    try:
        api.create_namespaced_pod(body=pod_manifest, namespace=NAMESPACE)
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not start on time.")
            info = api.read_namespaced_pod(POD_NAME, NAMESPACE)
            if info.status.phase == "Running":
                break
            time.sleep(2.0)
            counter -= 1
        print(
            api.read_namespaced_pod_log(name=POD_NAME,
                                        namespace=NAMESPACE,
                                        follow=True))
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not finish on time.")
            info = api.read_namespaced_pod(POD_NAME, NAMESPACE)
            if info.status.phase == "Succeeded":
                break
            if info.status.phase == "Failed":
                raise RuntimeError("Test failed")
            time.sleep(2.0)
            counter -= 1
    finally:
        print(
            api.read_namespaced_pod_log(name=POD_NAME,
                                        namespace=NAMESPACE,
                                        follow=True))
        api.delete_namespaced_pod(POD_NAME, NAMESPACE, body=V1DeleteOptions())
        if with_pv_at:
            api.delete_namespaced_persistent_volume_claim(
                name=claim_name, namespace=NAMESPACE, body=V1DeleteOptions())
Example #3
0
def run_test_within_pod(test_path: str,
                        with_pv_at: Optional[str] = None,
                        new_namespace: bool = False):
    """
    run selected test from within an openshift pod

    :param test_path: relative path to the test
    :param with_pv_at: path to PV within the pod
    :param new_namespace: create new namespace and pass it via env var
    """
    # this will connect to the cluster you have active right now - see `oc status`
    current_context = check_output(["oc", "config",
                                    "current-context"]).strip().decode()
    api_client = new_client_from_config(context=current_context)
    api = client.CoreV1Api(api_client)

    # you need this for minishift; or do `eval $(minishift docker-env) && make build`
    # # FIXME: get this from env or cli (`minishift openshift registry`)
    # also it doesn't work for me right now, unable to reach minishift's docker registry
    # registry = "172.30.1.1:5000"
    # openshift_image_name = f"{registry}/myproject/{TEST_IMAGE_BASENAME}"
    # # {'authorization': 'Bearer pRW5rGmqgBREnCeVweLcHbEhXvluvG1cImWfIrxWJ2A'}
    # api_token = list(api_client.configuration.api_key.values())[0].split(" ")[1]
    # check_call(["docker", "login", "-u", "developer", "-p", api_token, registry])
    # check_call(["docker", "tag", TEST_IMAGE_NAME, openshift_image_name])
    # check_call(["docker", "push", openshift_image_name])

    pod_name = f"test-orchestrator-{get_timestamp_now()}"

    cont_cmd = [
        "bash",
        "-c",
        "~/setup_env_in_openshift.sh "
        "&& ls -lha && pwd && id "
        f"&& pytest-3 -vv -l -p no:cacheprovider {test_path}",
    ]

    container: Dict[str, Any] = {
        "image": TEST_IMAGE_NAME,  # make sure this is correct
        "name": pod_name,
        "tty": True,  # corols
        "command": cont_cmd,
        "imagePullPolicy": "Never",
        "env": [],
    }

    user = f"system:serviceaccount:{NAMESPACE}:default"
    enable_user_access_namespace(user, NAMESPACE)
    test_namespace = None
    if new_namespace:
        test_namespace = f"sandcastle-tests-{get_timestamp_now()}"
        c = ["oc", "new-project", test_namespace]
        run_command(c)
        enable_user_access_namespace(user, test_namespace)
        container["env"] += [{
            "name": "SANDCASTLE_TESTS_NAMESPACE",
            "value": test_namespace
        }]

    spec = {"containers": [container], "restartPolicy": "Never"}

    pod_manifest = {
        "apiVersion": "v1",
        "kind": "Pod",
        "metadata": {
            "name": pod_name
        },
        "spec": spec,
    }
    if with_pv_at:
        cleaned_test_name = clean_string(test_path)
        ts = get_timestamp_now()
        volume_name = f"{cleaned_test_name}-{ts}-vol"[-63:]
        claim_name = f"{cleaned_test_name}-{ts}-pvc"[-63:]
        container["env"] = [{"name": "SANDCASTLE_PVC", "value": claim_name}]
        pvc_dict = {
            "kind": "PersistentVolumeClaim",
            "spec": {
                "accessModes": ["ReadWriteMany"],
                "resources": {
                    "requests": {
                        "storage": "1Gi"
                    }
                },
            },
            "apiVersion": "v1",
            "metadata": {
                "name": claim_name
            },
        }
        api.create_namespaced_persistent_volume_claim(NAMESPACE, pvc_dict)
        container["volumeMounts"] = [{
            "mountPath": with_pv_at,
            "name": volume_name
        }]
        spec["volumes"] = [{
            "name": volume_name,
            "persistentVolumeClaim": {
                "claimName": claim_name
            }
        }]
    try:
        api.delete_namespaced_pod(pod_name, NAMESPACE, body=V1DeleteOptions())
    except ApiException as ex:
        if ex.status != 404:
            raise

    try:
        api.create_namespaced_pod(body=pod_manifest, namespace=NAMESPACE)
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not start on time.")
            info = api.read_namespaced_pod(pod_name, NAMESPACE)
            if info.status.phase == "Running":
                break
            elif info.status.phase == "Failed":
                print_pod_logs(api, pod_name, NAMESPACE)
                raise RuntimeError("The pod failed to start.")
            time.sleep(2.0)
            counter -= 1
        print_pod_logs(api, pod_name, NAMESPACE)
        counter = 15
        while True:
            if counter < 0:
                raise RuntimeError("Pod did not finish on time.")
            info = api.read_namespaced_pod(pod_name, NAMESPACE)
            if info.status.phase == "Succeeded":
                break
            if info.status.phase == "Failed":
                raise RuntimeError("Test failed")
            time.sleep(2.0)
            counter -= 1
    finally:
        print_pod_logs(api, pod_name, NAMESPACE)
        api.delete_namespaced_pod(pod_name, NAMESPACE, body=V1DeleteOptions())
        if new_namespace:
            run_command(["oc", "delete", "project", test_namespace])
        if with_pv_at:
            api.delete_namespaced_persistent_volume_claim(
                name=claim_name, namespace=NAMESPACE, body=V1DeleteOptions())