JFIF # -$)%7&).0444#9?92>-240 5+#+4;224;652252222225222220222522225222522;2225222222"B!1AQa"q2B#R3br5CS/!12AQ"aRq#3 ??;}q7:bd%Ո>L8/$rsrQٷf=+e: Rb0Z6pN۰7b 1S`JAT K,-֥7(bNRb9CsD/s,9?}+KA]`,EΞ@@ 3ukq14""tD@D@D@D@D@D@D@D@D@D@D@ȓ|:^Yw-)G%AI/9pwVSнm@6=g7AA5tg18gj>F'J,{C3(q<*#AzX?[$va:Q4SԽ7Uԥ&,c}nF;3mO$DN}RySm\*I"}b%7GLj;gp{{FYs(p_xOJFtStǸMU蓰s95"#H'Uq>7F5[}>v%'Y,&CqMzn}m*Xo vl˳hrӦ V)))g`7$sz^%I-1leE]y%݉>?f}( *BNNñ𜤢S[i'T1 ӥԊ>NlHď~)pKw1.UsD LI/k]Sr\r=ߴMAZNKi+P}| qBS*G*z:Imk\_|l6A7߉H\z0賈'Zt_\u>4 {\#O[ERxzLvP wOLT C0ȴ]BAʷ7uNNINS,(DDDDDDDL8MY݂N$ dMK׭i2FesmNQ=?omKv]OVl^@&pɴ[t5+E`oy.E]Ϳ}$g(7y7&X+imcT\(cHɤ|=. C =yȗXʧpv=&cX*[X_i4 GtfFՓnbMjR@ thv4LO I0zlU-_*G!cH9`nԿ \k-~rS*c[}9]qbi~+%)(h($ s;dՒG_\ё[Q,plq!pEſA RZU0*\n]a~Md_3EZ { &8e:jR*dAkyۛs\B˞0Z5%6e`3;0slSx+Xȇ"*ozkE"vܬWاQ8r @ m5$ [/KNFycgrۑ@ {""""""|xd*@s7o~7BSG|܎vøGtЍL١ѬnK/, f~^~l/Ij+!JI'^;{˚*hӤJarʮ)ڱ[P^$;%.V FLJW̔?2ԭUpJe,~b%iW Yhz̻FAl|3ln"M4kM@$2wmͣp8JY)ݬ.]3vԩİ(P*Tb/1FXTg KŮ*C9jE[69d!GZȩMu!5`H\Cp"=wSAmJjCn&/*Q[kQ~b"zΕ~)aA(2EZ0(FÑp.66_φk}T5 YdRarK ɽLSj"SnR-N-Mz~F^Igb Jq(~X fH'Ӵp5_HN(ܰ,Ȍ䶛DK%a~?FuI}"p=U+j}'p&I_ɑ-x!IٮM:w|q;9M?.6x:ODѪ̬zTL`t^?8xJ$ Q cL4d/_xy ˔ SPGNgwSrrS/`5ӧKj ,hTpI=LѦ(,Pc4*4iESO?5sMz<`&_bsTO)fkX[ xqq::h9ifVۉ\_R }JVg~Jzm`(]:O &6IOghX6+HM 7X]RkUr{HL-"< >~28b{[><@6gF5&\1̹nVŕonZM7 (SF$l\sM];owE+IֹȫzɲDߌPcMQMG)b,N ;*!uo&rHT`s^7įĴz0?P&Ҫ3]@H:hڢFҢM~p{&0s?k}+Ι9׵mw >?"fs+Odٯ̌m(R9T:UpbkW=F*ZQh urk8C8@ҧeUԀyKS '.UP,NBcpFS6n=AJl*7 4<(XY_Cda/D=()b,{yHL>[jrǹ7#M7fO`o/w]GȈEU2f\?7a)#봙݂͠SEg>VRdPfF@PV"Ꮷ_(qCJG_0?1[% NKu$7&ۭ ߡ26U$`/ 3ES:/nek |\tmSg5 س}6/qDT "(*sP4SrX)%T(6y%_ Z9<%]B}oyyY"]76*U*vjijw i3D̍IS \Jnn9ۋ>%o;~)5u56槡'z* B5#5

