summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cloudinit/config/cc_chef.py4
-rw-r--r--cloudinit/config/cc_mcollective.py10
-rw-r--r--cloudinit/config/cc_ntp.py20
-rw-r--r--cloudinit/config/cc_power_state_change.py9
-rw-r--r--cloudinit/config/cc_rsyslog.py7
-rw-r--r--cloudinit/config/cc_ubuntu_advantage.py4
-rw-r--r--cloudinit/config/cc_write_files.py3
-rw-r--r--cloudinit/config/cc_yum_add_repo.py12
-rwxr-xr-xcloudinit/distros/__init__.py13
-rw-r--r--cloudinit/distros/freebsd.py7
-rw-r--r--cloudinit/distros/parsers/sys_conf.py6
-rwxr-xr-xcloudinit/distros/ug_util.py22
-rw-r--r--cloudinit/net/network_state.py11
-rw-r--r--cloudinit/net/renderer.py4
-rw-r--r--cloudinit/net/sysconfig.py15
-rw-r--r--cloudinit/sources/tests/test_init.py33
-rw-r--r--cloudinit/sources/tests/test_oracle.py3
-rw-r--r--cloudinit/stages.py6
-rw-r--r--cloudinit/tests/helpers.py15
-rw-r--r--tests/unittests/test_cli.py16
-rw-r--r--tests/unittests/test_datasource/test_smartos.py4
-rw-r--r--tests/unittests/test_handler/test_handler_chef.py3
-rw-r--r--tests/unittests/test_handler/test_handler_write_files.py15
-rw-r--r--tests/unittests/test_log.py11
-rw-r--r--tests/unittests/test_merging.py6
-rw-r--r--tests/unittests/test_util.py17
26 files changed, 104 insertions, 172 deletions
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
index 0ad6b7f1..01d61fa1 100644
--- a/cloudinit/config/cc_chef.py
+++ b/cloudinit/config/cc_chef.py
@@ -79,8 +79,6 @@ from cloudinit import templater
from cloudinit import url_helper
from cloudinit import util
-import six
-
RUBY_VERSION_DEFAULT = "1.8"
CHEF_DIRS = tuple([
@@ -273,7 +271,7 @@ def run_chef(chef_cfg, log):
cmd_args = chef_cfg['exec_arguments']
if isinstance(cmd_args, (list, tuple)):
cmd.extend(cmd_args)
- elif isinstance(cmd_args, six.string_types):
+ elif isinstance(cmd_args, str):
cmd.append(cmd_args)
else:
log.warning("Unknown type %s provided for chef"
diff --git a/cloudinit/config/cc_mcollective.py b/cloudinit/config/cc_mcollective.py
index d5f63f5f..351183f1 100644
--- a/cloudinit/config/cc_mcollective.py
+++ b/cloudinit/config/cc_mcollective.py
@@ -49,9 +49,7 @@ private certificates for mcollective. Their values will be written to
"""
import errno
-
-import six
-from six import BytesIO
+import io
# Used since this can maintain comments
# and doesn't need a top level section
@@ -73,7 +71,7 @@ def configure(config, server_cfg=SERVER_CFG,
# original file in order to be able to mix the rest up.
try:
old_contents = util.load_file(server_cfg, quiet=False, decode=False)
- mcollective_config = ConfigObj(BytesIO(old_contents))
+ mcollective_config = ConfigObj(io.BytesIO(old_contents))
except IOError as e:
if e.errno != errno.ENOENT:
raise
@@ -93,7 +91,7 @@ def configure(config, server_cfg=SERVER_CFG,
'plugin.ssl_server_private'] = pricert_file
mcollective_config['securityprovider'] = 'ssl'
else:
- if isinstance(cfg, six.string_types):
+ if isinstance(cfg, str):
# Just set it in the 'main' section
mcollective_config[cfg_name] = cfg
elif isinstance(cfg, (dict)):
@@ -119,7 +117,7 @@ def configure(config, server_cfg=SERVER_CFG,
raise
# Now we got the whole (new) file, write to disk...
- contents = BytesIO()
+ contents = io.BytesIO()
mcollective_config.write(contents)
util.write_file(server_cfg, contents.getvalue(), mode=0o644)
diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py
index 9e074bda..5498bbaa 100644
--- a/cloudinit/config/cc_ntp.py
+++ b/cloudinit/config/cc_ntp.py
@@ -6,19 +6,17 @@
"""NTP: enable and configure ntp"""
-from cloudinit.config.schema import (
- get_schema_doc, validate_cloudconfig_schema)
+import copy
+import os
+from textwrap import dedent
+
from cloudinit import log as logging
-from cloudinit.settings import PER_INSTANCE
from cloudinit import temp_utils
from cloudinit import templater
from cloudinit import type_utils
from cloudinit import util
-
-import copy
-import os
-import six
-from textwrap import dedent
+from cloudinit.config.schema import get_schema_doc, validate_cloudconfig_schema
+from cloudinit.settings import PER_INSTANCE
LOG = logging.getLogger(__name__)
@@ -460,7 +458,7 @@ def supplemental_schema_validation(ntp_config):
for key, value in sorted(ntp_config.items()):
keypath = 'ntp:config:' + key
if key == 'confpath':
- if not all([value, isinstance(value, six.string_types)]):
+ if not all([value, isinstance(value, str)]):
errors.append(
'Expected a config file path {keypath}.'
' Found ({value})'.format(keypath=keypath, value=value))
@@ -472,11 +470,11 @@ def supplemental_schema_validation(ntp_config):
elif key in ('template', 'template_name'):
if value is None: # Either template or template_name can be none
continue
- if not isinstance(value, six.string_types):
+ if not isinstance(value, str):
errors.append(
'Expected a string type for {keypath}.'
' Found ({value})'.format(keypath=keypath, value=value))
- elif not isinstance(value, six.string_types):
+ elif not isinstance(value, str):
errors.append(
'Expected a string type for {keypath}.'
' Found ({value})'.format(keypath=keypath, value=value))
diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py
index 43a479cf..3e81a3c7 100644
--- a/cloudinit/config/cc_power_state_change.py
+++ b/cloudinit/config/cc_power_state_change.py
@@ -49,16 +49,15 @@ key returns 0.
condition: <true/false/command>
"""
-from cloudinit.settings import PER_INSTANCE
-from cloudinit import util
-
import errno
import os
import re
-import six
import subprocess
import time
+from cloudinit.settings import PER_INSTANCE
+from cloudinit import util
+
frequency = PER_INSTANCE
EXIT_FAIL = 254
@@ -183,7 +182,7 @@ def load_power_state(cfg):
pstate['timeout'])
condition = pstate.get("condition", True)
- if not isinstance(condition, six.string_types + (list, bool)):
+ if not isinstance(condition, (str, list, bool)):
raise TypeError("condition type %s invalid. must be list, bool, str")
return (args, timeout, condition)
diff --git a/cloudinit/config/cc_rsyslog.py b/cloudinit/config/cc_rsyslog.py
index ff211f65..5df0137d 100644
--- a/cloudinit/config/cc_rsyslog.py
+++ b/cloudinit/config/cc_rsyslog.py
@@ -180,7 +180,6 @@ config entries. Legacy to new mappings are as follows:
import os
import re
-import six
from cloudinit import log as logging
from cloudinit import util
@@ -233,9 +232,9 @@ def load_config(cfg):
fillup = (
(KEYNAME_CONFIGS, [], list),
- (KEYNAME_DIR, DEF_DIR, six.string_types),
- (KEYNAME_FILENAME, DEF_FILENAME, six.string_types),
- (KEYNAME_RELOAD, DEF_RELOAD, six.string_types + (list,)),
+ (KEYNAME_DIR, DEF_DIR, str),
+ (KEYNAME_FILENAME, DEF_FILENAME, str),
+ (KEYNAME_RELOAD, DEF_RELOAD, (str, list)),
(KEYNAME_REMOTES, DEF_REMOTES, dict))
for key, default, vtypes in fillup:
diff --git a/cloudinit/config/cc_ubuntu_advantage.py b/cloudinit/config/cc_ubuntu_advantage.py
index f846e9a5..8b6d2a1a 100644
--- a/cloudinit/config/cc_ubuntu_advantage.py
+++ b/cloudinit/config/cc_ubuntu_advantage.py
@@ -4,8 +4,6 @@
from textwrap import dedent
-import six
-
from cloudinit.config.schema import (
get_schema_doc, validate_cloudconfig_schema)
from cloudinit import log as logging
@@ -98,7 +96,7 @@ def configure_ua(token=None, enable=None):
if enable is None:
enable = []
- elif isinstance(enable, six.string_types):
+ elif isinstance(enable, str):
LOG.warning('ubuntu_advantage: enable should be a list, not'
' a string; treating as a single enable')
enable = [enable]
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
index 0b6546e2..bd87e9e5 100644
--- a/cloudinit/config/cc_write_files.py
+++ b/cloudinit/config/cc_write_files.py
@@ -57,7 +57,6 @@ binary gzip data can be specified and will be decoded before being written.
import base64
import os
-import six
from cloudinit import log as logging
from cloudinit.settings import PER_INSTANCE
@@ -126,7 +125,7 @@ def decode_perms(perm, default):
if perm is None:
return default
try:
- if isinstance(perm, six.integer_types + (float,)):
+ if isinstance(perm, (int, float)):
# Just 'downcast' it (if a float)
return int(perm)
else:
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
index 3b354a7d..3673166a 100644
--- a/cloudinit/config/cc_yum_add_repo.py
+++ b/cloudinit/config/cc_yum_add_repo.py
@@ -30,13 +30,9 @@ entry, the config entry will be skipped.
# any repository configuration options (see man yum.conf)
"""
+import io
import os
-
-try:
- from configparser import ConfigParser
-except ImportError:
- from ConfigParser import ConfigParser
-import six
+from configparser import ConfigParser
from cloudinit import util
@@ -57,7 +53,7 @@ def _format_repo_value(val):
# Can handle 'lists' in certain cases
# See: https://linux.die.net/man/5/yum.conf
return "\n".join([_format_repo_value(v) for v in val])
- if not isinstance(val, six.string_types):
+ if not isinstance(val, str):
return str(val)
return val
@@ -72,7 +68,7 @@ def _format_repository_config(repo_id, repo_config):
# For now assume that people using this know
# the format of yum and don't verify keys/values further
to_be.set(repo_id, k, _format_repo_value(v))
- to_be_stream = six.StringIO()
+ to_be_stream = io.StringIO()
to_be.write(to_be_stream)
to_be_stream.seek(0)
lines = to_be_stream.readlines()
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index cdce26f2..92598a2d 100755
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -9,13 +9,11 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
-import six
-from six import StringIO
-
import abc
import os
import re
import stat
+from io import StringIO
from cloudinit import importer
from cloudinit import log as logging
@@ -53,8 +51,7 @@ _EC2_AZ_RE = re.compile('^[a-z][a-z]-(?:[a-z]+-)+[0-9][a-z]$')
PREFERRED_NTP_CLIENTS = ['chrony', 'systemd-timesyncd', 'ntp', 'ntpdate']
-@six.add_metaclass(abc.ABCMeta)
-class Distro(object):
+class Distro(metaclass=abc.ABCMeta):
usr_lib_exec = "/usr/lib"
hosts_fn = "/etc/hosts"
@@ -429,7 +426,7 @@ class Distro(object):
# support kwargs having groups=[list] or groups="g1,g2"
groups = kwargs.get('groups')
if groups:
- if isinstance(groups, six.string_types):
+ if isinstance(groups, str):
groups = groups.split(",")
# remove any white spaces in group names, most likely
@@ -544,7 +541,7 @@ class Distro(object):
if 'ssh_authorized_keys' in kwargs:
# Try to handle this in a smart manner.
keys = kwargs['ssh_authorized_keys']
- if isinstance(keys, six.string_types):
+ if isinstance(keys, str):
keys = [keys]
elif isinstance(keys, dict):
keys = list(keys.values())
@@ -668,7 +665,7 @@ class Distro(object):
if isinstance(rules, (list, tuple)):
for rule in rules:
lines.append("%s %s" % (user, rule))
- elif isinstance(rules, six.string_types):
+ elif isinstance(rules, str):
lines.append("%s %s" % (user, rules))
else:
msg = "Can not create sudoers rule addition with type %r"
diff --git a/cloudinit/distros/freebsd.py b/cloudinit/distros/freebsd.py
index 40e435e7..026d1142 100644
--- a/cloudinit/distros/freebsd.py
+++ b/cloudinit/distros/freebsd.py
@@ -5,10 +5,8 @@
# This file is part of cloud-init. See LICENSE file for license information.
import os
-import six
-from six import StringIO
-
import re
+from io import StringIO
from cloudinit import distros
from cloudinit import helpers
@@ -108,8 +106,7 @@ class Distro(distros.Distro):
}
for key, val in kwargs.items():
- if (key in pw_useradd_opts and val and
- isinstance(val, six.string_types)):
+ if key in pw_useradd_opts and val and isinstance(val, str):
pw_useradd_cmd.extend([pw_useradd_opts[key], val])
elif key in pw_useradd_flags and val:
diff --git a/cloudinit/distros/parsers/sys_conf.py b/cloudinit/distros/parsers/sys_conf.py
index 44df17de..dee4c551 100644
--- a/cloudinit/distros/parsers/sys_conf.py
+++ b/cloudinit/distros/parsers/sys_conf.py
@@ -4,11 +4,9 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
-import six
-from six import StringIO
-
import pipes
import re
+from io import StringIO
# This library is used to parse/write
# out the various sysconfig files edited (best attempt effort)
@@ -65,7 +63,7 @@ class SysConf(configobj.ConfigObj):
return out_contents.getvalue()
def _quote(self, value, multiline=False):
- if not isinstance(value, six.string_types):
+ if not isinstance(value, str):
raise ValueError('Value "%s" is not a string' % (value))
if len(value) == 0:
return ''
diff --git a/cloudinit/distros/ug_util.py b/cloudinit/distros/ug_util.py
index 9378dd78..08446a95 100755
--- a/cloudinit/distros/ug_util.py
+++ b/cloudinit/distros/ug_util.py
@@ -9,8 +9,6 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
-import six
-
from cloudinit import log as logging
from cloudinit import type_utils
from cloudinit import util
@@ -29,7 +27,7 @@ LOG = logging.getLogger(__name__)
# is the standard form used in the rest
# of cloud-init
def _normalize_groups(grp_cfg):
- if isinstance(grp_cfg, six.string_types):
+ if isinstance(grp_cfg, str):
grp_cfg = grp_cfg.strip().split(",")
if isinstance(grp_cfg, list):
c_grp_cfg = {}
@@ -39,7 +37,7 @@ def _normalize_groups(grp_cfg):
if k not in c_grp_cfg:
if isinstance(v, list):
c_grp_cfg[k] = list(v)
- elif isinstance(v, six.string_types):
+ elif isinstance(v, str):
c_grp_cfg[k] = [v]
else:
raise TypeError("Bad group member type %s" %
@@ -47,12 +45,12 @@ def _normalize_groups(grp_cfg):
else:
if isinstance(v, list):
c_grp_cfg[k].extend(v)
- elif isinstance(v, six.string_types):
+ elif isinstance(v, str):
c_grp_cfg[k].append(v)
else:
raise TypeError("Bad group member type %s" %
type_utils.obj_name(v))
- elif isinstance(i, six.string_types):
+ elif isinstance(i, str):
if i not in c_grp_cfg:
c_grp_cfg[i] = []
else:
@@ -89,7 +87,7 @@ def _normalize_users(u_cfg, def_user_cfg=None):
if isinstance(u_cfg, dict):
ad_ucfg = []
for (k, v) in u_cfg.items():
- if isinstance(v, (bool, int, float) + six.string_types):
+ if isinstance(v, (bool, int, float, str)):
if util.is_true(v):
ad_ucfg.append(str(k))
elif isinstance(v, dict):
@@ -99,12 +97,12 @@ def _normalize_users(u_cfg, def_user_cfg=None):
raise TypeError(("Unmappable user value type %s"
" for key %s") % (type_utils.obj_name(v), k))
u_cfg = ad_ucfg
- elif isinstance(u_cfg, six.string_types):
+ elif isinstance(u_cfg, str):
u_cfg = util.uniq_merge_sorted(u_cfg)
users = {}
for user_config in u_cfg:
- if isinstance(user_config, (list,) + six.string_types):
+ if isinstance(user_config, (list, str)):
for u in util.uniq_merge(user_config):
if u and u not in users:
users[u] = {}
@@ -209,7 +207,7 @@ def normalize_users_groups(cfg, distro):
old_user = cfg['user']
# Translate it into the format that is more useful
# going forward
- if isinstance(old_user, six.string_types):
+ if isinstance(old_user, str):
old_user = {
'name': old_user,
}
@@ -238,7 +236,7 @@ def normalize_users_groups(cfg, distro):
default_user_config = util.mergemanydict([old_user, distro_user_config])
base_users = cfg.get('users', [])
- if not isinstance(base_users, (list, dict) + six.string_types):
+ if not isinstance(base_users, (list, dict, str)):
LOG.warning(("Format for 'users' key must be a comma separated string"
" or a dictionary or a list and not %s"),
type_utils.obj_name(base_users))
@@ -252,7 +250,7 @@ def normalize_users_groups(cfg, distro):
base_users.append({'name': 'default'})
elif isinstance(base_users, dict):
base_users['default'] = dict(base_users).get('default', True)
- elif isinstance(base_users, six.string_types):
+ elif isinstance(base_users, str):
# Just append it on to be re-parsed later
base_users += ",default"
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index 9b126100..63d6e291 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -10,8 +10,6 @@ import logging
import socket
import struct
-import six
-
from cloudinit import safeyaml
from cloudinit import util
@@ -186,7 +184,7 @@ class NetworkState(object):
def iter_interfaces(self, filter_func=None):
ifaces = self._network_state.get('interfaces', {})
- for iface in six.itervalues(ifaces):
+ for iface in ifaces.values():
if filter_func is None:
yield iface
else:
@@ -220,8 +218,7 @@ class NetworkState(object):
)
-@six.add_metaclass(CommandHandlerMeta)
-class NetworkStateInterpreter(object):
+class NetworkStateInterpreter(metaclass=CommandHandlerMeta):
initial_network_state = {
'interfaces': {},
@@ -970,7 +967,7 @@ def ipv4_mask_to_net_prefix(mask):
"""
if isinstance(mask, int):
return mask
- if isinstance(mask, six.string_types):
+ if isinstance(mask, str):
try:
return int(mask)
except ValueError:
@@ -997,7 +994,7 @@ def ipv6_mask_to_net_prefix(mask):
if isinstance(mask, int):
return mask
- if isinstance(mask, six.string_types):
+ if isinstance(mask, str):
try:
return int(mask)
except ValueError:
diff --git a/cloudinit/net/renderer.py b/cloudinit/net/renderer.py
index 5f32e90f..2a61a7a8 100644
--- a/cloudinit/net/renderer.py
+++ b/cloudinit/net/renderer.py
@@ -6,7 +6,7 @@
# This file is part of cloud-init. See LICENSE file for license information.
import abc
-import six
+import io
from .network_state import parse_net_config_data
from .udev import generate_udev_rule
@@ -34,7 +34,7 @@ class Renderer(object):
"""Given state, emit udev rules to map mac to ifname."""
# TODO(harlowja): this seems shared between eni renderer and
# this, so move it to a shared location.
- content = six.StringIO()
+ content = io.StringIO()
for iface in network_state.iter_interfaces(filter_by_physical):
# for physical interfaces write out a persist net udev rule
if 'name' in iface and iface.get('mac_address'):
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 3e06af01..07668d3e 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -1,16 +1,15 @@
# This file is part of cloud-init. See LICENSE file for license information.
+import io
import os
import re
-import six
+from configobj import ConfigObj
-from cloudinit.distros.parsers import networkmanager_conf
-from cloudinit.distros.parsers import resolv_conf
from cloudinit import log as logging
from cloudinit import util
-
-from configobj import ConfigObj
+from cloudinit.distros.parsers import networkmanager_conf
+from cloudinit.distros.parsers import resolv_conf
from . import renderer
from .network_state import (
@@ -96,7 +95,7 @@ class ConfigMap(object):
return len(self._conf)
def to_string(self):
- buf = six.StringIO()
+ buf = io.StringIO()
buf.write(_make_header())
if self._conf:
buf.write("\n")
@@ -104,7 +103,7 @@ class ConfigMap(object):
value = self._conf[key]
if isinstance(value, bool):
value = self._bool_map[value]
- if not isinstance(value, six.string_types):
+ if not isinstance(value, str):
value = str(value)
buf.write("%s=%s\n" % (key, _quote_value(value)))
return buf.getvalue()
@@ -150,7 +149,7 @@ class Route(ConfigMap):
# only accept ipv4 and ipv6
if proto not in ['ipv4', 'ipv6']:
raise ValueError("Unknown protocol '%s'" % (str(proto)))
- buf = six.StringIO()
+ buf = io.StringIO()
buf.write(_make_header())
if self._conf:
buf.write("\n")
diff --git a/cloudinit/sources/tests/test_init.py b/cloudinit/sources/tests/test_init.py
index 9698261b..f73b37ed 100644
--- a/cloudinit/sources/tests/test_init.py
+++ b/cloudinit/sources/tests/test_init.py
@@ -3,7 +3,6 @@
import copy
import inspect
import os
-import six
import stat
from cloudinit.event import EventType
@@ -13,7 +12,7 @@ from cloudinit.sources import (
EXPERIMENTAL_TEXT, INSTANCE_JSON_FILE, INSTANCE_JSON_SENSITIVE_FILE,
METADATA_UNKNOWN, REDACT_SENSITIVE_VALUE, UNSET, DataSource,
canonical_cloud_id, redact_sensitive_keys)
-from cloudinit.tests.helpers import CiTestCase, skipIf, mock
+from cloudinit.tests.helpers import CiTestCase, mock
from cloudinit.user_data import UserDataProcessor
from cloudinit import util
@@ -422,7 +421,6 @@ class TestDataSource(CiTestCase):
{'network_json': 'is good'},
instance_data['ds']['network_json'])
- @skipIf(not six.PY3, "json serialization on <= py2.7 handles bytes")
def test_get_data_base64encodes_unserializable_bytes(self):
"""On py3, get_data base64encodes any unserializable content."""
tmp = self.tmp_dir()
@@ -440,35 +438,6 @@ class TestDataSource(CiTestCase):
{'key1': 'val1', 'key2': {'key2.1': 'EjM='}},
instance_json['ds']['meta_data'])
- @skipIf(not six.PY2, "json serialization on <= py2.7 handles bytes")
- def test_get_data_handles_bytes_values(self):
- """On py2 get_data handles bytes values without having to b64encode."""
- tmp = self.tmp_dir()
- datasource = DataSourceTestSubclassNet(
- self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
- custom_metadata={'key1': 'val1', 'key2': {'key2.1': b'\x123'}})
- self.assertTrue(datasource.get_data())
- json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
- content = util.load_file(json_file)
- instance_json = util.load_json(content)
- self.assertEqual([], instance_json['base64_encoded_keys'])
- self.assertEqual(
- {'key1': 'val1', 'key2': {'key2.1': '\x123'}},
- instance_json['ds']['meta_data'])
-
- @skipIf(not six.PY2, "Only python2 hits UnicodeDecodeErrors on non-utf8")
- def test_non_utf8_encoding_gets_b64encoded(self):
- """When non-utf-8 values exist in py2 instance-data is b64encoded."""
- tmp = self.tmp_dir()
- datasource = DataSourceTestSubclassNet(
- self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
- custom_metadata={'key1': 'val1', 'key2': {'key2.1': b'ab\xaadef'}})
- self.assertTrue(datasource.get_data())
- json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
- instance_json = util.load_json(util.load_file(json_file))
- key21_value = instance_json['ds']['meta_data']['key2']['key2.1']
- self.assertEqual('ci-b64:' + util.b64e(b'ab\xaadef'), key21_value)
-
def test_get_hostname_subclass_support(self):
"""Validate get_hostname signature on all subclasses of DataSource."""
# Use inspect.getfullargspec when we drop py2.6 and py2.7
diff --git a/cloudinit/sources/tests/test_oracle.py b/cloudinit/sources/tests/test_oracle.py
index 85b6db97..6c551fcb 100644
--- a/cloudinit/sources/tests/test_oracle.py
+++ b/cloudinit/sources/tests/test_oracle.py
@@ -13,7 +13,6 @@ import httpretty
import json
import mock
import os
-import six
import uuid
DS_PATH = "cloudinit.sources.DataSourceOracle"
@@ -334,7 +333,7 @@ class TestReadMetaData(test_helpers.HttprettyTestCase):
for k, v in data.items():
httpretty.register_uri(
httpretty.GET, self.mdurl + MD_VER + "/" + k,
- v if not isinstance(v, six.text_type) else v.encode('utf-8'))
+ v if not isinstance(v, str) else v.encode('utf-8'))
def test_broken_no_sys_uuid(self, m_read_system_uuid):
"""Datasource requires ability to read system_uuid and true return."""
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 71f3a49e..db8ba64c 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -6,11 +6,9 @@
import copy
import os
+import pickle
import sys
-import six
-from six.moves import cPickle as pickle
-
from cloudinit.settings import (
FREQUENCIES, CLOUD_CONFIG, PER_INSTANCE, RUN_CLOUD_CONFIG)
@@ -758,7 +756,7 @@ class Modules(object):
for item in cfg_mods:
if not item:
continue
- if isinstance(item, six.string_types):
+ if isinstance(item, str):
module_list.append({
'mod': item.strip(),
})
diff --git a/cloudinit/tests/helpers.py b/cloudinit/tests/helpers.py
index 4dad2afd..0220648d 100644
--- a/cloudinit/tests/helpers.py
+++ b/cloudinit/tests/helpers.py
@@ -4,6 +4,7 @@ from __future__ import print_function
import functools
import httpretty
+import io
import logging
import os
import random
@@ -14,7 +15,6 @@ import tempfile
import time
import mock
-import six
import unittest2
from unittest2.util import strclass
@@ -72,7 +72,7 @@ def retarget_many_wrapper(new_base, am, old_func):
# Python 3 some of these now accept file-descriptors (integers).
# That breaks rebase_path() so in lieu of a better solution, just
# don't rebase if we get a fd.
- if isinstance(path, six.string_types):
+ if isinstance(path, str):
n_args[i] = rebase_path(path, new_base)
return old_func(*n_args, **kwds)
return wrapper
@@ -149,7 +149,7 @@ class CiTestCase(TestCase):
if self.with_logs:
# Create a log handler so unit tests can search expected logs.
self.logger = logging.getLogger()
- self.logs = six.StringIO()
+ self.logs = io.StringIO()
formatter = logging.Formatter('%(levelname)s: %(message)s')
handler = logging.StreamHandler(self.logs)
handler.setFormatter(formatter)
@@ -166,7 +166,7 @@ class CiTestCase(TestCase):
else:
cmd = args[0]
- if not isinstance(cmd, six.string_types):
+ if not isinstance(cmd, str):
cmd = cmd[0]
pass_through = False
if not isinstance(self.allowed_subp, (list, bool)):
@@ -346,8 +346,9 @@ class FilesystemMockingTestCase(ResourceUsingTestCase):
def patchOpen(self, new_root):
trap_func = retarget_many_wrapper(new_root, 1, open)
- name = 'builtins.open' if six.PY3 else '__builtin__.open'
- self.patched_funcs.enter_context(mock.patch(name, trap_func))
+ self.patched_funcs.enter_context(
+ mock.patch('builtins.open', trap_func)
+ )
def patchStdoutAndStderr(self, stdout=None, stderr=None):
if stdout is not None:
@@ -420,7 +421,7 @@ def populate_dir(path, files):
p = os.path.sep.join([path, name])
util.ensure_dir(os.path.dirname(p))
with open(p, "wb") as fp:
- if isinstance(content, six.binary_type):
+ if isinstance(content, bytes):
fp.write(content)
else:
fp.write(content.encode('utf-8'))
diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py
index d283f136..e57c15d1 100644
--- a/tests/unittests/test_cli.py
+++ b/tests/unittests/test_cli.py
@@ -1,8 +1,8 @@
# This file is part of cloud-init. See LICENSE file for license information.
-from collections import namedtuple
import os
-import six
+import io
+from collections import namedtuple
from cloudinit.cmd import main as cli
from cloudinit.tests import helpers as test_helpers
@@ -18,7 +18,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def setUp(self):
super(TestCLI, self).setUp()
- self.stderr = six.StringIO()
+ self.stderr = io.StringIO()
self.patchStdoutAndStderr(stderr=self.stderr)
def _call_main(self, sysv_args=None):
@@ -147,7 +147,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def test_conditional_subcommands_from_entry_point_sys_argv(self):
"""Subcommands from entry-point are properly parsed from sys.argv."""
- stdout = six.StringIO()
+ stdout = io.StringIO()
self.patchStdoutAndStderr(stdout=stdout)
expected_errors = [
@@ -178,7 +178,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def test_collect_logs_subcommand_parser(self):
"""The subcommand cloud-init collect-logs calls the subparser."""
# Provide -h param to collect-logs to avoid having to mock behavior.
- stdout = six.StringIO()
+ stdout = io.StringIO()
self.patchStdoutAndStderr(stdout=stdout)
self._call_main(['cloud-init', 'collect-logs', '-h'])
self.assertIn('usage: cloud-init collect-log', stdout.getvalue())
@@ -186,7 +186,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def test_clean_subcommand_parser(self):
"""The subcommand cloud-init clean calls the subparser."""
# Provide -h param to clean to avoid having to mock behavior.
- stdout = six.StringIO()
+ stdout = io.StringIO()
self.patchStdoutAndStderr(stdout=stdout)
self._call_main(['cloud-init', 'clean', '-h'])
self.assertIn('usage: cloud-init clean', stdout.getvalue())
@@ -194,7 +194,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def test_status_subcommand_parser(self):
"""The subcommand cloud-init status calls the subparser."""
# Provide -h param to clean to avoid having to mock behavior.
- stdout = six.StringIO()
+ stdout = io.StringIO()
self.patchStdoutAndStderr(stdout=stdout)
self._call_main(['cloud-init', 'status', '-h'])
self.assertIn('usage: cloud-init status', stdout.getvalue())
@@ -219,7 +219,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
def test_wb_devel_schema_subcommand_doc_content(self):
"""Validate that doc content is sane from known examples."""
- stdout = six.StringIO()
+ stdout = io.StringIO()
self.patchStdoutAndStderr(stdout=stdout)
self._call_main(['cloud-init', 'devel', 'schema', '--doc'])
expected_doc_sections = [
diff --git a/tests/unittests/test_datasource/test_smartos.py b/tests/unittests/test_datasource/test_smartos.py
index d5b1c29c..62084de5 100644
--- a/tests/unittests/test_datasource/test_smartos.py
+++ b/tests/unittests/test_datasource/test_smartos.py
@@ -33,8 +33,6 @@ from cloudinit.sources.DataSourceSmartOS import (
identify_file)
from cloudinit.event import EventType
-import six
-
from cloudinit import helpers as c_helpers
from cloudinit.util import (
b64e, subp, ProcessExecutionError, which, write_file)
@@ -798,7 +796,7 @@ class TestJoyentMetadataClient(FilesystemMockingTestCase):
return self.serial.write.call_args[0][0]
def test_get_metadata_writes_bytes(self):
- self.assertIsInstance(self._get_written_line(), six.binary_type)
+ self.assertIsInstance(self._get_written_line(), bytes)
def test_get_metadata_line_starts_with_v2(self):
foo = self._get_written_line()
diff --git a/tests/unittests/test_handler/test_handler_chef.py b/tests/unittests/test_handler/test_handler_chef.py
index f4311268..2dab3a54 100644
--- a/tests/unittests/test_handler/test_handler_chef.py
+++ b/tests/unittests/test_handler/test_handler_chef.py
@@ -4,7 +4,6 @@ import httpretty
import json
import logging
import os
-import six
from cloudinit import cloud
from cloudinit.config import cc_chef
@@ -178,7 +177,7 @@ class TestChef(FilesystemMockingTestCase):
continue
# the value from the cfg overrides that in the default
val = cfg['chef'].get(k, v)
- if isinstance(val, six.string_types):
+ if isinstance(val, str):
self.assertIn(val, c)
c = util.load_file(cc_chef.CHEF_FB_PATH)
self.assertEqual({}, json.loads(c))
diff --git a/tests/unittests/test_handler/test_handler_write_files.py b/tests/unittests/test_handler/test_handler_write_files.py
index bc8756ca..ed0a4da2 100644
--- a/tests/unittests/test_handler/test_handler_write_files.py
+++ b/tests/unittests/test_handler/test_handler_write_files.py
@@ -1,17 +1,16 @@
# This file is part of cloud-init. See LICENSE file for license information.
-from cloudinit.config.cc_write_files import write_files, decode_perms
-from cloudinit import log as logging
-from cloudinit import util
-
-from cloudinit.tests.helpers import CiTestCase, FilesystemMockingTestCase
-
import base64
import gzip
+import io
import shutil
-import six
import tempfile
+from cloudinit import log as logging
+from cloudinit import util
+from cloudinit.config.cc_write_files import write_files, decode_perms
+from cloudinit.tests.helpers import CiTestCase, FilesystemMockingTestCase
+
LOG = logging.getLogger(__name__)
YAML_TEXT = """
@@ -138,7 +137,7 @@ class TestDecodePerms(CiTestCase):
def _gzip_bytes(data):
- buf = six.BytesIO()
+ buf = io.BytesIO()
fp = None
try:
fp = gzip.GzipFile(fileobj=buf, mode="wb")
diff --git a/tests/unittests/test_log.py b/tests/unittests/test_log.py
index cd6296d6..e069a487 100644
--- a/tests/unittests/test_log.py
+++ b/tests/unittests/test_log.py
@@ -2,14 +2,15 @@
"""Tests for cloudinit.log """
-from cloudinit.analyze.dump import CLOUD_INIT_ASCTIME_FMT
-from cloudinit import log as ci_logging
-from cloudinit.tests.helpers import CiTestCase
import datetime
+import io
import logging
-import six
import time
+from cloudinit import log as ci_logging
+from cloudinit.analyze.dump import CLOUD_INIT_ASCTIME_FMT
+from cloudinit.tests.helpers import CiTestCase
+
class TestCloudInitLogger(CiTestCase):
@@ -18,7 +19,7 @@ class TestCloudInitLogger(CiTestCase):
# of sys.stderr, we'll plug in a StringIO() object so we can see
# what gets logged
logging.Formatter.converter = time.gmtime
- self.ci_logs = six.StringIO()
+ self.ci_logs = io.StringIO()
self.ci_root = logging.getLogger()
console = logging.StreamHandler(self.ci_logs)
console.setFormatter(logging.Formatter(ci_logging.DEF_CON_FORMAT))
diff --git a/tests/unittests/test_merging.py b/tests/unittests/test_merging.py
index 3a5072c7..10871bcf 100644
--- a/tests/unittests/test_merging.py
+++ b/tests/unittests/test_merging.py
@@ -13,13 +13,11 @@ import glob
import os
import random
import re
-import six
import string
SOURCE_PAT = "source*.*yaml"
EXPECTED_PAT = "expected%s.yaml"
-TYPES = [dict, str, list, tuple, None]
-TYPES.extend(six.integer_types)
+TYPES = [dict, str, list, tuple, None, int]
def _old_mergedict(src, cand):
@@ -85,7 +83,7 @@ def _make_dict(current_depth, max_depth, rand):
pass
if t in [tuple]:
base = tuple(base)
- elif t in six.integer_types:
+ elif t in [int]:
base = rand.randint(0, 2 ** 8)
elif t in [str]:
base = _random_str(rand)
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 0e71db82..75a3f0b4 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -2,16 +2,15 @@
from __future__ import print_function
+import io
+import json
import logging
import os
import re
import shutil
import stat
-import tempfile
-
-import json
-import six
import sys
+import tempfile
import yaml
from cloudinit import importer, util
@@ -320,7 +319,7 @@ class TestLoadYaml(helpers.CiTestCase):
def test_python_unicode(self):
# complex type of python/unicode is explicitly allowed
- myobj = {'1': six.text_type("FOOBAR")}
+ myobj = {'1': "FOOBAR"}
safe_yaml = yaml.dump(myobj)
self.assertEqual(util.load_yaml(blob=safe_yaml,
default=self.mydefault),
@@ -663,8 +662,8 @@ class TestMultiLog(helpers.FilesystemMockingTestCase):
self.patchOS(self.root)
self.patchUtils(self.root)
self.patchOpen(self.root)
- self.stdout = six.StringIO()
- self.stderr = six.StringIO()
+ self.stdout = io.StringIO()
+ self.stderr = io.StringIO()
self.patchStdoutAndStderr(self.stdout, self.stderr)
def test_stderr_used_by_default(self):
@@ -879,8 +878,8 @@ class TestSubp(helpers.CiTestCase):
"""Raised exc should have stderr, stdout as string if no decode."""
with self.assertRaises(util.ProcessExecutionError) as cm:
util.subp([BOGUS_COMMAND], decode=True)
- self.assertTrue(isinstance(cm.exception.stdout, six.string_types))
- self.assertTrue(isinstance(cm.exception.stderr, six.string_types))
+ self.assertTrue(isinstance(cm.exception.stdout, str))
+ self.assertTrue(isinstance(cm.exception.stderr, str))
def test_bunch_of_slashes_in_path(self):
self.assertEqual("/target/my/path/",