diff options
Diffstat (limited to 'tools')
| -rwxr-xr-x | tools/ds-identify | 78 | ||||
| -rwxr-xr-x | tools/net-convert.py | 84 | 
2 files changed, 140 insertions, 22 deletions
| diff --git a/tools/ds-identify b/tools/ds-identify index e138d780..5d390ef7 100755 --- a/tools/ds-identify +++ b/tools/ds-identify @@ -70,7 +70,9 @@ PATH_PROC_CMDLINE="${PATH_PROC_CMDLINE:-${PATH_ROOT}/proc/cmdline}"  PATH_PROC_1_CMDLINE="${PATH_PROC_1_CMDLINE:-${PATH_ROOT}/proc/1/cmdline}"  PATH_PROC_1_ENVIRON="${PATH_PROC_1_ENVIRON:-${PATH_ROOT}/proc/1/environ}"  PATH_PROC_UPTIME=${PATH_PROC_UPTIME:-${PATH_ROOT}/proc/uptime} -PATH_CLOUD_CONFD="${PATH_CLOUD_CONFD:-${PATH_ROOT}/etc/cloud}" +PATH_ETC_CLOUD="${PATH_ETC_CLOUD:-${PATH_ROOT}/etc/cloud}" +PATH_ETC_CI_CFG="${PATH_ETC_CI_CFG:-${PATH_ETC_CLOUD}/cloud.cfg}" +PATH_ETC_CI_CFG_D="${PATH_ETC_CI_CFG_D:-${PATH_ETC_CI_CFG}.d}"  PATH_RUN_CI="${PATH_RUN_CI:-${PATH_RUN}/cloud-init}"  PATH_RUN_CI_CFG=${PATH_RUN_CI_CFG:-${PATH_RUN_CI}/cloud.cfg}  PATH_RUN_DI_RESULT=${PATH_RUN_DI_RESULT:-${PATH_RUN_CI}/.ds-identify.result} @@ -108,7 +110,7 @@ DI_DSNAME=""  # this has to match the builtin list in cloud-init, it is what will  # be searched if there is no setting found in config.  DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \ -CloudSigma CloudStack DigitalOcean Ec2 OpenNebula OpenStack OVF SmartOS" +CloudSigma CloudStack DigitalOcean Ec2 GCE OpenNebula OpenStack OVF SmartOS"  DI_DSLIST=""  DI_MODE=""  DI_ON_FOUND="" @@ -383,6 +385,14 @@ dmi_product_name_matches() {      return 1  } +dmi_product_serial_matches() { +    is_container && return 1 +    case "${DI_DMI_PRODUCT_SERIAL}" in +        $1) return 0;; +    esac +    return 1 +} +  dmi_product_name_is() {      is_container && return 1      [ "${DI_DMI_PRODUCT_NAME}" = "$1" ] @@ -464,16 +474,19 @@ dscheck_CloudSigma() {  }  check_config() { -    # somewhat hackily read config for 'key' in files matching 'files' -    # currently does not respect any hierarchy. -    local key="$1" files="" bp="${PATH_CLOUD_CONFD}/cloud.cfg" -    if [ $# -eq 1 ]; then -        files="$bp ${bp}.d/*.cfg" +    # check_config(key [,file_globs]) +    # somewhat hackily read through file_globs for 'key' +    # file_globs are expanded via path expansion and +    # default to /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.d/*.cfg +    # currently does not respect any hierarchy in searching for key. +    local key="$1" files="" +    shift +    if [ $# -eq 0 ]; then +        files="${PATH_ETC_CI_CFG} ${PATH_ETC_CI_CFG_D}/*.cfg"      else          files="$*"      fi -    shift -    set +f; set -- $files; set +f; +    set +f; set -- $files; set -f;      if [ "$1" = "$files" -a ! -f "$1" ]; then          return 1      fi @@ -512,9 +525,7 @@ dscheck_MAAS() {      esac      # check config files written by maas for installed system. -    local confd="${PATH_CLOUD_CONFD}" -    local fnmatch="$confd/*maas*.cfg $confd/*kernel_cmdline*.cfg" -    if check_config "MAAS" "$fnmatch"; then +    if check_config "MAAS"; then          return "${DS_FOUND}"      fi      return ${DS_NOT_FOUND} @@ -538,6 +549,19 @@ check_configdrive_v2() {      if has_fs_with_label "config-2"; then          return ${DS_FOUND}      fi +    # look in /config-drive <vlc>/seed/config_drive for a directory +    # openstack/YYYY-MM-DD format with a file meta_data.json +    local d="" +    for d in /config-drive "${PATH_VAR_LIB_CLOUD}/seed/config_drive"; do +        set +f; set -- "$d/openstack/"2???-??-??/meta_data.json; set -f; +        [ -f "$1" ] && return ${DS_FOUND} +    done +    # at least one cloud (softlayer) seeds config drive with only 'latest'. +    local lpath="openstack/latest/meta_data.json" +    if [ -e "${PATH_VAR_LIB_CLOUD}/$lpath" ]; then +        debug 1 "config drive seeded directory had only 'latest'" +        return ${DS_FOUND} +    fi      return ${DS_NOT_FOUND}  } @@ -586,9 +610,7 @@ ovf_vmware_guest_customization() {      # (disable_vmware_customization=true). If it is set to false, then      # user has requested customization.      local key="disable_vmware_customization" -    local match="" bp="${PATH_CLOUD_CONFD}/cloud.cfg" -    match="$bp $bp.d/*[Oo][Vv][Ff]*.cfg" -    if check_config "$key" "$match"; then +    if check_config "$key"; then          debug 2 "${_RET_fname} set $key to $_RET"          case "$_RET" in              0|false|False) return 0;; @@ -633,7 +655,8 @@ dscheck_Azure() {  dscheck_Bigstep() {      # bigstep is activated by presense of seed file 'url' -    check_seed_dir "bigstep" url && return ${DS_FOUND} +    [ -f "${PATH_VAR_LIB_CLOUD}/data/seed/bigstep/url" ] && +        return ${DS_FOUND}      return ${DS_NOT_FOUND}  } @@ -658,9 +681,9 @@ ec2_read_strict_setting() {      esac      # 3. look for the key 'strict_id' (datasource/Ec2/strict_id) -    local match="" bp="${PATH_CLOUD_CONFD}/cloud.cfg" -    match="$bp $bp.d/*[Ee][Cc]2*.cfg" -    if check_config strict_id "$match"; then +    # only in cloud.cfg or cloud.cfg.d/EC2.cfg (case insensitive) +    local cfg="${PATH_ETC_CI_CFG}" cfg_d="${PATH_ETC_CI_CFG_D}" +    if check_config strict_id $cfg "$cfg_d/*[Ee][Cc]2*.cfg"; then          debug 2 "${_RET_fname} set strict_id to $_RET"          return 0      fi @@ -756,6 +779,10 @@ dscheck_GCE() {      if dmi_product_name_is "Google Compute Engine"; then          return ${DS_FOUND}      fi +    # product name is not guaranteed (LP: #1674861) +    if dmi_product_serial_matches "GoogleCloud-*"; then +        return ${DS_FOUND} +    fi      return ${DS_NOT_FOUND}  } @@ -769,10 +796,15 @@ dscheck_OpenStack() {      if [ $? -eq ${DS_FOUND} ]; then          return ${DS_NOT_FOUND}      fi -    if dmi_product_name_is "OpenStack Nova"; then +    local nova="OpenStack Nova" compute="OpenStack Compute" +    if dmi_product_name_is "$nova"; then +        return ${DS_FOUND} +    fi +    if dmi_product_name_is "$compute"; then +        # RDO installed nova (LP: #1675349).          return ${DS_FOUND}      fi -    if [ "${DI_PID_1_PLATFORM}" = "OpenStack Nova" ]; then +    if [ "${DI_PID_1_PLATFORM}" = "$nova" ]; then          return ${DS_FOUND}      fi @@ -923,7 +955,9 @@ found() {          shift      fi      # always write the None datasource last. -    list="${list:+${list}, }None" +    if [ "$list" != "None" ]; then +        list="${list:+${list}, }None" +    fi      write_result "datasource_list: [ $list ]" "$@"      return  } diff --git a/tools/net-convert.py b/tools/net-convert.py new file mode 100755 index 00000000..870da639 --- /dev/null +++ b/tools/net-convert.py @@ -0,0 +1,84 @@ +#!/usr/bin/python3 +# This file is part of cloud-init. See LICENSE file for license information. + +import argparse +import json +import os +import yaml + +from cloudinit.sources.helpers import openstack + +from cloudinit.net import eni +from cloudinit.net import network_state +from cloudinit.net import netplan +from cloudinit.net import sysconfig + + +def main(): +    parser = argparse.ArgumentParser() +    parser.add_argument("--network-data", "-p", type=open, +                        metavar="PATH", required=True) +    parser.add_argument("--kind", "-k", +                        choices=['eni', 'network_data.json', 'yaml'], +                        required=True) +    parser.add_argument("-d", "--directory", +                        metavar="PATH", +                        help="directory to place output in", +                        required=True) +    parser.add_argument("-m", "--mac", +                        metavar="name,mac", +                        action='append', +                        help="interface name to mac mapping") +    parser.add_argument("--output-kind", "-ok", +                        choices=['eni', 'netplan', 'sysconfig'], +                        required=True) +    args = parser.parse_args() + +    if not os.path.isdir(args.directory): +        os.makedirs(args.directory) + +    if args.mac: +        known_macs = {} +        for item in args.mac: +            iface_name, iface_mac = item.split(",", 1) +            known_macs[iface_mac] = iface_name +    else: +        known_macs = None + +    net_data = args.network_data.read() +    if args.kind == "eni": +        pre_ns = eni.convert_eni_data(net_data) +        ns = network_state.parse_net_config_data(pre_ns) +    elif args.kind == "yaml": +        pre_ns = yaml.load(net_data) +        if 'network' in pre_ns: +            pre_ns = pre_ns.get('network') +        print("Input YAML") +        print(yaml.dump(pre_ns, default_flow_style=False, indent=4)) +        ns = network_state.parse_net_config_data(pre_ns) +    else: +        pre_ns = openstack.convert_net_json( +            json.loads(net_data), known_macs=known_macs) +        ns = network_state.parse_net_config_data(pre_ns) + +    if not ns: +        raise RuntimeError("No valid network_state object created from" +                           "input data") + +    print("\nInternal State") +    print(yaml.dump(ns, default_flow_style=False, indent=4)) +    if args.output_kind == "eni": +        r_cls = eni.Renderer +    elif args.output_kind == "netplan": +        r_cls = netplan.Renderer +    else: +        r_cls = sysconfig.Renderer + +    r = r_cls() +    r.render_network_state(ns, target=args.directory) + + +if __name__ == '__main__': +    main() + +# vi: ts=4 expandtab | 
