Release Notes

v0.37.22

Deprecation Notes

  • Remove six Python 2 compatibility library. All six.moves imports replaced with Python 3 stdlib equivalents:

    • six.moves.configparserconfigparser

    • six.moves.urlliburllib.parse / urllib.request

    • six.moves.urllib.errorurllib.error

    • six.moves.input → builtin input

    • six.text_typestr

    Affected modules: deploy.py, lfidapi.py, nexus/cmd.py, cli/__init__.py, cli/config.py, cli/jenkins/__init__.py, cli/jenkins/token.py.

    The six package is removed from project dependencies in pyproject.toml and types-six removed from pre-commit mypy configuration.

Bug Fixes

  • Fix deprecated openstacksdk image attributes for compatibility with openstacksdk >= 2.x. Three issues resolved in image.py:

    1. Replace image.is_public (removed) with image.visibility == "public"

    2. Replace image.metadata.get() (returns None in SDK 4.x) with (image.properties or {}).get() for ci_managed filtering

    3. Remove image.protected fallback that generated noisy warnings (WARNING: Use of image.protected resulted in an exception) on every image. Use image.is_protected directly which is the correct attribute in openstacksdk >= 2.x.

    Also replaces six.moves.urllib import with stdlib urllib.request in the same module.

  • Fix TypeError: delete() missing 1 required positional argument: 'force' in lftools openstack stack delete-stale. The delete() function in stack.py required force as a positional argument, but callers at lines 63 and 233 did not pass it. Changed force to a keyword argument with default value False.

v0.37.18

New Features

  • Add OpenStack COE cluster management commands to lftools.

    New commands:

    • lftools openstack cluster list - List COE clusters

    • lftools openstack cluster show - Show cluster details

    • lftools openstack cluster remove - Remove a specific cluster

    • lftools openstack cluster cleanup - Cleanup old clusters

    All commands use the OpenStack SDK Python library for direct API interaction, following the same patterns as other lftools openstack subcommands (server, volume, stack, image).

    Example usage:

    # List all clusters
    lftools openstack --os-cloud mycloud cluster list
    
    # List clusters older than 30 days
    lftools openstack --os-cloud mycloud cluster list --days 30
    
    # Show cluster details
    lftools openstack --os-cloud mycloud cluster show my-cluster-name
    
    # Remove a specific cluster (only if older than 60 minutes)
    lftools openstack --os-cloud mycloud cluster remove my-cluster --minutes 60
    
    # Cleanup clusters older than 90 days
    lftools openstack --os-cloud mycloud cluster cleanup --days 90
    

v0.37.17

Bug Fixes

  • Fix UnicodeEncodeError in Gerrit API requests when responses contain Unicode characters. JSON string data is now properly encoded as UTF-8 in the RestApi._request() method, preventing ‘latin-1’ codec errors when user names or group names contain special characters (e.g., ‘š’).

    This fixes failures in commands like:

    lftools gerrit addgithubrights <fqdn> <project>

  • Fix logging TypeError in GitHub create-repo command. Changed from using comma-separated arguments (which caused format string errors) to using f-string formatting for proper message construction.

v0.37.16

Bug Fixes

  • Fix ValueError in match-ldap-to-info when lfservices_releng missing.

    The code unconditionally tried to remove ‘lfservices_releng’ from the user list, causing a ValueError when it doesn’t exist in the LDAP group (common in production environments).

    This was causing info-merge-master jobs to fail.

    Now checks if the user exists before attempting removal.

v0.37.15

Bug Fixes

  • Add timeout handling to lftools openstack stack cost command to prevent indefinite hangs when retrieving stack costs from OpenStack and pricing APIs.

    The cost() function now accepts a --timeout option (default: 60 seconds) that applies to all network operations. When a timeout occurs, the command gracefully degrades by returning 0 cost instead of hanging indefinitely.

    This fixes the issue where Jenkins jobs would hang at “INFO: Retrieving stack cost for: <stack-name>” when the VEXXHOST pricing API is slow or unresponsive, or when OpenStack API queries take too long with nested stacks.

    Key changes:

    • Added timeout parameter to urllib.request.urlopen() calls

    • Wrapped network operations in try/except blocks to catch urllib.error.URLError and socket.timeout exceptions

    • Returns 0.0 cost for individual servers that timeout

    • Returns “total: 0.0” if the entire operation fails

    • Added –timeout CLI option (default: 60 seconds)

    • Enhanced logging with warning/error messages for debugging

    Usage examples:

    # Use default 60-second timeout
    lftools openstack --os-cloud vexx stack cost my-stack-name
    
    # Use custom 30-second timeout
    lftools openstack --os-cloud vexx stack cost --timeout 30 my-stack-name
    
    # Use longer timeout for complex nested stacks
    lftools openstack --os-cloud vexx stack cost --timeout 120 my-stack-name
    
  • Fix Python build failure with version 3.14

    Pin Python version to <3.14, as builds fail with new release. pyproject.toml also needed updating for modern PEP standards. Changes were needed to the license declarations.

