Exemplo n.º 1
0
 def _install_by_version_with_download(cls, version, verbose=False):
     color_print.debug('switching kernel version with downloading packages')
     stdout, stderr = verbose_func.verbose_output(verbose)
     try:
         debs = cls._fetch_package_list_by_version(version, verbose=verbose)
         if not debs:
             return
         # download necessary *.deb and install
         temp_cmd = copy.copy(cls.cmd_dpkg_install)
         version_suffix = None
         for deb in debs:
             cls.download_file(deb, config.kernel_packages_dir)
             filename = deb.split('/')[-1]
             temp_cmd.append(
                 '{prefix}/{filename}'.format(prefix=config.kernel_packages_dir, filename=filename))
             if 'linux-image-' in filename:  # get full version for further modification in grub
                 try:
                     version_suffix = re.search(
                         r'linux-image-[a-z]*-?([\d].*?)_', filename).group(1)
                 except AttributeError:  # failed to derive complete kernel version
                     pass
         color_print.debug('installing kernel packages')
         # installation of kernel may return nonzero, currently ignore them
         subprocess.run(temp_cmd, stdout=stdout, stderr=stderr, check=False)
         if version_suffix:
             color_print.debug('kernel version: %s' % version_suffix)
             cls._modify_grub(version=version_suffix)
         else:
             color_print.warning('failed to derive complete kernel version')
             color_print.warning('please update grub manually')
         return True
     except subprocess.CalledProcessError:
         return False
Exemplo n.º 2
0
    def _modify_grub(cls, version=None, recover=False, verbose=False):
        stdout, stderr = verbose_func.verbose_output(verbose)
        # edit grub
        color_print.debug('modifying grub config file')
        if recover:  # recover grub
            grub_option = '0'
        else:
            grub_option = '\"Advanced options for Ubuntu>Ubuntu, with Linux {version}\"'.format(
                version=version)

        cmd_modify_grub = 'sed\n-i\ns/^GRUB_DEFAULT=.*$/' \
                          'GRUB_DEFAULT={grub_option}/\n/etc/default/grub'.format(
                              grub_option=grub_option).split('\n')
        subprocess.run(
            cmd_modify_grub,
            stdout=stdout,
            stderr=stderr,
            check=True)
        # update grub
        color_print.debug('updating grub')
        subprocess.run(
            cls.cmd_update_grub,
            stdout=stdout,
            stderr=stderr,
            check=True)
