def update_pod_with_init_container(pod, cmd, cmk_img, cmk_img_pol, args): container_template = k8s.get_container_template() container_template["image"] = cmk_img container_template["imagePullPolicy"] = cmk_img_pol container_template["args"][0] = args # Each container name should be distinct within a Pod. container_template["name"] = cmd pod_init_containers_list = [] version = util.parse_version(k8s.get_kubelet_version(None)) if version >= util.parse_version("v1.7.0"): pod["spec"]["initContainers"] = [container_template] else: init_containers_key = "pod.beta.kubernetes.io/init-containers" if init_containers_key in pod["metadata"]["annotations"]: init_containers = \ pod["metadata"]["annotations"][init_containers_key] pod_init_containers_list = json.loads(init_containers) pod_init_containers_list.append(container_template) pod["metadata"]["annotations"][init_containers_key] = \ json.dumps(pod_init_containers_list)
def update_pod_with_init_container(pod, cmd, cmk_img, cmk_img_pol, args): container_template = k8s.get_container_template() container_template["image"] = cmk_img container_template["imagePullPolicy"] = cmk_img_pol container_template["args"][0] = args # Each container name should be distinct within a Pod. container_template["name"] = cmd # Note(balajismaniam): Downward API for spec.nodeName doesn't seem to # work with init-containers. Removing it as a work-around. Needs further # investigation. container_template["env"].pop() pod_init_containers_list = [] version = util.parse_version(k8s.get_kubelet_version(None)) if version >= util.parse_version("v1.7.0"): pod["spec"]["initContainers"] = [container_template] else: init_containers_key = "pod.beta.kubernetes.io/init-containers" if init_containers_key in pod["metadata"]["annotations"]: init_containers = \ pod["metadata"]["annotations"][init_containers_key] pod_init_containers_list = json.loads(init_containers) pod_init_containers_list.append(container_template) pod["metadata"]["annotations"][init_containers_key] = \ json.dumps(pod_init_containers_list)
def cluster_init(host_list, all_hosts, cmd_list, cmk_img, cmk_img_pol, conf_dir, install_dir, num_exclusive_cores, num_shared_cores, pull_secret, serviceaccount, exclusive_mode, shared_mode, namespace): logging.info("Used ServiceAccount: {}".format(serviceaccount)) cmk_node_list = get_cmk_node_list(host_list, all_hosts) logging.debug("CMK node list: {}".format(cmk_node_list)) cmk_cmd_list = [cmd.strip() for cmd in cmd_list.split(',')] logging.debug("CMK command list: {}".format(cmk_cmd_list)) # Check if all the flag values passed are valid. # Check if cmk_cmd_list is valid. valid_cmd_list = ["init", "discover", "install", "reconcile", "nodereport"] for cmk_cmd in cmk_cmd_list: if cmk_cmd not in valid_cmd_list: raise RuntimeError("CMK command should be one of {}" .format(valid_cmd_list)) if "init" in cmk_cmd_list and cmk_cmd_list[0] != "init": raise RuntimeError("init command should be run and listed first.") # Check if cmk_img_pol is valid. valid_img_pol_list = ["Never", "IfNotPresent", "Always"] if cmk_img_pol not in valid_img_pol_list: raise RuntimeError("Image pull policy should be one of {}" .format(valid_img_pol_list)) # Check if num_exclusive_cores and num_shared_cores are positive integers. if not num_exclusive_cores.isdigit(): raise RuntimeError("num_exclusive_cores cores should be a positive " "integer.") if not num_shared_cores.isdigit(): raise RuntimeError("num_shared_cores cores should be a positive " "integer.") # Split the cmk_cmd_list based on whether the cmd should be run as # one-shot job or long-running daemons. cmd_init_list = ["init", "discover", "install"] cmk_cmd_init_list = [cmd for cmd in cmk_cmd_list if cmd in cmd_init_list] cmk_cmd_list = [cmd for cmd in cmk_cmd_list if cmd not in cmd_init_list] # Run the pods based on the cmk_cmd_init_list and cmk_cmd_list with # provided options. if cmk_cmd_init_list: run_pods(None, cmk_cmd_init_list, cmk_img, cmk_img_pol, conf_dir, install_dir, num_exclusive_cores, num_shared_cores, cmk_node_list, pull_secret, serviceaccount, shared_mode, exclusive_mode, namespace) if cmk_cmd_list: run_pods(cmk_cmd_list, None, cmk_img, cmk_img_pol, conf_dir, install_dir, num_exclusive_cores, num_shared_cores, cmk_node_list, pull_secret, serviceaccount, shared_mode, exclusive_mode, namespace) # Run mutating webhook admission controller on supported cluster version = util.parse_version(k8s.get_kubelet_version(None)) if version >= util.parse_version("v1.9.0"): deploy_webhook(namespace, conf_dir, install_dir, serviceaccount, cmk_img)
def test_k8s_get_kubelet_version(): mock = MagicMock() with patch('intel.k8s.version_api_client_from_config', MagicMock(return_value=mock)): expected_version = "v1.7.0" mock.get_code.return_value.git_version = expected_version version = k8s.get_kubelet_version(None) assert version == expected_version
def run_cmd_pods(cmd_list, cmd_init_list, cmk_img, cmk_img_pol, conf_dir, install_dir, num_exclusive_cores, num_shared_cores, cmk_node_list, pull_secret, serviceaccount, shared_mode, exclusive_mode, namespace): pod = k8s.get_pod_template() if pull_secret: update_pod_with_pull_secret(pod, pull_secret) if cmd_list: update_pod(pod, "Always", conf_dir, install_dir, serviceaccount) version = util.parse_version(k8s.get_kubelet_version(None)) if version >= util.parse_version("v1.7.0"): pod["spec"]["tolerations"] = [{ "operator": "Exists"}] for cmd in cmd_list: args = "" if cmd == "reconcile": args = "/cmk/cmk.py isolate --pool=infra /cmk/cmk.py -- reconcile --interval=5 --publish" # noqa: E501 elif cmd == "nodereport": args = "/cmk/cmk.py isolate --pool=infra /cmk/cmk.py -- node-report --interval=5 --publish" # noqa: E501 update_pod_with_container(pod, cmd, cmk_img, cmk_img_pol, args) elif cmd_init_list: update_pod(pod, "Never", conf_dir, install_dir, serviceaccount) for cmd in cmd_init_list: args = "" if cmd == "init": args = ("/cmk/cmk.py init --num-exclusive-cores={} " "--num-shared-cores={} --shared-mode={} " "--exclusive-mode={}")\ .format(num_exclusive_cores, num_shared_cores, shared_mode, exclusive_mode) # If init is the only cmd in cmd_init_list, it should be run # as regular container as spec.containers is a required field. # Otherwise, it should be run as init-container. if len(cmd_init_list) == 1: update_pod_with_container(pod, cmd, cmk_img, cmk_img_pol, args) else: update_pod_with_init_container(pod, cmd, cmk_img, cmk_img_pol, args) else: if cmd == "discover": args = "/cmk/cmk.py discover" elif cmd == "install": args = "/cmk/cmk.py install" update_pod_with_container(pod, cmd, cmk_img, cmk_img_pol, args) for node_name in cmk_node_list: if cmd_list: update_pod_with_node_details(pod, node_name, cmd_list) daemon_set = k8s.ds_from(pod=pod) elif cmd_init_list: update_pod_with_node_details(pod, node_name, cmd_init_list) try: if cmd_list: cr_pod_resp = k8s.create_ds(None, daemon_set, namespace) logging.debug("Response while creating ds for {} command(s): " "{}".format(cmd_list, cr_pod_resp)) elif cmd_init_list: cr_pod_resp = k8s.create_pod(None, pod, namespace) logging.debug("Response while creating pod for {} command(s): " "{}".format(cmd_init_list, cr_pod_resp)) except K8sApiException as err: if cmd_list: logging.error("Exception when creating pod for {} command(s): " "{}".format(cmd_list, err)) elif cmd_init_list: logging.error("Exception when creating pod for {} command(s): " "{}".format(cmd_init_list, err)) logging.error("Aborting cluster-init ...") sys.exit(1)