5#a`,>1TW{Xɘ}G4"ҕ4z5F>e6*[\;%*U0LUUr2cpnݢkɜY͌3+bG0#el۴oe,,jO*M1X/3z)W^,p>s{ İQs:ޝd|w :fIe$~+ajXjnT80'S>KIUP&kNϒT=XlȞNڞ]Yz_K[Qׂގ\gq!nB@IoG *l;_뼳\RUeэkm)qh傢5KNz٘6ba:671k{  $N vfN]S7gxg=VjG;wBx t~l/"ʭl=ԝ6n[Dٛ]@"x)# E):\8Bvkcpv4O*;coJ?4ªMCA'.\zVð'w1USݻSlTyj/ gʕ,:S')ܴ]7!A^b%P׶ٮհU3 o\}XTp,e 597n}dk6UFrVǧ3qaR:BWn>Ѻ}oxKӦK)kܑKL tCs1#?升 v{r:u)?#ZxM=ڝYـ#e}JHBGTG>GsܞG2+~R̅Hש)$[*Hfx-ugx({ I7λwvYm~ |e'X#db@hW,0H8*J5AъA`;jȊY*&sh8Jn]"M>l3z%Րsy=Um'qF sX %,Uv|0W`Gzcy*V0'3R`5ޓ Hڙ>PWbw7;)[U(:krm>/ QU+)P>Hm!r -evY>wT7ԝe)^6_SN⚓ϫ('?2Sj5,[پd|+_Pv'[]t'mΝ2l}z/dz^E|"'J qED)R2ƂSg`9Ոu5~ d!G%>M6%pdcP-P L`ϼTQnA_,24G GneRn,XnߕSzV$ReBfZuE ,Z(yi?vO!clOYA [; c I|vCom+Hꡤ\eaӴ;XS|v4%FcϷAQ[yϢ_s+Ơ&pt}=%^Sb"#gĀ'[ oAUPzr;ȔZTy4t>f種ً>T؟GRgC^-WЖukS,G LV$ܱO餰%cp)[*X_v$@DDӢ3bE-V0֍?zySyadd\ j5": Bxi?;3a]1]ZFD澙rc|8uz/ CȎ3UTqb4'ҥX 6KʖYT2fPe$6 lGzSQTP} OL1q^*rxջQ_K?'?=V MR K IS HERE

MRKShell
Server IP : 104.21.73.244  /  Your IP : 172.71.28.168
Web Server : nginx/1.14.1
System : Linux comtuc2-s-2vcpu-8gb-160gb-intel-nyc3 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64
User : nginx ( 991)
PHP Version : 7.2.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /lib/python3.6/site-packages/cloudinit/config/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : /lib/python3.6/site-packages/cloudinit/config/cc_ntp.py
# Copyright (C) 2016 Canonical Ltd.
#
# Author: Ryan Harper <ryan.harper@canonical.com>
#
# This file is part of cloud-init. See LICENSE file for license information.

"""NTP: enable and configure ntp"""

import copy
import os
from textwrap import dedent

from cloudinit import log as logging
from cloudinit import temp_utils
from cloudinit import templater
from cloudinit import type_utils
from cloudinit import subp
from cloudinit import util
from cloudinit.config.schema import get_schema_doc, validate_cloudconfig_schema
from cloudinit.settings import PER_INSTANCE

LOG = logging.getLogger(__name__)

frequency = PER_INSTANCE
NTP_CONF = '/etc/ntp.conf'
NR_POOL_SERVERS = 4
distros = ['alpine', 'centos', 'debian', 'fedora', 'opensuse', 'rhel',
           'sles', 'ubuntu']

NTP_CLIENT_CONFIG = {
    'chrony': {
        'check_exe': 'chronyd',
        'confpath': '/etc/chrony.conf',
        'packages': ['chrony'],
        'service_name': 'chrony',
        'template_name': 'chrony.conf.{distro}',
        'template': None,
    },
    'ntp': {
        'check_exe': 'ntpd',
        'confpath': NTP_CONF,
        'packages': ['ntp'],
        'service_name': 'ntp',
        'template_name': 'ntp.conf.{distro}',
        'template': None,
    },
    'ntpdate': {
        'check_exe': 'ntpdate',
        'confpath': NTP_CONF,
        'packages': ['ntpdate'],
        'service_name': 'ntpdate',
        'template_name': 'ntp.conf.{distro}',
        'template': None,
    },
    'systemd-timesyncd': {
        'check_exe': '/lib/systemd/systemd-timesyncd',
        'confpath': '/etc/systemd/timesyncd.conf.d/cloud-init.conf',
        'packages': [],
        'service_name': 'systemd-timesyncd',
        'template_name': 'timesyncd.conf',
        'template': None,
    },
}