Exemplo n.º 3
0
 def _install_one_gadget_by_version(cls,
                                    name,
                                    version,
                                    mappings=None,
                                    verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     # get complete version, e.g. 18.03.1~ce-0~ubuntu
     complete_version = cls._get_apt_complete_version(name,
                                                      version,
                                                      verbose=verbose)
     if complete_version:
         color_print.debug(
             'installing {gadget} with {version} version'.format(
                 gadget=name, version=complete_version))
         # install with the specified version
         temp_cmd = copy.copy(cls.cmd_apt_install)
         temp_cmd.append('{name}={version}'.format(
             name=name, version=complete_version))
         try:
             subprocess.run(temp_cmd,
                            stderr=stderr,
                            stdout=stdout,
                            check=True)
         except subprocess.CalledProcessError:
             return False
         if mappings:
             mappings[name] = complete_version
         return True
     color_print.warning('no candidate version for %s' % name)
     return False
Exemplo n.º 4
0
 def _get_kubernetes_cni_version(cls, name, k8s_cni_version, verbose=False):
     _, stderr = verbose_func.verbose_output(verbose)
     kubelet_complete_version = cls._get_apt_complete_version(
         name, k8s_cni_version, verbose=verbose)
     res = subprocess.run([
         'apt', 'show', '{name}={version}'.format(
             name=name, version=kubelet_complete_version)
     ],
                          stdout=subprocess.PIPE,
                          stderr=stderr,
                          check=True)
     depends = None
     for entry in res.stdout.decode('utf-8').split('\n'):
         if entry.startswith('Depends:'):
             depends = entry
             break
     temp_version = None
     if depends:
         for depend in depends.split(','):
             if 'kubernetes-cni' in depend:
                 # maybe regex is better...
                 temp_version = depend.split('(')[-1].split(')')[0].split(
                     ' ')[-1]
                 # OK, regex (thanks to lzx):
                 # temp_version = re.search(r' kubernetes-cni \(= ([\d.]+)\)', depend).group(1)
                 break
     if temp_version:
         return cls._get_apt_complete_version('kubernetes-cni',
                                              temp_version,
                                              verbose=verbose)
     else:
         return None
Exemplo n.º 5
0
    def _add_apt_repository(cls, repo_entry, gpg_url=None, verbose=False):
        stdout, stderr = verbose_func.verbose_output(verbose)
        color_print.debug('adding apt repository %s' % repo_entry)
        try:
            if gpg_url:
                cmd_curl_gpg = 'curl -fsSL {gpg_url}'.format(
                    gpg_url=gpg_url).split()
                res = subprocess.run(cmd_curl_gpg,
                                     stdout=subprocess.PIPE,
                                     stderr=stderr,
                                     check=True)
                subprocess.run(cls.cmd_apt_add_key,
                               input=res.stdout,
                               stdout=stdout,
                               stderr=stderr,
                               check=True)

            # add apt repository
            cmd_apt_add_repository = 'add-apt-repository\n' \
                                     '{repo_entry}'.format(
                                         repo_entry=repo_entry).split('\n')
            subprocess.run(cmd_apt_add_repository,
                           stdout=stdout,
                           stderr=stderr,
                           check=True)
            return True
        except subprocess.CalledProcessError:
            return False
Exemplo n.º 6
0
    def _install_with_context(cls, gadgets, context=None, verbose=False):
        stdout, stderr = verbose_func.verbose_output(verbose)
        worker_template_mappings = dict(
        )  # used to generate install_k8s_worker_script
        worker_template_mappings['domestic'] = context.get('domestic', False)
        cls._pre_configure(verbose=verbose)
        cls._pre_install(worker_template_mappings, verbose=verbose)
        # firstly install kubernetes-cni, because of:
        # issue: https://github.com/kubernetes/kubernetes/issues/75701
        # note that the solution below is unstable and ugly to some extent...
        kubernetes_cni_version = cls._get_kubernetes_cni_version(
            'kubelet', gadgets[0]['version'], verbose=verbose)
        if kubernetes_cni_version:
            cls._install_one_gadget_by_version('kubernetes-cni',
                                               kubernetes_cni_version,
                                               worker_template_mappings,
                                               verbose=verbose)
        # install kubelet, kubeadm, kubectl
        for gadget in gadgets:
            cls._install_one_gadget_by_version(gadget['name'],
                                               gadget['version'],
                                               worker_template_mappings,
                                               verbose=verbose)

        # pull necessary k8s images
        k8s_version = gadgets[0]['version']
        images_base, images_extra = cls._get_k8s_images_list_by_version(
            k8s_version)
        cls._pull_k8s_images(k8s_version=k8s_version,
                             images_base=images_base,
                             images_extra=images_extra,
                             domestic=context.get('domestic', False),
                             mappings=worker_template_mappings,
                             verbose=verbose)

        # run kubeadm
        if not cls._run_kubeadm(k8s_version,
                                context,
                                mappings=worker_template_mappings,
                                verbose=verbose):
            return False

        # configure kube config
        cls._config_auth()
        # delete master's taint if needed
        if not context.get('taint_master', None):
            subprocess.run(cls._cmd_enable_schedule_master,
                           stdout=stdout,
                           stderr=stderr,
                           check=False)
        # install CNI plugin
        cls._install_cni_plugin(k8s_version,
                                context,
                                worker_template_mappings,
                                verbose=verbose)
        # generate install-script for worker
        cls._update_k8s_worker_script(worker_template_mappings,
                                      context,
                                      verbose=verbose)
        return True
Exemplo n.º 7
0
def kubernetes_specified_installed(temp_gadget, verbose=False):
    """Check whether Kubernetes with specified version has been installed.

    Args:
        temp_gadget: Kubernetes gadgets (e.g. kubelet, kubeadm).
        verbose: Verbose or not.

    Returns:
        If Kubernetes with specified version has been installed, return True,
        else False.
    """
    _, stderr = verbose_func.verbose_output(verbose)
    try:
        temp_cmd = 'kubectl version'.split()
        res = subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        server_string = res.stdout.decode('utf-8').split('\n')[1]
        server_version = re.search(
            r'GitVersion:".?([\d]+\.[\d]+\.[\d]+)"',
            server_string).group(1)
        if server_version == temp_gadget[0]['version']:
            return True
        return False
    except (FileNotFoundError, AttributeError, IndexError, subprocess.CalledProcessError):
        return False
Exemplo n.º 8
0
def kernel_specified_installed(temp_gadget, verbose=False):
    """Check whether Linux kernel with specified version has been installed.

    Args:
        temp_gadget: Kernel gadgets (e.g. kernel).
        verbose: Verbose or not.

    Returns:
        If kernel with specified version has been installed, return True,
        else False.
    """
    try:
        _, stderr = verbose_func.verbose_output(verbose)
        temp_cmd = 'uname -r'.split()
        res = subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        version_string = res.stdout.decode('utf-8')
        if version_string.startswith(temp_gadget[0]['version']):
            return True
        return False
    except (FileNotFoundError, AttributeError, IndexError, subprocess.CalledProcessError):
        return False
Exemplo n.º 9
0
def containerd_specified_installed(temp_gadgets, verbose=False):
    """Check whether Containerd with specified version has been installed.

    Args:
        temp_gadgets: Docker gadgets (e.g. containerd).
        verbose: Verbose or not.

    Returns:
        If Containerd with specified version has been installed, return True,
        else False.
    """
    _, stderr = verbose_func.verbose_output(verbose)
    try:
        temp_cmd = 'ctr version'.split()
        res = subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        server_string = res.stdout.decode('utf-8').split('Server')[1]
        server_version = re.search(
            r'Version:\s*(.*)\s+',
            server_string).group(1)
        temp_version = _get_gadget_version_from_gadgets(
            gadgets=temp_gadgets, name='containerd')
        if temp_version and server_version.startswith(temp_version):
            return True
        return False
    except (FileNotFoundError, AttributeError, IndexError, subprocess.CalledProcessError):
        return False
Exemplo n.º 10
0
    def reload_and_restart_docker(verbose=False):
        """Reload configurations and restart Docker.

        systemctl daemon-reload && systemctl restart docker

        Args:
            verbose: Verbose or not.

        Returns:
            Boolean indicating whether configurations is successfully reload and
            Docker is successfully restarted or not.
        """
        # reload docker daemon configurations
        if not system_func.reload_daemon_config(verbose=verbose):
            return False
        stdout, stderr = verbose_func.verbose_output(verbose)
        color_print.debug('restarting docker')
        try:
            subprocess.run('systemctl restart docker'.split(),
                           stdout=stdout,
                           stderr=stderr,
                           check=True)
            return True
        except subprocess.CalledProcessError:
            color_print.error('failed to restart docker')
            return False
Exemplo n.º 11
0
 def _create_k8s_resources(cls, desc_file, verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     temp_cmd = "kubectl create -f".split()
     temp_cmd.append(desc_file)
     try:
         subprocess.run(temp_cmd, stdout=stdout, stderr=stderr, check=True)
     except subprocess.CalledProcessError:
         raise
Exemplo n.º 12
0
def reboot_system(verbose=False):
    stdout, stderr = verbose_func.verbose_output(verbose)
    cmd_reboot = 'init 6'.split()
    try:
        subprocess.run(cmd_reboot, stdout=stdout, stderr=stderr, check=True)
    except subprocess.CalledProcessError:
        color_print.error('failed to reboot system')
        return False
Exemplo n.º 13
0
 def _apt_update(cls, verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     try:
         subprocess.run(cls.cmd_apt_update,
                        stdout=stdout,
                        stderr=stderr,
                        check=True)
         return True
     except subprocess.CalledProcessError:
         return False
Exemplo n.º 14
0
def reload_daemon_config(verbose=False):
    color_print.debug('reloading daemon configurations')
    stdout, stderr = verbose_func.verbose_output(verbose)
    try:
        subprocess.run('systemctl daemon-reload'.split(),
                       stdout=stdout,
                       stderr=stderr,
                       check=True)
        return True
    except subprocess.CalledProcessError:
        color_print.error('failed to reload daemon configurations')
        return False
Exemplo n.º 15
0
    def uninstall(cls, verbose=False):
        """Uninstall Docker.

        Args:
            verbose: Verbose or not.

        Returns:
            None.
        """
        stdout, stderr = verbose_func.verbose_output(verbose)
        subprocess.run(cls.cmd_apt_uninstall + cls._docker_gadgets,
                       stdout=stdout,
                       stderr=stderr,
                       check=False)
Exemplo n.º 16
0
    def uninstall(cls, verbose=False):
        """Uninstall Docker.

        Args:
            verbose: Verbose or not.

        Returns:
            None.
        """
        stdout, stderr = verbose_func.verbose_output(verbose)
        for gadget in cls._docker_gadgets:
            temp_cmd = copy.copy(cls.cmd_apt_uninstall)
            temp_cmd.append(gadget)
            subprocess.run(temp_cmd, stdout=stdout, stderr=stderr, check=False)
Exemplo n.º 17
0
 def _pre_install(cls, mappings=None, verbose=False):
     color_print.debug('pre-installing')
     stdout, stderr = verbose_func.verbose_output(verbose)
     # install requirements
     cls._apt_update(verbose=verbose)
     subprocess.run(cls.cmd_apt_install + cls._kubernetes_requirements,
                    stdout=stdout,
                    stderr=stderr,
                    check=True)
     cls._add_apt_repository(gpg_url=config.k8s_apt_repo_gpg,
                             repo_entry=config.k8s_apt_repo_entry,
                             verbose=verbose)
     # incompatible with ustc repo because it has no gpg currently
     mappings['gpg_url'] = config.k8s_apt_repo_gpg
     mappings['repo_entry'] = config.k8s_apt_repo_entry
Exemplo n.º 18
0
 def _install_by_version_with_apt(cls, version, verbose=False):
     color_print.debug('switching kernel version with apt')
     stdout, stderr = verbose_func.verbose_output(verbose)
     try:
         # install image package
         package_name = cls._get_apt_complete_package(
             'linux-image', ['linux-image-extra-{version}'.format(version=version), 'generic'], verbose=verbose)
         color_print.debug('installing kernel package %s' % package_name)
         version_suffix = package_name.lstrip('linux-image-extra-')
         temp_cmd = copy.copy(cls.cmd_apt_install)
         temp_cmd.append(package_name)
         subprocess.run(temp_cmd, stdout=stdout, stderr=stderr, check=True)
         cls._modify_grub(version=version_suffix, verbose=verbose)
         return True
     except subprocess.CalledProcessError:
         return False
Exemplo n.º 19
0
 def _get_kubeadm_token_and_hash(cls, verbose=False):
     _, stderr = verbose_func.verbose_output(verbose)
     res = subprocess.run('kubeadm token list'.split(),
                          stdout=subprocess.PIPE,
                          stderr=stderr,
                          check=True)
     res = res.stdout.decode('utf-8')
     token = re.search(r'([a-z0-9]{6}\.[a-z0-9]{16})', res).group(1)
     res = subprocess.run(
         'bash {script}'.format(script=config.k8s_hash_generator).split(),
         stdout=subprocess.PIPE,
         stderr=stderr,
         check=True)
     res = res.stdout.decode('utf-8').strip()
     ca_cert_hash = res
     return token, ca_cert_hash
Exemplo n.º 20
0
def kata_specified_installed(temp_gadget, kata_runtime_type, verbose=False):
    """Check whether kata-containers with specified version has been installed.

    Args:
        temp_gadget: Kata-containers gadgets (e.g. kata-containers).
        kata_runtime_type: Runtime of Kata (e.g. qemu/clh/...).
        verbose:

    Returns:
        If kata-containers with specified version has been installed, return True,
        else False.
    """
    try:
        _, stderr = verbose_func.verbose_output(verbose)
        temp_cmd = '{base_dir}/bin/kata-runtime --version'.format(
            base_dir=config.kata_tar_decompress_dest).split()
        res = subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        version_string = res.stdout.decode('utf-8').split('\n')[0]
        server_version = re.search(
            r'.*([\d]+\.[\d]+\.[\d]+)',
            version_string).group(1)
        if server_version == temp_gadget[0]['version']:
            # check whether kata runtime type is also correct
            try:
                link_target = os.readlink(
                    '{kata_config_dir}/configuration.toml'.format(kata_config_dir=config.kata_config_dir))
                actual_runtime_type = link_target.split('.')[0].split('-')[-1]
                if actual_runtime_type != kata_runtime_type:
                    color_print.warning(
                        'your expected kata runtime type is {expected}, while current type is {actual}'.format(
                            expected=kata_runtime_type, actual=actual_runtime_type))
                    color_print.warning(
                        'you can configure runtime type manually')
            except (FileNotFoundError, OSError):
                color_print.warning(
                    'configuration.toml does not exist or is not an effective symbol link to real configurations')
                color_print.warning(
                    'please check configurations in {kata_config_dir} manually'.format(
                        kata_config_dir=config.kata_config_dir))
            return True
        return False
    except (IndexError, AttributeError, FileNotFoundError, subprocess.CalledProcessError):
        return False
Exemplo n.º 21
0
 def _pull_image(cls, image, mappings=None, verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     if mappings:
         mappings[image] = None
     if not cls._image_exist(image):
         color_print.debug('pulling %s' % image)
         temp_cmd = 'docker pull {image}'.format(image=image).split()
         try:
             subprocess.run(temp_cmd,
                            stdout=stdout,
                            stderr=stderr,
                            check=True)
             return True
         except subprocess.CalledProcessError:
             return False
     else:
         color_print.debug('%s already pulled' % image)
Exemplo n.º 22
0
 def _get_apt_complete_version(cls, name, version, verbose=False):
     _, stderr = verbose_func.verbose_output(verbose)
     temp_cmd = copy.copy(cls.cmd_apt_madison)
     temp_cmd.append(name)
     try:
         res = subprocess.run(temp_cmd,
                              stdout=subprocess.PIPE,
                              stderr=stderr,
                              check=True)
     except subprocess.CalledProcessError:
         return None
     entries = res.stdout.decode('utf-8').split('\n')
     complete_version = None
     for entry in entries:
         if version in entry:
             complete_version = entry.split('|')[1].strip()
             break
     return complete_version
Exemplo n.º 23
0
    def _pre_configure(cls, verbose=False):
        color_print.debug('pre-configuring')
        stdout, stderr = verbose_func.verbose_output(verbose)
        # make sure br_netfilter is loaded.
        subprocess.run(cls._cmd_modprobe,
                       stdout=stdout,
                       stderr=stderr,
                       check=True)

        # ensure net.bridge.bridge-nf-call-iptables
        with open('/etc/sysctl.d/k8s.conf', 'a') as f:
            f.write('net.bridge.bridge-nf-call-ip6tables = 1\n')
            f.write('net.bridge.bridge-nf-call-iptables = 1\n')

        # temporarily turn off swap
        subprocess.run(cls._cmd_swapoff,
                       stdout=stdout,
                       stderr=stderr,
                       check=True)
Exemplo n.º 24
0
 def _get_apt_complete_package(cls, name, keywords, verbose=False):
     _, stderr = verbose_func.verbose_output(verbose)
     temp_cmd = copy.copy(cls.cmd_apt_search)
     temp_cmd.append(name)
     try:
         res = subprocess.run(temp_cmd,
                              stdout=subprocess.PIPE,
                              stderr=stderr,
                              check=True)
     except subprocess.CalledProcessError:
         return None
     entries = res.stdout.decode('utf-8').split('\n')
     for entry in entries:
         for keyword in keywords:
             if keyword not in entry:
                 break
         else:
             return entry.split()[0]
     return None
Exemplo n.º 25
0
    def _pre_install(cls, verbose=False):
        stdout, stderr = verbose_func.verbose_output(verbose)
        # install requirements
        color_print.debug('installing prerequisites')
        try:
            if not cls._apt_update(verbose=verbose):
                return False
            subprocess.run(cls.cmd_apt_install + cls._docker_requirements,
                           stdout=stdout,
                           stderr=stderr,
                           check=True)
        except subprocess.CalledProcessError:
            return False
        cls._add_apt_repository(gpg_url=config.docker_apt_repo_gpg,
                                repo_entry=config.docker_apt_repo_entry,
                                verbose=verbose)
        for repo in config.containerd_apt_repo_entries:
            cls._add_apt_repository(repo_entry=repo, verbose=verbose)

        return True
Exemplo n.º 26
0
 def _act(cls, resources_list, action=None, verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     cmd_kubectl_create = 'kubectl {action} -f'.format(
         action=action).split()
     for res in resources_list:
         color_print.debug('{action}ing {res}'.format(
             action=action.strip('e'), res=res))
         temp_cmd = copy.copy(cmd_kubectl_create)
         temp_cmd.append(res)
         try:
             subprocess.run(temp_cmd,
                            stdout=stdout,
                            stderr=stderr,
                            check=True)
         except subprocess.CalledProcessError:
             color_print.error(
                 'failed to {action} resources in {res}'.format(
                     action=action, res=res))
             return False
     return True
Exemplo n.º 27
0
def docker_installed(verbose=False):
    """Check whether Docker has been installed.

    Args:
        verbose: Verbose or not.

    Returns:
        If Docker has been installed, return True, else False.
    """
    _, stderr = verbose_func.verbose_output(verbose)
    try:
        temp_cmd = 'docker version'.split()
        subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        color_print.debug('docker already installed')
        return True
    except (FileNotFoundError, AttributeError, IndexError, subprocess.CalledProcessError):
        return False
Exemplo n.º 28
0
    def uninstall(cls, verbose=False):
        """Uninstall Kubernetes.

        Args:
            verbose: Verbose or not.

        Returns:
            None.
        """
        stdout, stderr = verbose_func.verbose_output(verbose)
        try:
            subprocess.run(cls._cmd_kubeadm_reset,
                           input='y\n'.encode('utf-8'),
                           stdout=stdout,
                           stderr=stderr,
                           check=False)
        except FileNotFoundError:
            pass
        subprocess.run(cls.cmd_apt_uninstall + cls._kubernetes_gadgets,
                       stdout=stdout,
                       stderr=stderr,
                       check=False)
Exemplo n.º 29
0
 def _run_kubeadm(cls, k8s_version, context, mappings=None, verbose=False):
     color_print.debug('running kubeadm')
     stdout, stderr = verbose_func.verbose_output(verbose)
     temp_cmd = 'kubeadm init'.split()
     temp_cmd.append('--kubernetes-version={k8s_version}'.format(
         k8s_version=k8s_version))
     temp_cmd.append(cls._kubeadm_common_options)
     if mappings:
         mappings['kubeadm_options'] = cls._kubeadm_common_options
     pod_network_cidr = context.get('pod_network_cidr', None)
     if pod_network_cidr:
         temp_cmd.append(
             '--pod-network-cidr={cidr}'.format(cidr=pod_network_cidr))
     try:
         subprocess.run(temp_cmd,
                        stdout=stdout,
                        stderr=stderr,
                        check=True,
                        env=context.get('envs', None))
         return True
     except subprocess.CalledProcessError:
         color_print.error('failed to run kubeadm')
         return False
Exemplo n.º 30
0
    def install_by_version(cls, gadgets, kata_runtime_type,
                           http_proxy=None, https_proxy=None, no_proxy=None, verbose=False):
        """Install Kata-containers with specified version.

        Args:
            gadgets: Kata-containers gadgets (e.g. kata-containers).
            kata_runtime_type: Runtime of Kata (e.g. qemu/clh/...).
            http_proxy: HTTP proxy.
            https_proxy: HTTPS proxy.
            no_proxy: Domains which should be visited without proxy.
            verbose: Verbose or not.

        Returns:
            Boolean indicating whether Kata-containers is successfully installed or not.
        """
        stdout, stderr = verbose_func.verbose_output(verbose)

        kata_static_tar_file = config.kata_static_tar_file % gadgets[0]['version']
        kata_static_save_path = config.runtime_data_dir + kata_static_tar_file
        kata_static_tar = Path(kata_static_save_path)

        # 1. download kata tar if necessary
        if not kata_static_tar.exists():
            color_print.debug(
                '{kata_tar} is going to be downloaded'.format(
                    kata_tar=kata_static_tar_file))
            kata_static_url = (
                config.kata_static_url_prefix %
                gadgets[0]['version']) + kata_static_tar_file
            proxies = {
                'http': http_proxy,
                'https': https_proxy,
                'no_proxy': no_proxy,
            }
            cls.download_file(
                url=kata_static_url,
                save_path=kata_static_save_path,
                proxies=proxies)
        else:
            color_print.debug(
                '{kata_tar} has been downloaded'.format(
                    kata_tar=kata_static_tar_file))

        # 2. decompress
        color_print.debug(
            'decompressing files into {dest}'.format(
                dest=config.kata_tar_decompress_dest))
        rmtree(path=config.kata_tar_decompress_dest, ignore_errors=True)
        system_func.mkdir_if_not_exist(config.kata_tar_decompress_dest)
        # use --strip-components=3 because `opt/kata/` path from tar are not needed
        # also, we should not just decompress files into `/` root path
        # which might cause risks
        temp_cmd = 'tar xf {file} -C {dest} --strip-components=3'.format(
            file=kata_static_save_path, dest=config.kata_tar_decompress_dest)
        try:
            subprocess.run(
                temp_cmd.split(),
                stdout=stdout,
                stderr=stderr,
                check=True)
        except subprocess.CalledProcessError:
            color_print.error(
                'failed to decompress {kata_tar}'.format(
                    kata_tar=kata_static_tar_file))
            return False

        # 3. copy files
        color_print.debug(
            'copying files to {kata_config_dir}'.format(
                kata_config_dir=config.kata_config_dir))
        rmtree(path=config.kata_config_dir, ignore_errors=True)
        system_func.mkdir_if_not_exist(config.kata_config_dir)
        for file in glob.glob(
                config.kata_tar_decompress_dest + 'share/defaults/kata-containers/*'):
            file_copy(
                src=file,
                dst=config.kata_config_dir,
                follow_symlinks=False)

        # 4. configure runtime type
        color_print.debug(
            'configuring kata runtime (type: {runtime_type})'.format(
                runtime_type=kata_runtime_type))
        kata_configuration_file = Path(
            '{kata_config_dir}/configuration.toml'.format(kata_config_dir=config.kata_config_dir))
        if kata_configuration_file.exists():
            kata_configuration_file.unlink()
        kata_configuration_file.symlink_to(
            '{kata_config_dir}/configuration-{runtime_type}.toml'.format(
                kata_config_dir=config.kata_config_dir,
                runtime_type=kata_runtime_type))

        # [5]. if docker is installed,
        # modify docker's configuration and restart docker
        # currently, metarget only supports docker
        # in the future more CRIs will be supported
        # see
        # https://github.com/kata-containers/documentation/blob/master/how-to/run-kata-with-k8s.md
        color_print.debug('configuring docker with kata-containers')
        if not cls._configure_docker_with_kata(
                base_dir=config.kata_tar_decompress_dest):
            color_print.error(
                'failed to configure docker with kata-containers')
            return False
        return cls.reload_and_restart_docker(verbose=verbose)