v0.37.12

Bug Fixes

  • Pin requests Python package to version <2.32.0 to avoid bug in newer version “urllib3.exceptions.URLSchemeUnknown: Not supported URL scheme http+docker”. Also sync Pytest versions at pyproject.toml with the ones from tox.ini.

v0.37.11

Bug Fixes

  • Initialize raw_json variable before first usage otherwise we will get UnboundLocalError. Additionally move some logic using the raw_json to a position where it makes more sense. Pytest configuration was outdated so it was required to upgrade plugin versions and tests code in order to get a healthy Gerrit change.

v0.37.10

Bug Fixes

  • Add missing Python module dependency “munch” causing Openstack job failures

  • Updated openstacksdk to >=2.1.0 to address dependency conflicts. Also updated linting tool versions with pre-commit autoupdate. Addressed minor type checking issue flagged by flake8. Minor file formatting changes implemented via linting.

  • Undo the urllib3 version pin now python-jenkins no longer breaks. It was previous pinned at <2.0.0, but we can now update to <2.1.0. There are still some issues with the latest release 2.1.0.

Other Notes

  • Update GitHub actions for setup-python and upload/download artefacts

v0.37.9

Deprecation Notes

  • The six module is being phased out of use as Python 2 support has been dropped. This release is the first in which one (or more) transitions have happened. There should be no issues related to this transition but bugs may creep in.

Bug Fixes

  • Correct path for Jenkins settings files.

    The correct path should be “<repo>-settings”, but was previously set to just “<repo>”. This was causing problems in our JCASC and other automation.

v0.37.7

Bug Fixes

  • Replace deprecated set_repo_permission method with update_team_repository. The latter has the same signature, but uses “pull” and “push” rather than “read” and “write” as the permission strings.

Other Notes

  • Python 3.5, 3.6, and 3.7 support is officially dropped from lftools

v0.37.6

Bug Fixes

  • Adds new lines at EOF of templates used by lftools to generate automated Gerrit changes after a new INFO.yaml is merged.

v0.37.4

Upgrade Notes

  • Add Python 3.8 and 3.9 support to PyPI

Deprecation Notes

  • Remove Python 2.7 support to PyPI

Bug Fixes

  • Use Centos8 nodes in ONAP new project creation automated yaml files.

  • Pin urllib3 to <2.0.0

    The latest version of module breaks compatibility with python-{jenkins,openstacksdk}.

    Error:

    ValueError: Timeout value connect was <object object at
    0x7fe57a4948a0>, but it must be an int, float or None.
    

    Reference:

    Launchpad#2018567 <https://bugs.launchpad.net/python-jenkins/+bug/2018567>

v0.37.3

Deprecation Notes

v0.37.2

Bug Fixes

  • Dockerhub retired the v1 version of the dockerhub api, which was used to collect the existing tag information. This patch replaces v1 with v2 which is using json files.

v0.37.1

Bug Fixes

  • Correct parameter name in os image cleanup code

v0.37.0

Bug Fixes

  • Correct the file path for the JJB info file job. This was incorrectly set as an absolute path, but it needs to be relative to the git repo root.

  • Add the “safe” parameter to URL parsing in create_project. This removes the default safe value which includes the forward slash. In this case, we do want to escape slashes that are part of the repo name.

  • Code refactored to pass MyPy validation. MyPy highlighted a few issues with functional definitions that were overwriting each other in the command subsystem but was not because of how it operates they weren’t discovered.

v0.36.2

New Features

  • Add get-private-keys to lftools.jenkins. get-private-keys retrives the private keys and passphrases stored in the credential store. This feature will add the command get-private-keys in order to print these as well.

Bug Fixes

  • Print upload size while deploying Nexus stage repositories. This is useful while comparing the repository sizes being uploaded or released.

  • Only attempt to split nexus3_ports after we’ve checked that they exist, and wrap that attempt in a try/except so that bad ports won’t break other parts of the job.

  • Remove all instances of the gerrit_api.sanity_check function. This is too tightly coupled with other parts of the Gerrit API, and does not perform correctly in the git class.

v0.36.1

Bug Fixes

  • Fix template for INFO jobs and a bad call to sanity_check in git.gerrit.

v0.36.0

New Features

  • Add get-secrets to lftools.jenkins. get-credentials only produces username/password credentials, which does not include “secret text” stores. This feature will add the command get-secrets in order to print these as well.

  • Add git-native functions for common Gerrit actions.

  • New method git.add_maven_config allows for adding settings files for new projects via JCasC, rather than the old method of using a Groovy script to manually add the file to Jenkins.