# This is Distro-specific configuration overrides of the base config
DISTRO_CLIENT_CONFIG = {
    'alpine': {
        'chrony': {
            'confpath': '/etc/chrony/chrony.conf',
            'service_name': 'chronyd',
        },
        'ntp': {
            'confpath': '/etc/ntp.conf',
            'packages': [],
            'service_name': 'ntpd',
        },
    },
    'debian': {
        'chrony': {
            'confpath': '/etc/chrony/chrony.conf',
        },
    },
    'rhel': {
        'ntp': {
            'service_name': 'ntpd',
        },
        'chrony': {
            'service_name': 'chronyd',
        },
    },
    'opensuse': {
        'chrony': {
            'service_name': 'chronyd',
        },
        'ntp': {
            'confpath': '/etc/ntp.conf',
            'service_name': 'ntpd',
        },
        'systemd-timesyncd': {
            'check_exe': '/usr/lib/systemd/systemd-timesyncd',
        },
    },
    'sles': {
        'chrony': {
            'service_name': 'chronyd',
        },
        'ntp': {
            'confpath': '/etc/ntp.conf',
            'service_name': 'ntpd',
        },
        'systemd-timesyncd': {
            'check_exe': '/usr/lib/systemd/systemd-timesyncd',
        },
    },
    'ubuntu': {
        'chrony': {
            'confpath': '/etc/chrony/chrony.conf',
        },
    },
}


# The schema definition for each cloud-config module is a strict contract for
# describing supported configuration parameters for each cloud-config section.
# It allows cloud-config to validate and alert users to invalid or ignored
# configuration options before actually attempting to deploy with said
# configuration.

