Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support (and tests) for Python 2 #158

Merged
merged 4 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '2.x', '3.x']
python-version: [ '3.x']
steps:
- name: Check out code
uses: actions/checkout@v1
Expand All @@ -58,7 +58,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '2.x', '3.x']
python-version: [ '3.x']
steps:
- name: Check out code
uses: actions/checkout@v1
Expand All @@ -74,5 +74,5 @@ jobs:
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Test usage
run: |
skipper make clean
sudo skipper make clean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


4 changes: 2 additions & 2 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v1
- name: Set up Python 2.7
- name: Set up Python 3
uses: actions/setup-python@v1
with:
python-version: 2.7.18
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
56 changes: 2 additions & 54 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ unsafe-load-any-extension=no
# run arbitrary code
extension-pkg-whitelist=

# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no


[MESSAGES CONTROL]

# Only show warnings with the listed confidence levels. Leave empty to show
Expand All @@ -65,7 +55,7 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,missing-docstring,fixme,superfluous-parens,too-many-locals
disable=useless-suppression,suppressed-message,missing-docstring,fixme,superfluous-parens,too-many-locals,unspecified-encoding,missing-timeout


[REPORTS]
Expand All @@ -75,12 +65,6 @@ disable=import-star-module-level,old-octal-literal,oct-method,print-statement,un
# mypackage.mymodule.MyReporterClass.
output-format=text

# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no

# Tells whether to display a full report or only the messages
reports=no

Expand Down Expand Up @@ -141,63 +125,33 @@ property-classes=abc.abstractproperty
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$

# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$

# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$

# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
Expand Down Expand Up @@ -225,12 +179,6 @@ ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# else.
single-line-if-stmt=no

# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator

# Maximum number of lines in a module
max-module-lines=1000

Expand Down Expand Up @@ -404,4 +352,4 @@ exclude-protected=_asdict,_fields,_replace,_source,_make

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
overgeneral-exceptions=builtins.Exception
2 changes: 1 addition & 1 deletion Dockerfile.skipper-build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:2.7
FROM python:3.11

COPY requirements.txt /tmp/requirements.txt
RUN pip install -r /tmp/requirements.txt
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ long_description = file: README.md
long_description_content_type = text/markdown

requires-dist = setuptools
requires-python = >=3


[files]
Expand Down
65 changes: 32 additions & 33 deletions skipper/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ def _validate_port(matcher, port_forwarding):

def _validate_port_range(start, end):
if start and end and end < start:
raise click.BadParameter("Invalid port range: {0} should be bigger than {1}".format(start, end))
raise click.BadParameter(f"Invalid port range: {start} should be bigger than {end}")


def _validate_port_out_of_range(port):
if port and not 1 <= int(port) <= 65535:
raise click.BadParameter("Invalid port number: port {0} is out of range".format(port))
raise click.BadParameter(f"Invalid port number: port {port} is out of range")


@click.group()
Expand Down Expand Up @@ -102,16 +102,16 @@ def build(ctx, images_to_build, container_context, cache):
else:
for image in images_to_build:
if image not in valid_images:
utils.logger.warning('Image %(image)s is not valid for this project! Skipping...', dict(image=image))
utils.logger.warning('Image %s is not valid for this project! Skipping...', image)
continue
valid_images_to_build[image] = valid_images[image]

tag = git.get_hash()
for image, dockerfile in six.iteritems(valid_images_to_build):
utils.logger.info('Building image: %(image)s', dict(image=image))
utils.logger.info('Building image: %s', image)

if not os.path.exists(dockerfile):
utils.logger.warning('Dockerfile %(dockerfile)s does not exist! Skipping...', dict(dockerfile=dockerfile))
utils.logger.warning('Dockerfile %s does not exist! Skipping...', dockerfile)
continue

