Skip to content
Open
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
49 changes: 27 additions & 22 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,54 @@ jobs:
linting:
runs-on: ubuntu-24.04
steps:
- name: Install dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Run ruff and mypy checks
run: tox -e ruff,mypy
py310:
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
- name: Run tox
run: tox -e py310
py312:
runs-on: ubuntu-24.04
run: uvx --with tox-uv tox -e ruff,mypy

unit-tests:
strategy:
matrix:
include:
- python: "3.10"
runner: ubuntu-22.04
tox-env: py310
- python: "3.12"
runner: ubuntu-24.04
tox-env: py312
runs-on: ${{ matrix.runner }}
steps:
- name: Install dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Run tox
run: tox -e py312
run: uvx --with tox-uv tox -e ${{ matrix.tox-env }}

docs:
runs-on: ubuntu-24.04
steps:
- name: Install dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
- name: Git checkout
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Build rtd docs
run: tox -e docs
run: uvx --with tox-uv tox -e docs

integration-tests:
runs-on: ubuntu-24.04
steps:
- name: Install dependencies
run: |
sudo apt-get update -q
sudo apt-get install -qy distro-info tox
sudo apt-get install -qy distro-info
sudo snap install lxd
- name: Git checkout
uses: actions/checkout@v3
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Setup LXD
uses: canonical/setup-lxd@v0.1.2
- name: Setup pycloudlib config and ssh key
Expand All @@ -62,4 +67,4 @@ jobs:
echo "[lxd]" > ~/.config/pycloudlib.toml
- name: Run CI integration tests
run: |
tox -e integration-tests-ci -- --color=yes tests/integration_tests/
uvx --with tox-uv tox -e integration-tests-ci -- --color=yes tests/integration_tests/
6 changes: 4 additions & 2 deletions .github/workflows/main_check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -q
sudo apt-get install -qy distro-info tox
sudo apt-get install -qy distro-info
sudo apt-get remove --yes --purge azure-cli
- name: Initialize Pycloudlib
env:
Expand All @@ -25,7 +25,9 @@ jobs:
echo "$PYCLOUDLIB_TOML" > ~/.config/pycloudlib.toml
- name: Git checkout
uses: actions/checkout@v3
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Run CI integration tests
run: |
GOOGLE_APPLICATION_CREDENTIALS=~/.config/gce_credentials tox -e integration-tests-main-check \
GOOGLE_APPLICATION_CREDENTIALS=~/.config/gce_credentials uvx --with tox-uv tox -e integration-tests-main-check \
-- --color=yes tests/integration_tests
12 changes: 4 additions & 8 deletions .github/workflows/version_check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,19 @@ jobs:
with:
fetch-depth: 0 # Necessary to compare with the main branch

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x' # Use Python 3.x
- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Check version bump
run: |
# Fetch VERSION file from the main branch
OLD_VERSION=$(git show origin/main:VERSION)
# Read VERSION file from the current branch
NEW_VERSION=$(cat VERSION)

echo "Old version: $OLD_VERSION"
echo "New version: $NEW_VERSION"

pip install -r ci-requirements.txt

# Run the version comparison Python script
python .github/workflows/version_check.py "$OLD_VERSION" "$NEW_VERSION"
uv run --with packaging .github/workflows/version_check.py "$OLD_VERSION" "$NEW_VERSION"

6 changes: 4 additions & 2 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ formats: all

python:
install:
- path: .
- requirements: docs/requirements.txt
- method: uv
path: .
extra-requirements:
- docs

sphinx:
configuration: docs/conf.py
23 changes: 10 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
PYTHON = python3
SETUP := $(PYTHON) setup.py
UV = uv

.PHONY: build clean install publish source test venv

build:
$(SETUP) build
$(UV) build

clean:
$(SETUP) clean
rm -rf .tox .eggs *.egg-info build dist venv
rm -rf .tox .eggs *.egg-info build dist .venv
@find . -regex '.*\(__pycache__\|\.py[co]\)' -delete
$(MAKE) -C docs clean

install:
$(SETUP) install
$(UV) sync

publish:
rm -rf dist/
$(SETUP) sdist
pip install twine
$(UV) build
$(UV) run pip install twine
twine upload dist/*

source:
$(SETUP) sdist
$(UV) build

test:
$(SETUP) check -r -s
tox
$(UV) run tox

venv:
$(PYTHON) -m virtualenv -p /usr/bin/$(PYTHON) venv
venv/bin/pip install -Ur requirements.txt
uv sync
@echo "Now run the following to activate the virtual env:"
@echo ". venv/bin/activate"
@echo ". .venv/bin/activate"
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pycloudlib

[![Build Status](https://travis-ci.com/canonical/pycloudlib.svg?branch=master)](https://travis-ci.com/canonical/pycloudlib)
[![CI](https://github.com/canonical/pycloudlib/actions/workflows/ci.yaml/badge.svg)](https://github.com/canonical/pycloudlib/actions/workflows/ci.yaml)

Python library to launch, interact, and snapshot cloud instances

Expand All @@ -9,17 +9,15 @@ Python library to launch, interact, and snapshot cloud instances
Install directly from [PyPI](https://pypi.org/project/pycloudlib/):

```shell
pip3 install pycloudlib
pip install pycloudlib
```

Project's requirements.txt file can include pycloudlib as a dependency. Check out the [pip documentation](https://pip.readthedocs.io/en/1.1/requirements.html) for instructions on how to include a particular version or git hash.

Install from latest changes in `main` branch:
Install from the latest `main` branch:

```shell
git clone https://github.com/canonical/pycloudlib.git
git clone https://git.launchpad.net/pycloudlib
cd pycloudlib
python3 setup.py install
uv sync
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1!10.17.0
1!10.18.0
1 change: 0 additions & 1 deletion ci-requirements.txt

This file was deleted.

4 changes: 2 additions & 2 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The makefile can be used to create a Python virtual environment and do local tes
```shell
# Creates a python virtual environment with all requirements
make venv
. venv/bin/activate
. .venv/bin/activate
```

### Documentation
Expand All @@ -39,7 +39,7 @@ Documentation should be written in Markdown whenever possible.
When making changes please keep the following in mind:

* Keep pull requests limited to a single issue
* Code must be formatted to [Black](https://black.readthedocs.io/en/stable/index.html) standards
* Code must be formatted to [ruff](https://docs.astral.sh/ruff/) standards
* Run `tox -e format` to reformat code accordingly
* Run `tox` to execute style and lint checks
* When adding new clouds please add detailed documentation under the `docs` directory and code examples under `examples`
Expand Down
11 changes: 4 additions & 7 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@ Install directly from `PyPI <https://pypi.org/project/pycloudlib/>`_:

.. code-block:: shell

pip3 install pycloudlib
uv pip install pycloudlib

Project's requirements.txt file can include pycloudlib as a dependency. Check
out the `pip documentation <https://pip.readthedocs.io/en/1.1/requirements.html>`_ for instructions on how to include a particular version or git hash.

Install from latest master:
Install from the latest ``main`` branch:

.. code-block:: shell

git clone https://git.launchpad.net/pycloudlib
cd pycloudlib
python3 setup.py install
uv sync

*****
Usage
Expand All @@ -49,7 +46,7 @@ for more information.
Bugs
****

File bugs on Launchpad under the `pycloudlib project <https://bugs.launchpad.net/pycloudlib/+filebug>`_.
File bugs on `Launchpad <https://bugs.launchpad.net/pycloudlib/+filebug>`_.

*******
Contact
Expand Down
3 changes: 0 additions & 3 deletions docs/requirements.txt

This file was deleted.

5 changes: 3 additions & 2 deletions examples/ibm_classic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging
import os
from typing import Optional

import pycloudlib
import pycloudlib.ibm_classic
Expand Down Expand Up @@ -39,7 +40,7 @@ def manage_ssh_key(classic: pycloudlib.IBMClassic):


def launch_with_basic_cloud_config(
ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: str = None
ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: Optional[str] = None
):
"""Launch a basic instance and demo basic functionality."""
image_gid = ibm_classic.released_image("22.04", disk_size=disk_size)
Expand Down Expand Up @@ -72,7 +73,7 @@ def launch_with_basic_cloud_config(


def launch_and_demo_all_lifecycle_features(
ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: str = None
ibm_classic: pycloudlib.IBMClassic, disk_size="25G", datacenter: Optional[str] = None
):
"""Launch a basic instance and demo basic functionality."""
image_gid = ibm_classic.released_image("22.04", disk_size=disk_size)
Expand Down
7 changes: 4 additions & 3 deletions examples/oracle/oracle-cluster-demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

import logging
import sys
from typing import Optional

import pycloudlib


def demo_cluster(
availability_domain: str = None,
compartment_id: str = None,
vcn_name: str = None,
availability_domain: Optional[str] = None,
compartment_id: Optional[str] = None,
vcn_name: Optional[str] = None,
):
"""Show example of using the OCI library to launch a cluster instance and ping between them."""
with pycloudlib.OCI(
Expand Down
2 changes: 1 addition & 1 deletion pycloudlib/azure/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources import ResourceManagementClient

from pycloudlib.azure import security_types, util
from pycloudlib.azure.instance import AzureInstance, VMInstanceStatus
Expand Down
2 changes: 1 addition & 1 deletion pycloudlib/ec2/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def list_keys(self):
keypair_names.append(keypair["KeyName"])
return keypair_names

def snapshot(self, instance, clean=True):
def snapshot(self, instance, clean=True, **kwargs):
"""Snapshot an instance and generate an image from it.

Args:
Expand Down
2 changes: 1 addition & 1 deletion pycloudlib/gce/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _wait_for_instance_start(self, **kwargs):
self._wait_for_status("RUNNING")
self._ip = self._get_ip()

def wait_for_delete(self, sleep_seconds=30, raise_on_fail=False):
def wait_for_delete(self, sleep_seconds=30, raise_on_fail=False, **kwargs):
"""Wait for instance to be deleted."""
get_instance_request = compute_v1.GetInstanceRequest(
project=self.project,
Expand Down
2 changes: 1 addition & 1 deletion pycloudlib/lxd/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def delete_image(self, image_id, **kwargs):
subp(["lxc", "image", "delete", image_id])
self._log.debug("Deleted %s", image_id)

def snapshot(self, instance, clean=True, name=None):
def snapshot(self, instance, clean=True, name=None, **kwargs):
"""Take a snapshot of the passed in instance for use as image.

:param instance: The instance to create an image from
Expand Down
Loading
Loading