schema = {
    'id': 'cc_ntp',
    'name': 'NTP',
    'title': 'enable and configure ntp',
    'description': dedent("""\
        Handle ntp configuration. If ntp is not installed on the system and
        ntp configuration is specified, ntp will be installed. If there is a
        default ntp config file in the image or one is present in the
        distro's ntp package, it will be copied to a file with ``.dist``
        appended to the filename before any changes are made. A list of ntp
        pools and ntp servers can be provided under the ``ntp`` config key.
        If no ntp ``servers`` or ``pools`` are provided, 4 pools will be used
        in the format ``{0-3}.{distro}.pool.ntp.org``."""),
    'distros': distros,
    'examples': [
        dedent("""\
        # Override ntp with chrony configuration on Ubuntu
        ntp:
          enabled: true
          ntp_client: chrony  # Uses cloud-init default chrony configuration
        """),
        dedent("""\
        # Provide a custom ntp client configuration
        ntp:
          enabled: true
          ntp_client: myntpclient
          config:
             confpath: /etc/myntpclient/myntpclient.conf
             check_exe: myntpclientd
             packages:
               - myntpclient
             service_name: myntpclient
             template: |
                 ## template:jinja
                 # My NTP Client config
                 {% if pools -%}# pools{% endif %}
                 {% for pool in pools -%}
                 pool {{pool}} iburst
                 {% endfor %}
                 {%- if servers %}# servers
                 {% endif %}
                 {% for server in servers -%}
                 server {{server}} iburst
                 {% endfor %}
          pools: [0.int.pool.ntp.org, 1.int.pool.ntp.org, ntp.myorg.org]
          servers:
            - ntp.server.local
            - ntp.ubuntu.com
            - 192.168.23.2""")],
    'frequency': PER_INSTANCE,
    'type': 'object',
    'properties': {
        'ntp': {
            'type': ['object', 'null'],
            'properties': {
                'pools': {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'format': 'hostname'
                    },
                    'uniqueItems': True,
                    'description': dedent("""\
                        List of ntp pools. If both pools and servers are
                        empty, 4 default pool servers will be provided of
                        the format ``{0-3}.{distro}.pool.ntp.org``. NOTE:
                        for Alpine Linux when using the Busybox NTP client
                        this setting will be ignored due to the limited
                        functionality of Busybox's ntpd.""")
                },
                'servers': {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'format': 'hostname'
                    },
                    'uniqueItems': True,
                    'description': dedent("""\
                        List of ntp servers. If both pools and servers are
                        empty, 4 default pool servers will be provided with
                        the format ``{0-3}.{distro}.pool.ntp.org``.""")
                },
                'ntp_client': {
                    'type': 'string',
                    'default': 'auto',
                    'description': dedent("""\
                        Name of an NTP client to use to configure system NTP.
                        When unprovided or 'auto' the default client preferred
                        by the distribution will be used. The following
                        built-in client names can be used to override existing
                        configuration defaults: chrony, ntp, ntpdate,
                        systemd-timesyncd."""),
                },
                'enabled': {
                    'type': 'boolean',
                    'default': True,
                    'description': dedent("""\
                        Attempt to enable ntp clients if set to True.  If set
                        to False, ntp client will not be configured or
                        installed"""),
                },
                'config': {
                    'description': dedent("""\
                        Configuration settings or overrides for the
                        ``ntp_client`` specified."""),
                    'type': ['object'],
                    'properties': {
                        'confpath': {
                            'type': 'string',
                            'description': dedent("""\
                                The path to where the ``ntp_client``
                                configuration is written."""),
                        },
                        'check_exe': {
                            'type': 'string',
                            'description': dedent("""\
                                The executable name for the ``ntp_client``.
                                For example, ntp service ``check_exe`` is
                                'ntpd' because it runs the ntpd binary."""),
                        },
                        'packages': {
                            'type': 'array',
                            'items': {
                                'type': 'string',
                            },
                            'uniqueItems': True,
                            'description': dedent("""\
                                List of packages needed to be installed for the
                                selected ``ntp_client``."""),
                        },
                        'service_name': {
                            'type': 'string',
                            'description': dedent("""\
                                The systemd or sysvinit service name used to
                                start and stop the ``ntp_client``
                                service."""),
                        },
                        'template': {
                            'type': 'string',
                            'description': dedent("""\
                                Inline template allowing users to define their
                                own ``ntp_client`` configuration template.
                                The value must start with '## template:jinja'
                                to enable use of templating support.
                                """),
                        },
                    },
                    # Don't use REQUIRED_NTP_CONFIG_KEYS to allow for override
                    # of builtin client values.
                    'required': [],
                    'minProperties': 1,  # If we have config, define something
                    'additionalProperties': False
                },
            },
            'required': [],
            'additionalProperties': False
        }
    }
}
REQUIRED_NTP_CONFIG_KEYS = frozenset([
    'check_exe', 'confpath', 'packages', 'service_name'])


__doc__ = get_schema_doc(schema)  # Supplement python help()


def distro_ntp_client_configs(distro):
    """Construct a distro-specific ntp client config dictionary by merging
       distro specific changes into base config.

    @param distro: String providing the distro class name.
    @returns: Dict of distro configurations for ntp clients.
    """
    dcfg = DISTRO_CLIENT_CONFIG
    cfg = copy.copy(NTP_CLIENT_CONFIG)
    if distro in dcfg:
        cfg = util.mergemanydict([cfg, dcfg[distro]], reverse=True)
    return cfg


def select_ntp_client(ntp_client, distro):
    """Determine which ntp client is to be used, consulting the distro
       for its preference.

    @param ntp_client: String name of the ntp client to use.
    @param distro: Distro class instance.
    @returns: Dict of the selected ntp client or {} if none selected.
    """

    # construct distro-specific ntp_client_config dict
    distro_cfg = distro_ntp_client_configs(distro.name)

    # user specified client, return its config
    if ntp_client and ntp_client != 'auto':
        LOG.debug('Selected NTP client "%s" via user-data configuration',
                  ntp_client)
        return distro_cfg.get(ntp_client, {})

    # default to auto if unset in distro
    distro_ntp_client = distro.get_option('ntp_client', 'auto')

    clientcfg = {}
    if distro_ntp_client == "auto":
        for client in distro.preferred_ntp_clients:
            cfg = distro_cfg.get(client)
            if subp.which(cfg.get('check_exe')):
                LOG.debug('Selected NTP client "%s", already installed',
                          client)
                clientcfg = cfg
                break

        if not clientcfg:
            client = distro.preferred_ntp_clients[0]
            LOG.debug(
                'Selected distro preferred NTP client "%s", not yet installed',
                client)
            clientcfg = distro_cfg.get(client)
    else:
        LOG.debug('Selected NTP client "%s" via distro system config',
                  distro_ntp_client)
        clientcfg = distro_cfg.get(distro_ntp_client, {})

    return clientcfg


