Contributions, whether features or bug fixes, are welcome. We aim to be responsive and helpful in project issues and feature requests. For larger changes, consider discussing the change first by filing an issue; the maintainers can then add to or create a GitHub project to track the work. This also gives us a chance to provide feedback on the feasibility and suitability of your proposal, which helps ensure your hard work aligns with the project's direction.
Following these guidelines will help you get up to speed quickly,
enabling you to develop and test changes for snapm and facilitating a
smooth review and merge process. This document provides instructions for
setting up your development environment, our coding style, and how to
run the test suite.
Before you start your work we suggest searching for an existing issue that describes the change you'd like to see. If there is no issue already open please file one so that the team can review the proposal and provide feedback and guidance. This applies to both fixes/bugs and new feature development.
We use a standard GitHub pull request workflow. Here are the basic steps:
- Fork the repository on GitHub.
- Clone your fork to your local machine.
- Create a new branch for your changes.
- Make your changes and commit them with a clear, concise message (see below for advice on how to format your commit message).
- Push your changes to your fork on GitHub.
- Create a pull request from your fork to the main snapm repository.
- A committer will review your pull request. You may be asked to make changes.
- Once your pull request is approved and all tests pass, it will be merged.
We use a consistent format for commit messages and we expect all contributors
to follow this pattern. If your commits are not formatted in the expected way
you may be asked to change or re-write them before your changes can be merged.
You can do this easily using the git commit --amend or git rebase --interactive commands. If you are not familiar with these and you receive a
request to amend a commit please ask—we are always happy to help new
contributors get the hang of the workflow!
The commit subject (first line) should be in the format:
subsystem: description of change
Where "subsystem" is free-form text that should succinctly describe the area of the codebase that your patch touches. There are no really hard rules here, but we encourage the use of the module name if changing a single Python file (minus any dot-separated prefix needed to uniquely identify the module to Python—so "lvm2" rather than "snapm.manager.plugins.lvm2", for example). If your changes touch several files in the same package you should use the package name (that would be "plugins" to continue with the previous example). Changes that are either tree-wide, or that affect several packages (such as a refactoring that lifts functionality upwards in the package tree) typically use the top-level "snapm" package as the subsystem. Occasionally a comma-separated list may make sense: for example "lvm2,stratis" but this easily gets unwieldy so it is not routinely encouraged.
The remainder of the subject should be a brief description of the change or what it achieves. Again there are few strict rules but it should be possible for a reviewer to get a rough idea of what to expect in the patch. We do not enforce a hard limit on the length of the subject but wherever possible it is good to keep it to fewer than 80 characters (sometimes this is difficult, especially when naming particular functions or class names—that's fine, and we review these on a case-by-case basis).
Some examples of common subsystem strings used in the project are:
- snapm: the top-level "catch all" subsystem
- plugins: changes that affect all plugins, or the plugin package itself. Use the plugin module name if your patch only affects one plugin.
- doc: documentation (including all MarkDown files in the root, as well as the Sphinx documentation in doc/, and the groff formatted man pages in the man/ directory).
- tests: changes to any of the test suites. It is also fine to use the
specific suite name if that makes sense ("
virt_tests", "container_tests", etc). - dist: package and distribution metadata: RPM spec file, Python project and build metadata etc.
- scripts: patches affecting the demo & helper scripts found in the scripts/ directory of the source tree.
The commit body (the main text of the commit which follows the subject, separated by a single empty line) should contain a description of the change if necessary (often the subject is sufficient, especially for simple changes).
Most changes (even simple fixes or refactors) should be accompanied by an issue (whether for a fix, or a new feature). Please reference the issue in the commit using the standard GitHub tags:
Related: #123
Resolves: #232
In most cases it's best to have a one-to-one relationship between commits and issues, but if the problem you are working on is complicated it is perfectly fine (and encouraged) to break it up into smaller chunks. You can file sub-issues on GitHub for these if you wish (and it can be helpful when working on large or complex features/fixes) but it is also acceptable to tag the series with the "Related:" keyword, and then use "Resolves:" for the final commit that ends the series.
You are welcome to include tool output, code snippets, and diff output in your
commit message if it provides helpful context. If you do so please indent such
text by at least two characters. This makes the message more readable and
helps to prevent the content being mis-interpreted by programs like
patch(1) which other developers or the maintainers may use to process your
changes.
To get started with development on a RHEL, Fedora, or CentOS-based system, you'll need to install the necessary build and runtime dependencies.
Install the build dependencies with this command:
dnf builddep boom-boot snapmYou'll also need lvm2 and stratisd for the test suite to run
correctly.
dnf install lvm2 stratisdInstall boom-boot first, either from distribution packages or using
the manual installation instructions from the project README.md.
Create a venv to isolate the installation (use --system-site-packages
to use the installed packages, rather than building from source):
python3 -m venv --system-site-packages .venv && source .venv/bin/activateInstall in editable mode:
git clone https://github.com/snapshotmanager/snapm.git
cd snapm
python3 -m pip install -e .Or run from a git clone:
git clone https://github.com/snapshotmanager/snapm.git
cd snapm
export PATH="$PWD/bin:$PATH" PYTHONPATH="$PWD:$PYTHONPATH"
snapm <type> <command> ...To maintain a consistent coding style, we use a few tools to format and lint our code.
- black: All Python code in the
snapmpackage should be formatted withblack(tests are currently excluded from automatic formatting). - pylint: Your code should pass a
pylintcheck using the.pylintrcfile in the root of the repository. - pycodestyle: We also use
pycodestylefor additional style and security checks. Check out thesnapm.ymlGitHub Actions workflow for tips on running this locally. - Sphinx Docstrings: All functions and methods should have a docstring in Sphinx format. You can find a good guide here.
We have a comprehensive test suite to ensure the quality of our code. We strongly recommend running the tests in a virtual machine or other isolated environment. The test suite creates LVM2 and Stratis devices using the Linux loopback device and will modify the system state outside of the source directory.
- The test suite requires
pytest(and optionallycoverage). You can install them withpipordnf(On RHEL/Fedora/CentOS systems these packages are namedpython3-pytestandpython3-coverage). - You'll need about ~250MiB of free space in
/var/tmpfor the tests to create temporary files and filesystems. - A full test run takes approximately 25-30 minutes, depending on system performance.
- You'll need to copy the
snapmconfiguration files and systemd units/tmpfiles.d configuration into the system and notify systemd. From the project root directory, run:# cp -r etc/snapm /etc # cp systemd/*.timer systemd/*.service /usr/lib/systemd/system # cp systemd/tmpfiles.d/snapm.conf /usr/lib/tmpfiles.d # systemd-tmpfiles --create /usr/lib/tmpfiles.d/snapm.conf # systemctl daemon-reload
To run the entire test suite with coverage checking, use the following commands:
coverage run -m pytest -v --log-level=debug tests
coverage report --include "./snapm/*"To run a specific test, you can use the -k flag with pytest:
pytest -v --log-level=debug tests -k <test_name_pattern>We also have a set of container-based tests. These tests require the
podman package to be installed. You can run them using the Makefile
in the container_tests directory:
$ make -C container_tests clean
$ make -C container_tests all
$ make -C container_tests reportThe test suite aims to be self-contained and to clean up after itself.
Certain kinds of test failures during development might leave some
artifacts behind. To clean them up run the tests/bin/cleanup.sh
script:
tests/bin/cleanup.sh
Clean up test suite mounts and devices? (y/n): yTo skip the confirmation prompt, use --force:
tests/bin/cleanup.sh --forceWe use Sphinx. To build the HTML docs locally:
python3 -m pip install -r requirements.txt
make -C doc html
xdg-open doc/_build/html/index.html