fqdn_image = image + ':' + tag
Expand All @@ -121,7 +121,7 @@ def build(ctx, images_to_build, container_context, cache):
build_context = ctx.obj['container_context']
else:
build_context = os.path.dirname(dockerfile)
command = ['build', '--network=host', '--build-arg', 'TAG={}'.format(tag),
command = ['build', '--network=host', '--build-arg', f'TAG={tag}',
'-f', dockerfile, '-t', fqdn_image, build_context]
if cache:
cache_image = utils.generate_fqdn_image(ctx.obj['registry'], namespace=None, image=image, tag=DOCKER_TAG_FOR_CACHE)
Expand All @@ -130,7 +130,7 @@ def build(ctx, images_to_build, container_context, cache):
ret = runner.run(command)

if ret != 0:
utils.logger.error('Failed to build image: %(image)s', dict(image=image))
utils.logger.error('Failed to build image: %s', image)
return ret

if cache:
Expand Down Expand Up @@ -158,7 +158,7 @@ def push(ctx, namespace, force, pbr, image):
if pbr:
# Format = pbr_version.short_hash
# pylint: disable=protected-access
tag_to_push = "{}.{}".format(packaging._get_version_from_git().replace('dev', ''), tag[:8])
tag_to_push = f"{packaging._get_version_from_git().replace('dev', '')}.{tag[:8]}"
image_name = image + ':' + tag

ret = _push(ctx, force, image, image_name, namespace, tag_to_push)
Expand All @@ -169,31 +169,31 @@ def push(ctx, namespace, force, pbr, image):

def _push(ctx, force, image, image_name, namespace, tag):
fqdn_image = utils.generate_fqdn_image(ctx.obj['registry'], namespace, image, tag)
utils.logger.debug("Adding tag %(tag)s", dict(tag=fqdn_image))
utils.logger.debug("Adding tag %s", fqdn_image)
command = ['tag', image_name, fqdn_image]
ret = runner.run(command)
if ret != 0:
utils.logger.error('Failed to tag image: %(tag)s as fqdn', dict(tag=image_name, fqdn=fqdn_image))
utils.logger.error('Failed to tag image: %s as fqdn: %s', image_name, fqdn_image)
sys.exit(ret)
repo_name = utils.generate_fqdn_image(None, namespace, image, tag=None)
images_info = utils.get_remote_images_info([repo_name], ctx.obj['registry'],
ctx.obj.get('username'), ctx.obj.get('password'))
tags = [info[-1] for info in images_info]
if tag in tags:
if not force:
utils.logger.info("Image %(image)s is already in registry %(registry)s, not pushing",
dict(image=fqdn_image, registry=ctx.obj['registry']))
utils.logger.info("Image %s is already in registry %s, not pushing",
fqdn_image, ctx.obj['registry'])
else:
utils.logger.warning("Image %(image)s is already in registry %(registry)s, pushing anyway",
dict(image=fqdn_image, registry=ctx.obj['registry']))
utils.logger.warning("Image %s is already in registry %s, pushing anyway",
fqdn_image, ctx.obj['registry'])
_push_to_registry(ctx.obj['registry'], fqdn_image)
else:
_push_to_registry(ctx.obj['registry'], fqdn_image)
utils.logger.debug("Removing tag %(tag)s", dict(tag=fqdn_image))
utils.logger.debug("Removing tag %s", fqdn_image)
command = ['rmi', fqdn_image]
ret = runner.run(command)
if ret != 0:
utils.logger.warning('Failed to remove image tag: %(tag)s', dict(tag=fqdn_image))
utils.logger.warning('Failed to remove image tag: %s', fqdn_image)
return ret


Expand All @@ -208,15 +208,15 @@ def images(ctx, remote):

valid_images = ctx.obj.get('containers') or utils.get_images_from_dockerfiles()
images_names = valid_images.keys()
utils.logger.info("Expected images: %(images)s\n", dict(images=", ".join(images_names)))
utils.logger.info("Expected images: %s\n", ", ".join(images_names))
images_info = utils.get_local_images_info(images_names)
if remote:
_validate_global_params(ctx, 'registry')
try:
images_info += utils.get_remote_images_info(images_names, ctx.obj['registry'],
ctx.obj.get('username'), ctx.obj.get('password'))
except Exception as exp:
raise click.exceptions.ClickException('Got unknow error from remote registry %(error)s' % dict(error=exp.message))
raise click.exceptions.ClickException(f'Got unknown error from remote registry {exp}')

print(tabulate.tabulate(images_info, headers=['REGISTRY', 'IMAGE', 'TAG'], tablefmt='grid'))

Expand All @@ -240,7 +240,7 @@ def rmi(ctx, remote, image, tag):
utils.delete_local_image(image, tag)


@cli.command(context_settings=dict(ignore_unknown_options=True))
@cli.command(context_settings={"ignore_unknown_options": True})
@click.option('-i', '--interactive', help='Interactive mode', is_flag=True, default=False, envvar='SKIPPER_INTERACTIVE')
@click.option('-n', '--name', help='Container name', default=None)
@click.option('-e', '--env', multiple=True, help='Environment variables to pass the container')
Expand Down Expand Up @@ -276,7 +276,7 @@ def run(ctx, interactive, name, env, publish, cache, command):
env_file=ctx.obj.get('env_file'))