def install_ntp_client(install_func, packages=None, check_exe="ntpd"):
    """Install ntp client package if not already installed.

    @param install_func: function.  This parameter is invoked with the contents
    of the packages parameter.
    @param packages: list.  This parameter defaults to ['ntp'].
    @param check_exe: string.  The name of a binary that indicates the package
    the specified package is already installed.
    """
    if subp.which(check_exe):
        return
    if packages is None:
        packages = ['ntp']

    install_func(packages)


def rename_ntp_conf(confpath=None):
    """Rename any existing ntp client config file

    @param confpath: string. Specify a path to an existing ntp client
    configuration file.
    """
    if os.path.exists(confpath):
        util.rename(confpath, confpath + ".dist")


def generate_server_names(distro):
    """Generate a list of server names to populate an ntp client configuration
    file.

    @param distro: string.  Specify the distro name
    @returns: list: A list of strings representing ntp servers for this distro.
    """
    names = []
    pool_distro = distro

    if distro == 'sles':
        # For legal reasons x.pool.sles.ntp.org does not exist,
        # use the opensuse pool
        pool_distro = 'opensuse'
    elif distro == 'alpine':
        # Alpine-specific pool (i.e. x.alpine.pool.ntp.org) does not exist
        # so use general x.pool.ntp.org instead.
        pool_distro = ''

    for x in range(0, NR_POOL_SERVERS):
        names.append(".".join(
            [n for n in [str(x)] + [pool_distro] + ['pool.ntp.org'] if n]))

    return names


def write_ntp_config_template(distro_name, service_name=None, servers=None,
                              pools=None, path=None, template_fn=None,
                              template=None):
    """Render a ntp client configuration for the specified client.

    @param distro_name: string.  The distro class name.
    @param service_name: string. The name of the NTP client service.
    @param servers: A list of strings specifying ntp servers. Defaults to empty
    list.
    @param pools: A list of strings specifying ntp pools. Defaults to empty
    list.
    @param path: A string to specify where to write the rendered template.
    @param template_fn: A string to specify the template source file.
    @param template: A string specifying the contents of the template. This
    content will be written to a temporary file before being used to render
    the configuration file.

    @raises: ValueError when path is None.
    @raises: ValueError when template_fn is None and template is None.
    """
    if not servers:
        servers = []
    if not pools:
        pools = []

    if (len(servers) == 0 and distro_name == 'alpine' and
            service_name == 'ntpd'):
        # Alpine's Busybox ntpd only understands "servers" configuration
        # and not "pool" configuration.
        servers = generate_server_names(distro_name)
        LOG.debug(
            'Adding distro default ntp servers: %s', ','.join(servers))
    elif len(servers) == 0 and len(pools) == 0:
        pools = generate_server_names(distro_name)
        LOG.debug(
            'Adding distro default ntp pool servers: %s', ','.join(pools))

    if not path:
        raise ValueError('Invalid value for path parameter')

    if not template_fn and not template:
        raise ValueError('Not template_fn or template provided')

    params = {'servers': servers, 'pools': pools}
    if template:
        tfile = temp_utils.mkstemp(prefix='template_name-', suffix=".tmpl")
        template_fn = tfile[1]  # filepath is second item in tuple
        util.write_file(template_fn, content=template)

    templater.render_to_file(template_fn, path, params)
    # clean up temporary template
    if template:
        util.del_file(template_fn)


def reload_ntp(service, systemd=False):
    """Restart or reload an ntp system service.

    @param service: A string specifying the name of the service to be affected.
    @param systemd: A boolean indicating if the distro uses systemd, defaults
    to False.
    @returns: A tuple of stdout, stderr results from executing the action.
    """
    if systemd:
        cmd = ['systemctl', 'reload-or-restart', service]
    else:
        cmd = ['service', service, 'restart']
    subp.subp(cmd, capture=True)


