Commit 0fd7b833 authored by Yuan Gao's avatar Yuan Gao
Browse files

Added support for python3

parent c7a4b968
......@@ -7,4 +7,4 @@
__pycache__/
build/
.idea/
......@@ -11,7 +11,7 @@ set -ex
BASE_DIR=$(pwd)
BUILD_ROOT=${BASE_DIR}/build/debbuild
VERSION=1.13
VERSION=1.17
echo 'Cleaning deb build workspace'
rm -rf ${BUILD_ROOT}
......
Package: amazon-efs-utils
Architecture: all
Version: 1.13
Version: 1.17
Section: utils
Depends: python|python2, nfs-common, stunnel4 (>= 4.56)
Priority: optional
......
......@@ -20,7 +20,7 @@
%endif
Name : amazon-efs-utils
Version : 1.13
Version : 1.17
Release : 1%{?dist}
Summary : This package provides utilities for simplifying the use of EFS file systems
......
......@@ -2,18 +2,18 @@ attrs==17.4.0
configparser==3.5.0
coverage==4.5
enum34==1.1.6
flake8==3.5.0
flake8==3.7.9
funcsigs==1.0.2
mccabe==0.6.1
mock==2.0.0
pbr==3.1.1
pluggy==0.6.0
py==1.5.2
pycodestyle==2.3.1
pyflakes==1.6.0
pytest==3.4.0
pytest-cov==2.5.1
pytest-html==1.16.1
pytest-metadata==1.6.0
pytest-mock==1.6.3
pluggy==0.13.0
py==1.8.0
pycodestyle==2.5.0
pyflakes==2.1.1
pytest==4.6.7
pytest-cov==2.8.1
pytest-html==1.19.0
pytest-metadata==1.7.0
pytest-mock==1.11.2
six==1.11.0
......@@ -44,6 +44,11 @@ import threading
from contextlib import contextmanager
from logging.handlers import RotatingFileHandler
try:
from ConfigParser import NoOptionError
except Exception:
from configparser import NoOptionError
try:
import ConfigParser
except ImportError:
......@@ -55,7 +60,7 @@ except ImportError:
from urllib.error import URLError
from urllib.request import urlopen
VERSION = '1.13'
VERSION = '1.17'
CONFIG_FILE = '/etc/amazon/efs/efs-utils.conf'
CONFIG_SECTION = 'mount'
......@@ -66,7 +71,7 @@ LOG_FILE = 'mount.log'
STATE_FILE_DIR = '/var/run/efs'
FS_ID_RE = re.compile('^(?P<fs_id>fs-[0-9a-f]+)$')
EFS_FQDN_RE = re.compile('^(?P<fs_id>fs-[0-9a-f]+)\.efs\.(?P<region>[a-z0-9-]+)\.amazonaws.com$')
EFS_FQDN_RE = re.compile(r'^(?P<fs_id>fs-[0-9a-f]+)\.efs\.(?P<region>[a-z0-9-]+)\.amazonaws.com$')
INSTANCE_METADATA_SERVICE_URL = 'http://169.254.169.254/latest/dynamic/instance-identity/document/'
......@@ -255,7 +260,7 @@ def is_stunnel_option_supported(stunnel_output, stunnel_option_name):
break
if not supported:
logging.warn('stunnel does not support "%s"', stunnel_option_name)
logging.warning('stunnel does not support "%s"', stunnel_option_name)
return supported
......@@ -391,11 +396,7 @@ def get_init_system(comm_file='/proc/1/comm'):
return init_system
def check_network_status(fs_id, init_system):
if init_system != 'systemd':
logging.debug('Not testing network on non-systemd init systems')
return
def check_network_target(fs_id):
with open(os.devnull, 'w') as devnull:
rc = subprocess.call(['systemctl', 'status', 'network.target'], stdout=devnull, stderr=devnull, close_fds=True)
......@@ -404,6 +405,14 @@ def check_network_status(fs_id, init_system):
exit_code=0)
def check_network_status(fs_id, init_system):
if init_system != 'systemd':
logging.debug('Not testing network on non-systemd init systems')
return
check_network_target(fs_id)
def start_watchdog(init_system):
if init_system == 'init':
proc = subprocess.Popen(
......@@ -436,8 +445,8 @@ def create_state_file_dir(config, state_file_dir):
try:
mode = int(mode_str, 8)
except ValueError:
logging.warn('Bad state_file_dir_mode "%s" in config file "%s"', mode_str, CONFIG_FILE)
except ConfigParser.NoOptionError:
logging.warning('Bad state_file_dir_mode "%s" in config file "%s"', mode_str, CONFIG_FILE)
except NoOptionError:
pass
try:
......@@ -585,7 +594,10 @@ def assert_root():
def read_config(config_file=CONFIG_FILE):
p = ConfigParser.SafeConfigParser()
try:
p = ConfigParser.SafeConfigParser()
except AttributeError:
p = ConfigParser()
p.read(config_file)
return p
......@@ -665,7 +677,7 @@ def match_device(config, device):
try:
primary, secondaries, _ = socket.gethostbyname_ex(remote)
hostnames = filter(lambda e: e is not None, [primary] + secondaries)
hostnames = list(filter(lambda e: e is not None, [primary] + secondaries))
except socket.gaierror:
fatal_error(
'Failed to resolve "%s" - check that the specified DNS name is a CNAME record resolving to a valid EFS DNS '
......@@ -710,7 +722,7 @@ def check_unsupported_options(options):
warn_message = 'The "%s" option is not supported and has been ignored, as amazon-efs-utils relies on a built-in ' \
'trust store.' % unsupported_option
sys.stderr.write('WARN: %s\n' % warn_message)
logging.warn(warn_message)
logging.warning(warn_message)
del options[unsupported_option]
......
......@@ -25,7 +25,7 @@ try:
except ImportError:
from configparser import ConfigParser
VERSION = '1.13'
VERSION = '1.17'
CONFIG_FILE = '/etc/amazon/efs/efs-utils.conf'
CONFIG_SECTION = 'mount-watchdog'
......@@ -248,7 +248,7 @@ def check_efs_mounts(child_procs, unmount_grace_period_sec, state_file_dir=STATE
if is_running:
logging.debug('TLS tunnel for %s is running', state_file)
else:
logging.warn('TLS tunnel for %s is not running', state_file)
logging.warning('TLS tunnel for %s is not running', state_file)
restart_tls_tunnel(child_procs, state, state_file_dir, state_file)
......@@ -256,7 +256,7 @@ def check_child_procs(child_procs):
for proc in child_procs:
proc.poll()
if proc.returncode is not None:
logging.warn('Child TLS tunnel process %d has exited, returncode=%d', proc.pid, proc.returncode)
logging.warning('Child TLS tunnel process %d has exited, returncode=%d', proc.pid, proc.returncode)
child_procs.remove(proc)
......@@ -280,7 +280,10 @@ def assert_root():
def read_config(config_file=CONFIG_FILE):
p = ConfigParser.SafeConfigParser()
try:
p = ConfigParser.SafeConfigParser()
except AttributeError:
p = ConfigParser()
p.read(config_file)
return p
......
......@@ -30,7 +30,7 @@ def setup_mocks(mocker):
mocker.patch('mount_efs.start_watchdog')
mocker.patch('mount_efs.get_tls_port_range', return_value=(DEFAULT_TLS_PORT, DEFAULT_TLS_PORT + 10))
mocker.patch('socket.socket', return_value=MagicMock())
mocker.patch('mount_efs.write_tls_tunnel_state_file')
mocker.patch('mount_efs.write_tls_tunnel_state_file', return_value="~mocktempfile")
mocker.patch('os.rename')
mocker.patch('os.kill')
......
......@@ -7,14 +7,6 @@
#
import mount_efs
import tempfile
def create_temp_file(tmpdir, content=''):
temp_file = tmpdir.join(tempfile.mktemp())
temp_file.write(content, ensure=True)
return temp_file
def test_no_unsupported_options(capsys):
options = {}
......
......@@ -7,19 +7,26 @@
#
import mount_efs
import ConfigParser
import socket
import pytest
from mock import MagicMock
try:
import ConfigParser
except ImportError:
from configparser import ConfigParser
DEFAULT_TLS_PORT_RANGE_LOW = 20049
DEFAULT_TLS_PORT_RANGE_HIGH = 20449
def _get_config():
config = ConfigParser.SafeConfigParser()
try:
config = ConfigParser.SafeConfigParser()
except AttributeError:
config = ConfigParser()
config.add_section(mount_efs.CONFIG_SECTION)
config.set(mount_efs.CONFIG_SECTION, 'port_range_lower_bound', str(DEFAULT_TLS_PORT_RANGE_LOW))
config.set(mount_efs.CONFIG_SECTION, 'port_range_upper_bound', str(DEFAULT_TLS_PORT_RANGE_HIGH))
......
#
# Copyright 2017-2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
#
# Licensed under the MIT License. See the LICENSE accompanying this file
# for the specific language governing permissions and limitations under
# the License.
#
import errno
import mount_efs
import os
import tempfile
import pytest
try:
import ConfigParser
except ImportError:
from configparser import ConfigParser
def _get_config(mode=None):
try:
config = ConfigParser.SafeConfigParser()
except AttributeError:
config = ConfigParser()
config.add_section(mount_efs.CONFIG_SECTION)
if mode is not None:
config.set(mount_efs.CONFIG_SECTION, 'state_file_dir_mode', mode)
return config
def test_create_state_file_dir(tmpdir):
state_file_dir = str(tmpdir.join('efs'))
mount_efs.create_state_file_dir(_get_config(), state_file_dir)
assert os.path.isdir(state_file_dir)
assert '0750' == oct(os.stat(state_file_dir).st_mode)[-4:]
def test_create_state_file_dir_exists(tmpdir):
state_file_dir = str(tmpdir.join('efs'))
os.makedirs(state_file_dir)
mount_efs.create_state_file_dir(_get_config(), state_file_dir)
assert os.path.isdir(state_file_dir)
def test_create_state_file_dir_exists_as_file(tmpdir):
state_file = tmpdir.join('efs')
state_file.write('', ensure=True)
with pytest.raises(OSError) as ex:
mount_efs.create_state_file_dir(_get_config(), str(state_file))
assert errno.EEXIST == ex.value.errno
def test_create_state_file_dir_overridden_mode(tmpdir):
state_file_dir = str(tmpdir.join('efs'))
mount_efs.create_state_file_dir(_get_config(mode=str(755)), state_file_dir)
assert os.path.isdir(state_file_dir)
assert '0755' == oct(os.stat(state_file_dir).st_mode)[-4:]
def test_create_state_file_dir_overridden_bad_mode(tmpdir):
state_file_dir = str(tmpdir.join('efs'))
mount_efs.create_state_file_dir(_get_config(mode='invalid-mode'), state_file_dir)
assert os.path.isdir(state_file_dir)
assert '0750' == oct(os.stat(state_file_dir).st_mode)[-4:]
......@@ -63,7 +63,7 @@ def test_get_dns_name_bad_format_wrong_specifiers(mocker):
with pytest.raises(ValueError) as ex:
mount_efs.get_dns_name(config, FS_ID)
assert 'must include' in ex.value.message
assert 'must include' in str(ex.value)
def test_get_dns_name_bad_format_too_many_specifiers_1(mocker):
......@@ -72,7 +72,7 @@ def test_get_dns_name_bad_format_too_many_specifiers_1(mocker):
with pytest.raises(ValueError) as ex:
mount_efs.get_dns_name(config, FS_ID)
assert 'incorrect number' in ex.value.message
assert 'incorrect number' in str(ex.value)
def test_get_dns_name_bad_format_too_many_specifiers_2(mocker):
......@@ -81,7 +81,7 @@ def test_get_dns_name_bad_format_too_many_specifiers_2(mocker):
with pytest.raises(ValueError) as ex:
mount_efs.get_dns_name(config, FS_ID)
assert 'incorrect number' in ex.value.message
assert 'incorrect number' in str(ex.value)
def test_get_dns_name_unresolvable(mocker, capsys):
......
......@@ -11,7 +11,10 @@ import json
import pytest
from urllib2 import URLError
try:
from urllib2 import URLError
except ImportError:
from urllib.error import URLError
INSTANCE_DATA = {
'devpayProductCodes': None,
......
......@@ -7,13 +7,20 @@
#
import mount_efs
import ConfigParser
import pytest
try:
import ConfigParser
except ImportError:
from configparser import ConfigParser
def _get_config(stunnel_check_cert_validity):
config = ConfigParser.SafeConfigParser()
try:
config = ConfigParser.SafeConfigParser()
except AttributeError:
config = ConfigParser()
config.add_section(mount_efs.CONFIG_SECTION)
if stunnel_check_cert_validity is not None:
config.set(mount_efs.CONFIG_SECTION, 'stunnel_check_cert_validity', str(stunnel_check_cert_validity))
......
......@@ -12,6 +12,7 @@ import pytest
from contextlib import contextmanager
from mock import patch
@contextmanager
def dummy_contextmanager(*args, **kwargs):
......@@ -48,11 +49,13 @@ def _test_main(mocker, tls=False, root=True):
bootstrap_tls_mock.assert_not_called()
def test_main_tls(mocker):
@patch('mount_efs.check_network_target')
def test_main_tls(check_network, mocker):
_test_main(mocker, tls=True)
def test_main_no_tls(mocker):
@patch('mount_efs.check_network_target')
def test_main_no_tls(check_network, mocker):
_test_main(mocker, tls=False)
......
......@@ -7,11 +7,15 @@
#
import mount_efs
import ConfigParser
import os
import pytest
try:
import ConfigParser
except ImportError:
from configparser import ConfigParser
FS_ID = 'fs-deadbeef'
DNS_NAME = 'fs-deadbeef.com'
MOUNT_POINT = '/mnt'
......@@ -33,7 +37,10 @@ def _get_config(mocker, stunnel_debug_enabled=False, stunnel_check_cert_hostname
if stunnel_check_cert_validity is None:
stunnel_check_cert_validity = stunnel_check_cert_validity_supported
config = ConfigParser.SafeConfigParser()
try:
config = ConfigParser.SafeConfigParser()
except AttributeError:
config = ConfigParser()
config.add_section(mount_efs.CONFIG_SECTION)
config.set(mount_efs.CONFIG_SECTION, 'stunnel_debug_enabled', str(stunnel_debug_enabled))
config.set(mount_efs.CONFIG_SECTION, 'stunnel_check_cert_hostname', str(stunnel_check_cert_hostname))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment