{"id":15151621,"url":"https://github.com/relaxdiego/aircraft","last_synced_at":"2026-02-26T18:31:52.687Z","repository":{"id":55033064,"uuid":"290408644","full_name":"relaxdiego/aircraft","owner":"relaxdiego","description":"A collection of pyinfra packaged deploys that can be used to declaratively configure services such as dnsmasq, apache2, and others.","archived":false,"fork":false,"pushed_at":"2021-02-22T13:17:16.000Z","size":645,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-07T06:30:46.636Z","etag":null,"topics":["ansible","infrastructure","pxe","pyinfra","python"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/aircraft","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/relaxdiego.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-26T05:56:16.000Z","updated_at":"2025-02-03T15:10:17.000Z","dependencies_parsed_at":"2022-08-14T09:40:37.710Z","dependency_job_id":null,"html_url":"https://github.com/relaxdiego/aircraft","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relaxdiego%2Faircraft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relaxdiego%2Faircraft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relaxdiego%2Faircraft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relaxdiego%2Faircraft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/relaxdiego","download_url":"https://codeload.github.com/relaxdiego/aircraft/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237932070,"owners_count":19389560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","infrastructure","pxe","pyinfra","python"],"created_at":"2024-09-26T15:04:35.614Z","updated_at":"2025-10-24T07:31:10.031Z","avatar_url":"https://github.com/relaxdiego.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Aircraft\n========\n\nA collection of [pyinfra](https://pyinfra.com) packaged deploys that can be used\nto declaratively configure services such as dnsmasq, apache2, and others. For now\nonly a few services are supported but more services such as GitLab or Jenkins\nwill become available in the future.\n\n\n# Video Introduction\n\n* [View on YouTube](https://youtu.be/-wF3zPSiHOk)\n* [Configure PXE on a Pi](https://youtu.be/HzXiBUNrDkg)\n\n\n# Project Rationale\n\nI work with infrastructure. The kind of infrastructure where you have a bunch\nof baremetal machines that don't have an OS installed. Where the only access\nyou have at the onset are their BMC IPs. In that case, I need some sort of\nmachine provisioning tool that is agentless. Truly agentless, not just Ansible\nagentless.\n\nIn other situations, I might need to set up a CI/CD cluster. Now if you're like\nme, you'd prefer to configure this cluster on top of as thin a technology stack\nas possible (read: just bare OSes). The reason for this is because if you want\nto deploy your CI/CD cluster on top of the best whiz-bang technology stack,\nsuch as Kubernetes, you have to ensure that you have a CI/CD infrastructure in\nplace before you do...but that's exactly what's missing and what we're trying\nto deploy! Again, what's needed here is an agentless infrastructure automation\ntool.\n\nIn both situations, I've found Ansible usable for a time. However, after years\nof using it, I've come to find it cumbersome. With its supposed-declarative\nYAML-based DSL slowly transforming into a turing-complete language. At this point\none wonders why we don't just use an already proper language itself like, oh\nI don't know, Python?\n\nThis is what brought be to [pyinfra](https://pyinfra.com/). This project builds\non top of pyinfra's good-enough implementation. It is an attempt at replicating\nthe Ansible project structure that I've been using for years as exemplified in\nanother project called [relaxdiego/cicd](https://github.com/relaxdiego/cicd).\n\n\n## Why Didn't You Just Use Terraform?\n\nI have ample experience with Terraform in the past too and I've maintained the\n\"Terraform for provisioning, Ansible for configuration\" dichotomy for some time.\nI maintain that stand for this project but have changed it to \"Terraform for\nprovisioning, Aircraft for configuration.\"\n\n\n# Usage\n\nThis project doesn't add wrappers around pyinfra, so once you get the hang\nof [how to use pyinfra](https://docs.pyinfra.com/en/1.x/getting_started.html),\nthen you can easily move on to some of the stuff I do in the `examples/` dir\nof this project.\n\nOnce you're comfortable with pyinfra and you start browsing the `examples/`\ndir, you'll see that all I'm doing is adding [pyinfra packaged deploys](https://docs.pyinfra.com/en/1.x/api/deploys.html)\nthat you can use in your operations files. I've also created some [pydantic](https://pydantic-docs.helpmanual.io/)\nmodels that go with the packaged deploys to help with validating inventory\ndata. Anyway, check out the `examples/` directory before I keep blabbering\nfor ages.\n\n\n# Developer's Guide\n\n## Prerequisites\n\n1. [Python 3](https://www.python.org/downloads/)\n2. Make\n\n\n## Prepare Your Python Environment (pyenv style; one-time only)\n\nYou will need two additional dependencies for this style:\n\n1. [pyenv](https://github.com/pyenv/pyenv-installer)\n2. [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv)\n\nOnce the above dependencies are installed, do the following:\n\n1. Install an isolated environment for your preferred Python version.\n\n```\npython_version=\u003cYOUR-PREFERRED-PYTHON-VERSION\u003e\npyenv install --enable-shared $python_version\n```\n\nNOTE: For more available versions, run `pyenv install --list`\n\n2. Create a virtualenv for this project\n\n```\npyenv virtualenv $python_version aircraft\n```\n\n3. Add a `.python-version` file to this project dir\n\n```\ncat \u003e.python-version\u003c\u003cEOF\naircrat\n$python_version\nEOF\n```\n\nYour newly created virtualenv should now be automatically activated if your\nprompt changed to the following:\n\n```\n(aircraft) ubuntu@dev...\n```\n\nor, should you happen to be using [dotfiles.relaxdiego.com](https://dotfiles.relaxdiego.com),\nif it changed to the following\n\n```\n... via 🐍 \u003cYOUR-PREFERRED-PYTHON-VERSION\u003e (aircraft)\n```\nNotice the things in parentheses that corresponds to the virtualenv you created\nin the previous step. This is thanks to the coordination of pyenv-virtualenv and\nthe `.python-version` file in the rootdir of this project.\n\nIf you `cd ..` or `cd` anywhere else outside your project directory, the virtualenv\nwill automatically be deactivated. When you `cd` back into the project dir, the\nvirtualenv will automatically be activated.\n\n\n## Prepare Your Python Environment (venv style)\n\nIf you'd rather manage your virtualenv manually, this section is for you.\nCreate your virtual environment:\n\n```\npython3 -m venv ./venv\n```\n\nActivate it in every shell session where you intend to run make or\nthe unit tests\n\n```\nsource ./venv/bin/activate\n```\n\n\n## Install The Dependencies\n\nInstall all development and runtime dependencies.\n\nWARNING: Make sure you are using a virtualenv before running this command. Since it\n         uses pip-sync to install dependencies, it will remove any package that is not\n         listed in either `requirements-dev.in` or `setup.py`. If you followed the steps\n         in any of the Prepare Your Development Environment sections above, then you\n         should be in good shape.\n\n```\nmake dependencies\n```\n\n\n## Adding A Development Dependency\n\n1. Add it to `requirements-dev.in` and then run make:\n\n```\necho \"foo\" \u003e\u003e requirements-dev.in\nmake dependencies\n```\n\nThis will create `requirements-dev.txt` and then install all dependencies\n\n\n2. Commit `requirements-dev.in` and `requirements-dev.txt`. Both\n   files should now be updated and the `foo` package installed in your\n   local machine. Make sure to commit both files to the repo to let your\n   teammates know of the new dependency.\n\n```\ngit add requirements-dev.*\ngit commit -m \"Add foo to requirements-dev.txt\"\ngit push origin\n```\n\n\n## Adding A Runtime Dependency\n\n1. Add it to `runtime_requirements` list in setup.py and then run:\n\n```\nmake dependencies\n```\n\nThis will create `requirements.txt` and then install all dependencies\n\n\n2. Commit `setup.py` and ignore `requirements.txt`. We ignore the latter\n   since this is a library project which may be used with different versions\n   of its dependencues at development and run time.\n\n```\ngit add setup.py\ngit commit -m \"Add bar to requirements\"\ngit push origin\n```\n\n\n## Testing and Building the Charm\n\nAfter any change in the library, you want to ensure that all unit tests\npass before building it. This can be easily done by running:\n\n```\nmake test build\n```\n\n\n## Viewing the Coverage Report\n\nTo view the coverage report, run the tests first and then run:\n\n```\nmake coverage-server\n```\n\nThis will run a simple web server on port 5000 that will serve the files\nin the auto-generated `htmlcov/` directory. You may leave this server running\nin a separate session as you run the tests so that you can just switch back\nto the browser and hit refresh to see the changes to your coverage down to\nthe line of code.\n\n\n## Other Make Goals\n\nRun `make help` or check out the contents of `Makefile`.\n\n\n## Running the Tests in Multiple Python Versions\n\nMore often than not you want to be able to support more than one version of\nPython. This is where tox comes in. Just run the following to get test\nresults for all Python versions listed in tox.ini's envlist config option\n\n```\ntox\n```\n\n# References\n\n* [SecureBoot-Compatible UEFI netboot](https://wiki.ubuntu.com/UEFI/SecureBoot/PXE-IPv6)\n* [dnsmasq](https://wiki.archlinux.org/index.php/dnsmasq#Configuration)\n* [Fully Automated Ubuntu 20.04 Install](https://askubuntu.com/a/1235724)\n* [Configuring PXE Network Boot Server on Ubuntu 18.04 LTS](https://linuxhint.com/pxe_boot_ubuntu_server/)\n* [Ubuntu Network installation with PXE](https://xinau.ch/notes/ubuntu-network-installation-with-pxe/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxdiego%2Faircraft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelaxdiego%2Faircraft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelaxdiego%2Faircraft/lists"}