def supplemental_schema_validation(ntp_config):
    """Validate user-provided ntp:config option values.

    This function supplements flexible jsonschema validation with specific
    value checks to aid in triage of invalid user-provided configuration.

    @param ntp_config: Dictionary of configuration value under 'ntp'.

    @raises: ValueError describing invalid values provided.
    """
    errors = []
    missing = REQUIRED_NTP_CONFIG_KEYS.difference(set(ntp_config.keys()))
    if missing:
        keys = ', '.join(sorted(missing))
        errors.append(
            'Missing required ntp:config keys: {keys}'.format(keys=keys))
    elif not any([ntp_config.get('template'),
                  ntp_config.get('template_name')]):
        errors.append(
            'Either ntp:config:template or ntp:config:template_name values'
            ' are required')
    for key, value in sorted(ntp_config.items()):
        keypath = 'ntp:config:' + key
        if key == 'confpath':
            if not all([value, isinstance(value, str)]):
                errors.append(
                    'Expected a config file path {keypath}.'
                    ' Found ({value})'.format(keypath=keypath, value=value))
        elif key == 'packages':
            if not isinstance(value, list):
                errors.append(
                    'Expected a list of required package names for {keypath}.'
                    ' Found ({value})'.format(keypath=keypath, value=value))
        elif key in ('template', 'template_name'):
            if value is None:  # Either template or template_name can be none
                continue
            if not isinstance(value, str):
                errors.append(
                    'Expected a string type for {keypath}.'
                    ' Found ({value})'.format(keypath=keypath, value=value))
        elif not isinstance(value, str):
            errors.append(
                'Expected a string type for {keypath}.'
                ' Found ({value})'.format(keypath=keypath, value=value))

    if errors:
        raise ValueError(r'Invalid ntp configuration:\n{errors}'.format(
            errors='\n'.join(errors)))


def handle(name, cfg, cloud, log, _args):
    """Enable and configure ntp."""
    if 'ntp' not in cfg:
        LOG.debug(
            "Skipping module named %s, not present or disabled by cfg", name)
        return
    ntp_cfg = cfg['ntp']
    if ntp_cfg is None:
        ntp_cfg = {}  # Allow empty config which will install the package

    # TODO drop this when validate_cloudconfig_schema is strict=True
    if not isinstance(ntp_cfg, (dict)):
        raise RuntimeError(
            "'ntp' key existed in config, but not a dictionary type,"
            " is a {_type} instead".format(_type=type_utils.obj_name(ntp_cfg)))

    validate_cloudconfig_schema(cfg, schema)

    # Allow users to explicitly enable/disable
    enabled = ntp_cfg.get('enabled', True)
    if util.is_false(enabled):
        LOG.debug("Skipping module named %s, disabled by cfg", name)
        return

    # Select which client is going to be used and get the configuration
    ntp_client_config = select_ntp_client(ntp_cfg.get('ntp_client'),
                                          cloud.distro)

    # Allow user ntp config to override distro configurations
    ntp_client_config = util.mergemanydict(
        [ntp_client_config, ntp_cfg.get('config', {})], reverse=True)

    supplemental_schema_validation(ntp_client_config)
    rename_ntp_conf(confpath=ntp_client_config.get('confpath'))

    template_fn = None
    if not ntp_client_config.get('template'):
        template_name = (
            ntp_client_config.get('template_name').replace('{distro}',
                                                           cloud.distro.name))
        template_fn = cloud.get_template_filename(template_name)
        if not template_fn:
            msg = ('No template found, not rendering %s' %
                   ntp_client_config.get('template_name'))
            raise RuntimeError(msg)

    write_ntp_config_template(cloud.distro.name,
                              service_name=ntp_client_config.get(
                                  'service_name'),
                              servers=ntp_cfg.get('servers', []),
                              pools=ntp_cfg.get('pools', []),
                              path=ntp_client_config.get('confpath'),
                              template_fn=template_fn,
                              template=ntp_client_config.get('template'))

    install_ntp_client(cloud.distro.install_packages,
                       packages=ntp_client_config['packages'],
                       check_exe=ntp_client_config['check_exe'])
    try:
        reload_ntp(ntp_client_config['service_name'],
                   systemd=cloud.distro.uses_systemd())
    except subp.ProcessExecutionError as e:
        LOG.exception("Failed to reload/start ntp service: %s", e)
        raise

# vi: ts=4 expandtab

Anon7 - 2022
AnonSec Team