@cli.command(context_settings=dict(ignore_unknown_options=True))
@cli.command(context_settings={"ignore_unknown_options": True})
@click.option('-i', '--interactive', help='Interactive mode', is_flag=True, default=False, envvar='SKIPPER_INTERACTIVE')
@click.option('-n', '--name', help='Container name', default=None)
@click.option('-e', '--env', multiple=True, help='Environment variables to pass the container')
Expand Down Expand Up @@ -369,11 +369,11 @@ def completion():


def _push_to_registry(registry, fqdn_image):
utils.logger.debug("Pushing to registry %(registry)s", dict(registry=registry))
utils.logger.debug("Pushing to registry %s", registry)
command = ['push', fqdn_image]
ret = runner.run(command)
if ret != 0:
utils.logger.error('Failed to push image: %(tag)s', dict(tag=fqdn_image))
utils.logger.error('Failed to push image: %s', fqdn_image)
sys.exit(ret)


Expand All @@ -399,24 +399,23 @@ def runner_run(command):
tagged_image_name = image + ':' + tag

if utils.local_image_exist(image, tag):
utils.logger.info("Using build container: %(image_name)s", dict(image_name=tagged_image_name))
utils.logger.info("Using build container: %s", tagged_image_name)
return tagged_image_name

if utils.remote_image_exist(registry, image, tag, username, password):
fqdn_image = utils.generate_fqdn_image(registry, None, image, tag)
utils.logger.info("Using build container: %(fqdn_image)s", dict(fqdn_image=fqdn_image))
utils.logger.info("Using build container: %s", fqdn_image)
return fqdn_image

if not git_revision:
raise click.exceptions.ClickException(
"Couldn't find build image %(image)s with tag %(tag)s" % dict(image=image, tag=tag))
raise click.exceptions.ClickException(f"Couldn't find build image {image} with tag {tag}")

else:
tagged_image_name = image
utils.logger.info("No build container tag was provided")

docker_file = utils.image_to_dockerfile(image)
utils.logger.info("Building image using docker file: %(docker_file)s", dict(docker_file=docker_file))
utils.logger.info("Building image using docker file: %s", docker_file)
if container_context is not None:
build_context = container_context
else:
Expand All @@ -433,10 +432,10 @@ def runner_run(command):
command.extend(['--cache-from', cache_image])

if runner_run(command) != 0:
exit('Failed to build image: %(image)s' % dict(image=image))
sys.exit(f'Failed to build image: {image}')

if git_revision and not git.uncommitted_changes():
utils.logger.info("Tagging image with git revision: %(tag)s", dict(tag=tag))
utils.logger.info("Tagging image with git revision: %s", tag)
runner_run(['tag', image, tagged_image_name])

if use_cache:
Expand All @@ -456,7 +455,7 @@ def _validate_global_params(ctx, *params):
def _validate_project_image(image):
project_images = utils.get_images_from_dockerfiles()
if image not in project_images:
raise click.BadParameter("'%s' is not an image of this project, try %s" % (image, project_images), param_hint='image')
raise click.BadParameter(f"'{image}' is not an image of this project, try {project_images}", param_hint='image')


def _expend_env(ctx, extra_env):
Expand All @@ -466,7 +465,7 @@ def _expend_env(ctx, extra_env):
if isinstance(env, dict):
for key, value in six.iteritems(env):
utils.logger.debug("Adding %s=%s to environment", key, value)
environment.append("{}={}".format(key, value))
environment.append(f"{key}={value}")
elif isinstance(env, list):
for item in env:
if '=' in item:
Expand All @@ -476,8 +475,8 @@ def _expend_env(ctx, extra_env):
# if the items is just a name of environment variable, try to get it
# from the host's environment variables
if item in os.environ:
environment.append('{}={}'.format(item, os.environ[item]))
environment.append(f'{item}={os.environ[item]}')
else:
raise TypeError('Type {} not supported for key env, use dict or list instead'.format(type(env)))
raise TypeError(f'Type {type(env)} not supported for key env, use dict or list instead')

return environment + list(extra_env)
Loading