Python 3 compatibility
* ConfigParser import from six * Drop iteritems() * To support both Python 2 and 3 * Encode string before writing it to file * To support both Python 2 and 3 * Use six.string_types * To support both Python 2 and 3 * Use key on Python 3 * Because cmp is no longer working * Add py33 and py34 to tox.ini Change-Id: I23985be55302cd4ef577919efb51975ecbd9563d Related-Bug: 1347899
This commit is contained in:
parent
a7ffb71ffd
commit
f8796122c5
|
@ -19,8 +19,8 @@ Not implemented yet:
|
||||||
- placeholders are ignored
|
- placeholders are ignored
|
||||||
"""
|
"""
|
||||||
import atexit
|
import atexit
|
||||||
import ConfigParser
|
|
||||||
import errno
|
import errno
|
||||||
|
import functools
|
||||||
import grp
|
import grp
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -35,6 +35,8 @@ except ImportError:
|
||||||
rpmutils_present = False
|
rpmutils_present = False
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
import six
|
||||||
|
import six.moves.configparser as ConfigParser
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def to_boolean(b):
|
def to_boolean(b):
|
||||||
val = b.lower().strip() if isinstance(b, basestring) else b
|
val = b.lower().strip() if isinstance(b, six.string_types) else b
|
||||||
return val in [True, 'true', 'yes', '1', 1]
|
return val in [True, 'true', 'yes', '1', 1]
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,7 +246,7 @@ class RpmHelper(object):
|
||||||
e.g., ['2.0', '2.2', '2.2-1.fc16', '2.2.22-1.fc16']
|
e.g., ['2.0', '2.2', '2.2-1.fc16', '2.2.22-1.fc16']
|
||||||
"""
|
"""
|
||||||
if versions:
|
if versions:
|
||||||
if isinstance(versions, basestring):
|
if isinstance(versions, six.string_types):
|
||||||
return versions
|
return versions
|
||||||
versions = sorted(versions, rpmutils.compareVerOnly,
|
versions = sorted(versions, rpmutils.compareVerOnly,
|
||||||
reverse=True)
|
reverse=True)
|
||||||
|
@ -432,7 +434,7 @@ class PackagesHandler(object):
|
||||||
# -b == local & remote install
|
# -b == local & remote install
|
||||||
# -y == install deps
|
# -y == install deps
|
||||||
opts = '-b -y'
|
opts = '-b -y'
|
||||||
for pkg_name, versions in packages.iteritems():
|
for pkg_name, versions in packages.items():
|
||||||
if len(versions) > 0:
|
if len(versions) > 0:
|
||||||
cmd_str = 'gem install %s --version %s %s' % (opts,
|
cmd_str = 'gem install %s --version %s %s' % (opts,
|
||||||
versions[0],
|
versions[0],
|
||||||
|
@ -444,7 +446,7 @@ class PackagesHandler(object):
|
||||||
def _handle_python_packages(self, packages):
|
def _handle_python_packages(self, packages):
|
||||||
"""very basic support for easy_install."""
|
"""very basic support for easy_install."""
|
||||||
# TODO(asalkeld) support versions
|
# TODO(asalkeld) support versions
|
||||||
for pkg_name, versions in packages.iteritems():
|
for pkg_name, versions in packages.items():
|
||||||
cmd_str = 'easy_install %s' % (pkg_name)
|
cmd_str = 'easy_install %s' % (pkg_name)
|
||||||
CommandRunner(cmd_str).run()
|
CommandRunner(cmd_str).run()
|
||||||
|
|
||||||
|
@ -471,7 +473,7 @@ class PackagesHandler(object):
|
||||||
# collect pkgs for batch processing at end
|
# collect pkgs for batch processing at end
|
||||||
installs = []
|
installs = []
|
||||||
downgrades = []
|
downgrades = []
|
||||||
for pkg_name, versions in packages.iteritems():
|
for pkg_name, versions in packages.items():
|
||||||
ver = RpmHelper.newest_rpm_version(versions)
|
ver = RpmHelper.newest_rpm_version(versions)
|
||||||
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
||||||
if RpmHelper.rpm_package_installed(pkg):
|
if RpmHelper.rpm_package_installed(pkg):
|
||||||
|
@ -516,7 +518,7 @@ class PackagesHandler(object):
|
||||||
# collect pkgs for batch processing at end
|
# collect pkgs for batch processing at end
|
||||||
installs = []
|
installs = []
|
||||||
downgrades = []
|
downgrades = []
|
||||||
for pkg_name, versions in packages.iteritems():
|
for pkg_name, versions in packages.items():
|
||||||
ver = RpmHelper.newest_rpm_version(versions)
|
ver = RpmHelper.newest_rpm_version(versions)
|
||||||
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
||||||
if RpmHelper.rpm_package_installed(pkg):
|
if RpmHelper.rpm_package_installed(pkg):
|
||||||
|
@ -572,7 +574,7 @@ class PackagesHandler(object):
|
||||||
# collect pkgs for batch processing at end
|
# collect pkgs for batch processing at end
|
||||||
installs = []
|
installs = []
|
||||||
downgrades = []
|
downgrades = []
|
||||||
for pkg_name, versions in packages.iteritems():
|
for pkg_name, versions in packages.items():
|
||||||
ver = RpmHelper.newest_rpm_version(versions)
|
ver = RpmHelper.newest_rpm_version(versions)
|
||||||
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
pkg = "%s-%s" % (pkg_name, ver) if ver else pkg_name
|
||||||
if RpmHelper.rpm_package_installed(pkg):
|
if RpmHelper.rpm_package_installed(pkg):
|
||||||
|
@ -646,7 +648,15 @@ class PackagesHandler(object):
|
||||||
"""
|
"""
|
||||||
if not self._packages:
|
if not self._packages:
|
||||||
return
|
return
|
||||||
packages = sorted(self._packages.iteritems(), PackagesHandler._pkgsort)
|
try:
|
||||||
|
packages = sorted(
|
||||||
|
self._packages.items(), cmp=PackagesHandler._pkgsort)
|
||||||
|
except TypeError:
|
||||||
|
# On Python 3, we have to use key instead of cmp
|
||||||
|
# This could also work on Python 2.7, but not on 2.6
|
||||||
|
packages = sorted(
|
||||||
|
self._packages.items(),
|
||||||
|
key=functools.cmp_to_key(PackagesHandler._pkgsort))
|
||||||
|
|
||||||
for manager, package_entries in packages:
|
for manager, package_entries in packages:
|
||||||
handler = self._package_handler(manager)
|
handler = self._package_handler(manager)
|
||||||
|
@ -663,7 +673,7 @@ class FilesHandler(object):
|
||||||
def apply_files(self):
|
def apply_files(self):
|
||||||
if not self._files:
|
if not self._files:
|
||||||
return
|
return
|
||||||
for fdest, meta in self._files.iteritems():
|
for fdest, meta in self._files.items():
|
||||||
dest = fdest.encode()
|
dest = fdest.encode()
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(dest))
|
os.makedirs(os.path.dirname(dest))
|
||||||
|
@ -674,13 +684,14 @@ class FilesHandler(object):
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
|
|
||||||
if 'content' in meta:
|
if 'content' in meta:
|
||||||
if isinstance(meta['content'], basestring):
|
if isinstance(meta['content'], six.string_types):
|
||||||
f = open(dest, 'w+')
|
f = open(dest, 'w+')
|
||||||
f.write(meta['content'])
|
f.write(meta['content'])
|
||||||
f.close()
|
f.close()
|
||||||
else:
|
else:
|
||||||
f = open(dest, 'w+')
|
f = open(dest, 'w+')
|
||||||
f.write(json.dumps(meta['content'], indent=4))
|
f.write(json.dumps(meta['content'], indent=4)
|
||||||
|
.encode('UTF-8'))
|
||||||
f.close()
|
f.close()
|
||||||
elif 'source' in meta:
|
elif 'source' in meta:
|
||||||
CommandRunner('curl -o %s %s' % (dest, meta['source'])).run()
|
CommandRunner('curl -o %s %s' % (dest, meta['source'])).run()
|
||||||
|
@ -791,7 +802,7 @@ class SourcesHandler(object):
|
||||||
def apply_sources(self):
|
def apply_sources(self):
|
||||||
if not self._sources:
|
if not self._sources:
|
||||||
return
|
return
|
||||||
for dest, url in self._sources.iteritems():
|
for dest, url in self._sources.items():
|
||||||
self._apply_source(dest, url)
|
self._apply_source(dest, url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -885,11 +896,11 @@ class ServicesHandler(object):
|
||||||
h.event('service.restarted', service, self.resource)
|
h.event('service.restarted', service, self.resource)
|
||||||
|
|
||||||
def _monitor_services(self, handler, services):
|
def _monitor_services(self, handler, services):
|
||||||
for service, properties in services.iteritems():
|
for service, properties in services.items():
|
||||||
self._monitor_service(handler, service, properties)
|
self._monitor_service(handler, service, properties)
|
||||||
|
|
||||||
def _initialize_services(self, handler, services):
|
def _initialize_services(self, handler, services):
|
||||||
for service, properties in services.iteritems():
|
for service, properties in services.items():
|
||||||
self._initialize_service(handler, service, properties)
|
self._initialize_service(handler, service, properties)
|
||||||
|
|
||||||
# map of function pointers to various service handlers
|
# map of function pointers to various service handlers
|
||||||
|
@ -908,7 +919,7 @@ class ServicesHandler(object):
|
||||||
"""Starts, stops, enables, disables services."""
|
"""Starts, stops, enables, disables services."""
|
||||||
if not self._services:
|
if not self._services:
|
||||||
return
|
return
|
||||||
for manager, service_entries in self._services.iteritems():
|
for manager, service_entries in self._services.items():
|
||||||
handler = self._service_handler(manager)
|
handler = self._service_handler(manager)
|
||||||
if not handler:
|
if not handler:
|
||||||
LOG.warn("Skipping invalid service type: %s" % manager)
|
LOG.warn("Skipping invalid service type: %s" % manager)
|
||||||
|
@ -919,7 +930,7 @@ class ServicesHandler(object):
|
||||||
"""Restarts failed services, and runs hooks."""
|
"""Restarts failed services, and runs hooks."""
|
||||||
if not self._services:
|
if not self._services:
|
||||||
return
|
return
|
||||||
for manager, service_entries in self._services.iteritems():
|
for manager, service_entries in self._services.items():
|
||||||
handler = self._service_handler(manager)
|
handler = self._service_handler(manager)
|
||||||
if not handler:
|
if not handler:
|
||||||
LOG.warn("Skipping invalid service type: %s" % manager)
|
LOG.warn("Skipping invalid service type: %s" % manager)
|
||||||
|
@ -1078,7 +1089,7 @@ class GroupsHandler(object):
|
||||||
"""Create Linux/UNIX groups and assign group IDs."""
|
"""Create Linux/UNIX groups and assign group IDs."""
|
||||||
if not self.groups:
|
if not self.groups:
|
||||||
return
|
return
|
||||||
for group, properties in self.groups.iteritems():
|
for group, properties in self.groups.items():
|
||||||
LOG.debug("%s group is being created" % group)
|
LOG.debug("%s group is being created" % group)
|
||||||
self._initialize_group(group, properties)
|
self._initialize_group(group, properties)
|
||||||
|
|
||||||
|
@ -1122,7 +1133,7 @@ class UsersHandler(object):
|
||||||
"""Create Linux/UNIX users and assign user IDs, groups and homedir."""
|
"""Create Linux/UNIX users and assign user IDs, groups and homedir."""
|
||||||
if not self.users:
|
if not self.users:
|
||||||
return
|
return
|
||||||
for user, properties in self.users.iteritems():
|
for user, properties in self.users.items():
|
||||||
LOG.debug("%s user is being created" % user)
|
LOG.debug("%s user is being created" % user)
|
||||||
self._initialize_user(user, properties)
|
self._initialize_user(user, properties)
|
||||||
|
|
||||||
|
@ -1357,7 +1368,7 @@ class Metadata(object):
|
||||||
mode='wb',
|
mode='wb',
|
||||||
delete=False) as cf:
|
delete=False) as cf:
|
||||||
os.chmod(cf.name, 0o600)
|
os.chmod(cf.name, 0o600)
|
||||||
cf.write(json.dumps(self._metadata))
|
cf.write(json.dumps(self._metadata).encode('UTF-8'))
|
||||||
os.rename(cf.name, last_path)
|
os.rename(cf.name, last_path)
|
||||||
cf.close()
|
cf.close()
|
||||||
if res_last_path != last_path:
|
if res_last_path != last_path:
|
||||||
|
|
|
@ -633,13 +633,13 @@ class TestHupConfig(MockPopenTestCase):
|
||||||
|
|
||||||
def test_load_main_section(self):
|
def test_load_main_section(self):
|
||||||
fcreds = tempfile.NamedTemporaryFile()
|
fcreds = tempfile.NamedTemporaryFile()
|
||||||
fcreds.write('AWSAccessKeyId=foo\nAWSSecretKey=bar\n')
|
fcreds.write('AWSAccessKeyId=foo\nAWSSecretKey=bar\n'.encode('UTF-8'))
|
||||||
fcreds.flush()
|
fcreds.flush()
|
||||||
|
|
||||||
main_conf = tempfile.NamedTemporaryFile()
|
main_conf = tempfile.NamedTemporaryFile()
|
||||||
main_conf.write('''[main]
|
main_conf.write(('''[main]
|
||||||
stack=teststack
|
stack=teststack
|
||||||
credential-file=%s''' % fcreds.name)
|
credential-file=%s''' % fcreds.name).encode('UTF-8'))
|
||||||
main_conf.flush()
|
main_conf.flush()
|
||||||
mainconfig = cfn_helper.HupConfig([open(main_conf.name)])
|
mainconfig = cfn_helper.HupConfig([open(main_conf.name)])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -649,11 +649,11 @@ credential-file=%s''' % fcreds.name)
|
||||||
main_conf.close()
|
main_conf.close()
|
||||||
|
|
||||||
main_conf = tempfile.NamedTemporaryFile()
|
main_conf = tempfile.NamedTemporaryFile()
|
||||||
main_conf.write('''[main]
|
main_conf.write(('''[main]
|
||||||
stack=teststack
|
stack=teststack
|
||||||
region=region1
|
region=region1
|
||||||
credential-file=%s-invalid
|
credential-file=%s-invalid
|
||||||
interval=120''' % fcreds.name)
|
interval=120''' % fcreds.name).encode('UTF-8'))
|
||||||
main_conf.flush()
|
main_conf.flush()
|
||||||
e = self.assertRaises(Exception, cfn_helper.HupConfig,
|
e = self.assertRaises(Exception, cfn_helper.HupConfig,
|
||||||
[open(main_conf.name)])
|
[open(main_conf.name)])
|
||||||
|
@ -675,9 +675,9 @@ interval=120''' % fcreds.name)
|
||||||
hooks_conf = tempfile.NamedTemporaryFile()
|
hooks_conf = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
def write_hook_conf(f, name, triggers, path, action):
|
def write_hook_conf(f, name, triggers, path, action):
|
||||||
f.write(
|
f.write((
|
||||||
'[%s]\ntriggers=%s\npath=%s\naction=%s\nrunas=root\n\n' % (
|
'[%s]\ntriggers=%s\npath=%s\naction=%s\nrunas=root\n\n' % (
|
||||||
name, triggers, path, action))
|
name, triggers, path, action)).encode('UTF-8'))
|
||||||
|
|
||||||
write_hook_conf(
|
write_hook_conf(
|
||||||
hooks_conf,
|
hooks_conf,
|
||||||
|
@ -706,15 +706,15 @@ interval=120''' % fcreds.name)
|
||||||
hooks_conf.flush()
|
hooks_conf.flush()
|
||||||
|
|
||||||
fcreds = tempfile.NamedTemporaryFile()
|
fcreds = tempfile.NamedTemporaryFile()
|
||||||
fcreds.write('AWSAccessKeyId=foo\nAWSSecretKey=bar\n')
|
fcreds.write('AWSAccessKeyId=foo\nAWSSecretKey=bar\n'.encode('UTF-8'))
|
||||||
fcreds.flush()
|
fcreds.flush()
|
||||||
|
|
||||||
main_conf = tempfile.NamedTemporaryFile()
|
main_conf = tempfile.NamedTemporaryFile()
|
||||||
main_conf.write('''[main]
|
main_conf.write(('''[main]
|
||||||
stack=teststack
|
stack=teststack
|
||||||
credential-file=%s
|
credential-file=%s
|
||||||
region=region1
|
region=region1
|
||||||
interval=120''' % fcreds.name)
|
interval=120''' % fcreds.name).encode('UTF-8'))
|
||||||
main_conf.flush()
|
main_conf.flush()
|
||||||
|
|
||||||
mainconfig = cfn_helper.HupConfig([
|
mainconfig = cfn_helper.HupConfig([
|
||||||
|
@ -758,7 +758,7 @@ class TestCfnHelper(testtools.TestCase):
|
||||||
|
|
||||||
def _check_metadata_content(self, content, value):
|
def _check_metadata_content(self, content, value):
|
||||||
with tempfile.NamedTemporaryFile() as metadata_info:
|
with tempfile.NamedTemporaryFile() as metadata_info:
|
||||||
metadata_info.write(content)
|
metadata_info.write(content.encode('UTF-8'))
|
||||||
metadata_info.flush()
|
metadata_info.flush()
|
||||||
port = cfn_helper.metadata_server_port(metadata_info.name)
|
port = cfn_helper.metadata_server_port(metadata_info.name)
|
||||||
self.assertEqual(value, port)
|
self.assertEqual(value, port)
|
||||||
|
|
|
@ -2,3 +2,4 @@ pbr>=0.6,!=0.7,<1.0
|
||||||
argparse
|
argparse
|
||||||
boto>=2.12.0,!=2.13.0
|
boto>=2.12.0,!=2.13.0
|
||||||
psutil>=1.1.1,<2.0.0
|
psutil>=1.1.1,<2.0.0
|
||||||
|
six>=1.9.0
|
||||||
|
|
Loading…
Reference in New Issue