├── .github └── workflows │ └── default.yml ├── .gitignore ├── .gitlab-ci.yml ├── .travis.yml ├── .yamllint ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── LICENSE.md ├── README.md ├── distros.yml ├── docs ├── .gitkeep ├── ABOUT.md ├── USAGE.md └── index.md ├── mkdocs.yml ├── packer_builder ├── __init__.py ├── __main__.py ├── build.py ├── cli.py ├── distros.py ├── http │ ├── alpine │ │ └── answers.j2 │ ├── centos │ │ └── ks.cfg.j2 │ ├── debian │ │ └── preseed.cfg.j2 │ ├── fedora │ │ └── ks.cfg.j2 │ └── ubuntu │ │ └── preseed.cfg.j2 ├── logger.py ├── release.py ├── scripts │ ├── base.ps1 │ ├── base.sh │ ├── bootstrap.ps1 │ ├── cleanup.ps1 │ ├── cleanup.sh │ ├── desktop.sh │ ├── freenas.sh │ ├── nethserver.sh │ ├── oracle-cert.cer │ ├── remove_default_apps.ps1 │ ├── vagrant.ps1 │ ├── vagrant.sh │ ├── virtualbox.ps1 │ ├── virtualbox.sh │ ├── vmware.ps1 │ ├── vmware.sh │ ├── windows_updates.ps1 │ └── zerodisk.sh ├── specs │ ├── __init__.py │ ├── builders │ │ ├── __init__.py │ │ ├── common.py │ │ ├── distro.py │ │ ├── distros │ │ │ ├── __init__.py │ │ │ ├── alpine.py │ │ │ ├── centos.py │ │ │ ├── debian.py │ │ │ ├── fedora.py │ │ │ ├── freenas.py │ │ │ └── ubuntu.py │ │ ├── qemu.py │ │ ├── virtualbox.py │ │ └── vmware.py │ └── provisioners │ │ ├── __init__.py │ │ ├── freenas.py │ │ ├── linux.py │ │ └── windows.py ├── template.py └── templates.py ├── pylintrc ├── requirements-dev.in ├── requirements-dev.txt ├── requirements.in ├── requirements.txt ├── setup.py └── tests └── .gitkeep /.github/workflows/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Python Test 3 | on: push 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | strategy: 8 | max-parallel: 4 9 | matrix: 10 | python-version: [3.6, 3.7] 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | with: 15 | path: packer-builder 16 | - name: Set up Python ${{ matrix.python-version }} 17 | uses: actions/setup-python@v1 18 | with: 19 | python-version: ${{ matrix.python-version }} 20 | 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip3 install -r requirements.txt 25 | pip3 install flake8 pylint 26 | - name: flake8 27 | run: | 28 | flake8 packer_builder/ 29 | - name: pylint 30 | run: | 31 | pylint packer_builder/ 32 | - name: Install Packer 33 | env: 34 | PACKER_VERSION: 1.4.3 35 | run: | 36 | sudo apt-get update 37 | sudo apt-get install -y unzip wget 38 | wget https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip 39 | unzip packer_${PACKER_VERSION}_linux_amd64.zip 40 | sudo mv packer /usr/local/bin 41 | echo "Packer Version: $(packer --version)" 42 | - name: Generate Packer Templates 43 | run: | 44 | python -m packer_builder generate-templates --outputdir ~/projects/packer 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Distribution / packaging 8 | .Python 9 | build/ 10 | develop-eggs/ 11 | dist/ 12 | downloads/ 13 | eggs/ 14 | .eggs/ 15 | lib/ 16 | lib64/ 17 | parts/ 18 | sdist/ 19 | var/ 20 | wheels/ 21 | pip-wheel-metadata/ 22 | share/python-wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .nox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | *.py,cover 49 | .hypothesis/ 50 | .pytest_cache/ 51 | cover/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | db.sqlite3-journal 62 | 63 | # Flask stuff: 64 | instance/ 65 | .webassets-cache 66 | 67 | # Scrapy stuff: 68 | .scrapy 69 | 70 | # Sphinx documentation 71 | docs/_build/ 72 | 73 | # PyBuilder 74 | target/ 75 | 76 | # Jupyter Notebook 77 | .ipynb_checkpoints 78 | 79 | # IPython 80 | profile_default/ 81 | ipython_config.py 82 | 83 | # pyenv 84 | # For a library or package, you might want to ignore these files since the code is 85 | # intended to run in multiple environments; otherwise, check them in: 86 | # .python-version 87 | 88 | # pipenv 89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 92 | # install all needed dependencies. 93 | #Pipfile.lock 94 | 95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 96 | __pypackages__/ 97 | 98 | # Celery stuff 99 | celerybeat-schedule 100 | celerybeat.pid 101 | 102 | # SageMath parsed files 103 | *.sage.py 104 | 105 | # Environments 106 | .env 107 | .venv 108 | env/ 109 | venv/ 110 | ENV/ 111 | env.bak/ 112 | venv.bak/ 113 | 114 | # Spyder project settings 115 | .spyderproject 116 | .spyproject 117 | 118 | # Rope project settings 119 | .ropeproject 120 | 121 | # mkdocs documentation 122 | /site 123 | 124 | # mypy 125 | .mypy_cache/ 126 | .dmypy.json 127 | dmypy.json 128 | 129 | # Pyre type checker 130 | .pyre/ 131 | 132 | # pytype static type analyzer 133 | .pytype/ 134 | © 2020 GitHub, Inc. 135 | Terms 136 | Privacy 137 | Security 138 | Status 139 | Help 140 | Contact GitHub 141 | Pricing 142 | API 143 | Training 144 | Blog 145 | About 146 | 147 | # Random 148 | .vscode/ 149 | logs/ 150 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | image: python:3.7 3 | 4 | variables: 5 | PACKER_VERSION: "1.4.3" 6 | 7 | before_script: 8 | - python --version 9 | - pip3 install -r requirements.txt 10 | - pip3 install pylint flake8 11 | 12 | stages: 13 | - linting 14 | - install_packer 15 | - generate_packer_templates 16 | 17 | flake8: 18 | stage: linting 19 | script: 20 | - flake8 packer_builder/ 21 | 22 | pylint: 23 | stage: linting 24 | script: 25 | - pylint packer_builder/ 26 | install_packer: 27 | stage: install_packer 28 | script: | 29 | sudo apt-get update 30 | sudo apt-get install -y unzip wget 31 | wget https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip 32 | unzip packer_${PACKER_VERSION}_linux_amd64.zip 33 | sudo mv packer /usr/local/bin 34 | echo "Packer Version: $(packer --version)" 35 | 36 | generate_packer_templates: 37 | stage: generate_packer_templates 38 | script: python -m packer_builder generate-templates --outputdir ~/projects/packer 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | 4 | python: 5 | - 3.6 6 | - 3.7 7 | 8 | env: 9 | - PACKER_VERSION="1.4.3" 10 | 11 | before_script: 12 | - python --version 13 | - pip3 install -r requirements.txt 14 | - pip3 install flake8 pylint 15 | 16 | script: 17 | - flake8 packer_builder/ 18 | - pylint packer_builder/ 19 | - | 20 | sudo apt-get update 21 | sudo apt-get install -y unzip wget 22 | wget https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip 23 | unzip packer_${PACKER_VERSION}_linux_amd64.zip 24 | sudo mv packer /usr/local/bin 25 | echo "Packer Version: $(packer --version)" 26 | - python -m packer_builder generate-templates --outputdir ~/projects/packer 27 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | # Based on ansible-lint config 3 | extends: default 4 | 5 | ignore: | 6 | venv/ 7 | 8 | rules: 9 | braces: 10 | max-spaces-inside: 1 11 | level: error 12 | brackets: 13 | max-spaces-inside: 1 14 | level: error 15 | colons: 16 | max-spaces-after: -1 17 | level: error 18 | commas: 19 | max-spaces-after: -1 20 | level: error 21 | comments: disable 22 | comments-indentation: disable 23 | document-start: disable 24 | empty-lines: 25 | max: 3 26 | level: error 27 | hyphens: 28 | level: error 29 | indentation: disable 30 | key-duplicates: enable 31 | line-length: disable 32 | new-line-at-end-of-file: disable 33 | new-lines: 34 | type: unix 35 | trailing-spaces: disable 36 | truthy: disable 37 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | commit dc95dde9f58ee8992f777e8ca34d0d895395a3f9 2 | Author: Larry Smith Jr 3 | Date: Thu May 14 21:15:19 2020 -0400 4 | 5 | Switched to pip-tools to manage Python reqs 6 | 7 | commit 558b019614ecc9c1bf3eee9b00f0b87d44e37cbe 8 | Author: Larry Smith Jr 9 | Date: Tue Apr 28 12:44:08 2020 -0400 10 | 11 | Added several wait commands 12 | 13 | For some reason Ubuntu boot_command is gobbling up the commands. Adding 14 | wait commands seems to help with this. 15 | 16 | Resolves #81 17 | 18 | commit 68abf16c4c19fe52b1835658cdaf9544c61d0a85 19 | Author: Larry Smith Jr 20 | Date: Mon Apr 27 23:08:04 2020 -0400 21 | 22 | Added Ubuntu 20.04 23 | 24 | Now that Ubuntu 20.04 is out, we are adding Ubuntu 20.04 support. 25 | 26 | Closes #74 27 | 28 | commit e93c474b5fe7b1b1183bdf067265bb34c57da036 29 | Author: Larry Smith Jr 30 | Date: Fri Apr 17 10:14:23 2020 -0400 31 | 32 | Added Python 3.6 testing back 33 | 34 | commit 3df3a80b45ef48682b135256fd50d71d83e1746f 35 | Author: Larry Smith Jr 36 | Date: Fri Apr 17 10:11:16 2020 -0400 37 | 38 | Updated changelog 39 | 40 | commit 8eb1017a83f2dc5e3e9a5ef7ebdb811f626e6006 41 | Author: Larry Smith Jr 42 | Date: Thu Apr 16 01:08:09 2020 -0400 43 | 44 | Fixing issue with Python 3.6 45 | 46 | commit eeadc9989409eae50103ebc264d32901c1ba6a16 47 | Author: Larry Smith Jr 48 | Date: Wed Apr 8 16:59:41 2020 -0400 49 | 50 | Added CentOS 8 support 51 | 52 | CentOS 8 is now supported and tested. 53 | 54 | Closes #46 55 | 56 | commit ade53eda99d4833f18260464c6eb618786b01b74 57 | Author: Larry Smith Jr 58 | Date: Wed Mar 25 08:24:01 2020 -0400 59 | 60 | Removed facter from Alpine build 61 | 62 | Closes #51 63 | 64 | commit f222016972a3af647b54ee5ee37fc62e5d126846 65 | Author: Larry Smith Jr 66 | Date: Sat Feb 15 21:16:42 2020 -0500 67 | 68 | Fixed incorrect Debian id format 69 | 70 | commit b15a20da4bd7d4008169a1486fef8177e6b5e60c 71 | Author: Larry Smith Jr 72 | Date: Sat Feb 15 01:01:15 2020 -0500 73 | 74 | First commit to resolve issues #51 and #52 75 | 76 | commit 31a224b18cacb17c734030ef8a7acfa233ef7033 77 | Author: Larry Smith Jr 78 | Date: Wed Mar 25 01:36:45 2020 -0400 79 | 80 | Added logger rotation 81 | 82 | Needed to get log rotation enabled to minimize the log file size. 83 | 84 | Resolves #70 85 | 86 | commit 6d7dd92bba6e70359e1bbc51516ec6ed6557b12f 87 | Author: Larry Smith Jr 88 | Date: Mon Mar 23 13:15:02 2020 -0400 89 | 90 | Initial commit of documentation 91 | 92 | commit 598b7124d462d564ae9c5b24e785d71d91614971 93 | Author: Larry Smith Jr 94 | Date: Sun Mar 22 11:21:00 2020 -0400 95 | 96 | Python 3.6 removed from testing - Not supported 97 | 98 | commit 02ddbf898b604ef49d0cebcffdfb18b69b696ff2 99 | Author: Larry Smith Jr 100 | Date: Sun Mar 22 11:14:21 2020 -0400 101 | 102 | Fixed linting issues 103 | 104 | commit cd476f2a2c2dce2de5649992ec6e33d0190e5e4d 105 | Author: Larry Smith Jr 106 | Date: Sun Mar 22 11:08:30 2020 -0400 107 | 108 | More cleanup and optimizations 109 | 110 | - Template validations have been moved out of build module and into 111 | template as it should be. 112 | - Changed from subprocess Popen to subprocess run 113 | - Cleaned up a bit more formatting, etc. 114 | 115 | commit 5cbc9a6213b70146fb67129bcbc0ec747447e1e2 116 | Author: Larry Smith Jr 117 | Date: Sun Mar 22 02:32:39 2020 -0400 118 | 119 | Fixed linting issues 120 | 121 | commit fdd970d12d5ce6412cf4bb835b3d1eecd9a202a1 122 | Author: Larry Smith Jr 123 | Date: Sun Mar 22 02:24:25 2020 -0400 124 | 125 | Oh my! So, so many changes. 126 | 127 | - Cleaned up many if-then trees to use decision maps instead 128 | - Cleaned up functions using self in favor of kwargs 129 | - Added a bit more logging 130 | - Added more comments to clarify things 131 | - Probably more that I have forgotten 132 | - This will be a huge refactoring to clean up code and add more 133 | efficient logic, etc. 134 | 135 | commit f998d27b23d280cd7792967c45b10ed8cfffe671 136 | Author: Larry Smith Jr 137 | Date: Sun Mar 22 02:23:51 2020 -0400 138 | 139 | Renamed generate_templates module to templates 140 | 141 | Now has generate as function 142 | 143 | commit 4b2306af479229a90c7b531065a412098a96d070 144 | Author: Larry Smith Jr 145 | Date: Sat Mar 21 17:52:00 2020 -0400 146 | 147 | Fixing linting issues. 148 | 149 | After updating linting checks from template, the flood gates opened. 150 | 151 | commit b28329826496a396a54d380707ab99032e8ea999 152 | Author: Larry Smith Jr 153 | Date: Sat Mar 21 17:26:43 2020 -0400 154 | 155 | Switch from if-then tree to action map 156 | 157 | This is a cleaner structure for going forward 158 | 159 | commit 1b7e7eb86967ccdc6422753dddd73f07fa30109b 160 | Author: Larry Smith Jr 161 | Date: Sat Mar 21 17:25:46 2020 -0400 162 | 163 | Standardized CLI args from Cookiecutter template 164 | 165 | commit 5569a65faa0c861130ed1df0b28b09dd66531656 166 | Author: Larry Smith Jr 167 | Date: Sat Mar 21 17:24:46 2020 -0400 168 | 169 | Random cleanup, etc. 170 | 171 | Cleaned up code structure a bit. Need to do more cleanup soon. 172 | 173 | commit 792ee42591eb4af609ab1bc4dc96cc90a874833e 174 | Author: Larry Smith Jr 175 | Date: Sat Mar 21 17:21:58 2020 -0400 176 | 177 | Added new logging functionality 178 | 179 | This new functionality comes from the Cookiecutter template 180 | It replaces teh old logging 181 | 182 | commit 13d7b1c3a6f87505a532e55109355141fc2ec44f 183 | Author: Larry Smith Jr 184 | Date: Sat Mar 21 17:18:05 2020 -0400 185 | 186 | New files, etc. from updated Cookiecutter template 187 | 188 | commit 3eb07dadb0e745e1ff13d93ac1ddcc9719b07b2c 189 | Author: Larry Smith Jr 190 | Date: Tue Mar 3 01:38:11 2020 -0500 191 | 192 | Fixing GitHub Actions and Travis CI tests 193 | 194 | commit aa1f12611881b1cf2343b469ca7b747ef8e11bd2 195 | Author: Larry Smith Jr 196 | Date: Tue Mar 3 01:20:16 2020 -0500 197 | 198 | Fixing additional Flake8 linting issues 199 | 200 | commit 68d4b03149c9daa906512a4932844cc55779ae6e 201 | Author: Larry Smith Jr 202 | Date: Tue Mar 3 01:17:32 2020 -0500 203 | 204 | Fixing Flake8 linting issues 205 | 206 | commit 58ddae01faa8e8dd14b8d03026149615880311e4 207 | Author: Larry Smith Jr 208 | Date: Tue Mar 3 01:12:15 2020 -0500 209 | 210 | Added changelog to track changes 211 | 212 | commit 0594c8c09ed934638a76edca561e96e34a42a511 213 | Author: Larry Smith Jr 214 | Date: Tue Mar 3 01:11:02 2020 -0500 215 | 216 | Added new files which are part of cookiecutter template 217 | 218 | - Various files such as code of conduct, contributing guide, 219 | contributors, license, etc. 220 | - Closes #65 221 | 222 | commit fe4b849e5438b541d2f0d2c9cb573b77315174ea 223 | Author: Larry Smith Jr 224 | Date: Tue Mar 3 01:09:06 2020 -0500 225 | 226 | Added GitLab CI config 227 | 228 | commit 9814dfa150244abec004b1e538e285d5f0ca8f74 229 | Author: Larry Smith Jr 230 | Date: Tue Mar 3 01:05:28 2020 -0500 231 | 232 | Added Travis CI config 233 | 234 | commit a6bcdd95e78f15d64401d5632dc2869b83ba63fd 235 | Author: Larry Smith Jr 236 | Date: Tue Mar 3 00:56:19 2020 -0500 237 | 238 | Renamed and updated GitHub actions CI testing 239 | 240 | commit a1af1f83c6fdfe34d9f1c6247a3eaba2b2569a62 241 | Author: Larry Smith Jr 242 | Date: Tue Mar 3 00:55:37 2020 -0500 243 | 244 | Updated repo info based on cookiecutter template 245 | 246 | commit d7b77936962b609648afbd0f109aeeae66af9053 247 | Author: Larry Smith Jr 248 | Date: Tue Mar 3 00:49:15 2020 -0500 249 | 250 | Updated gitignore with standard list from cookiecutter template 251 | 252 | commit 1d987b3b24f158c06cec06d429d5e655bc4cf9e1 253 | Author: Larry Smith Jr 254 | Date: Tue Mar 3 00:48:50 2020 -0500 255 | 256 | Updated description of module 257 | 258 | commit 526c1431b99a7ec5b4fb6e5ff7f9df68f9aa6026 259 | Author: Larry Smith Jr 260 | Date: Tue Mar 3 00:47:56 2020 -0500 261 | 262 | Changed import of args to cli after renaming 263 | 264 | commit e56cca07ae10595ece059d458b2657d2f61e8117 265 | Author: Larry Smith Jr 266 | Date: Tue Mar 3 00:47:26 2020 -0500 267 | 268 | Updated Python requirements to latest versions 269 | 270 | commit 080ff15fa7cf7dde073422d9ad509c129e50a2cd 271 | Author: Larry Smith Jr 272 | Date: Tue Mar 3 00:44:23 2020 -0500 273 | 274 | Updated pylintrc config 275 | 276 | commit ed3ed0762b13dbe8b549daf9504448d346e559d4 277 | Author: Larry Smith Jr 278 | Date: Tue Mar 3 00:43:19 2020 -0500 279 | 280 | Renamed args.py to cli.py 281 | 282 | commit 4660fc4ab11d7c07c3060d4a4fd0f1a03b82401d 283 | Author: Larry Smith Jr 284 | Date: Sat Feb 15 21:11:37 2020 -0500 285 | 286 | Fixed pylint issue for line too long 287 | 288 | - disabling this for now 289 | 290 | commit 118e99143556f51a838c03efef4bb71769de00cf 291 | Author: Larry Smith Jr 292 | Date: Sat Feb 15 21:04:23 2020 -0500 293 | 294 | First commit of splitting out template constructs 295 | 296 | - Splitting these out into build specs will make things more clear I 297 | believe. With #4 still being a good option, this will at least put more 298 | clarity in the meantime. 299 | - Closes #58 300 | 301 | commit 1b799041a6b26f65c4d6df328999745d43e66d62 302 | Author: Larry Smith Jr 303 | Date: Sat Feb 15 21:40:00 2020 -0500 304 | 305 | Updated Python requirements to latest 306 | 307 | - Closes #61 308 | 309 | commit a5fae59043dc4330ebb8e832fae9f2cf606e4c09 310 | Author: Larry Smith Jr 311 | Date: Sat Feb 15 21:31:13 2020 -0500 312 | 313 | Updated Debian and Ubuntu ISO info 314 | 315 | - Closes #59 316 | 317 | commit 853adfd96c94f5e4b0a0e9a73cc7953c7c41b83a 318 | Author: Larry Smith Jr 319 | Date: Sat Feb 15 00:45:28 2020 -0500 320 | 321 | Updated CentOS 7 ISO location 322 | 323 | - Resolves #56 324 | 325 | commit d393e436d7f68e18aacdff2c0e7452d1f960b71e 326 | Author: Larry Smith Jr 327 | Date: Sat Feb 15 00:07:25 2020 -0500 328 | 329 | Resolves issue #54 330 | 331 | - We have added the logic required in order to determine whether or not 332 | the ovftool post processor is added to generate a VMware image. This was 333 | getting added before regardless if the vmware-iso builder was defined or 334 | not. 335 | 336 | commit 491320ce3572c6683e0dc8b3567e338903e62ea9 337 | Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 338 | Date: Tue Dec 3 00:25:03 2019 +0000 339 | 340 | Bump typed-ast from 1.3.1 to 1.3.2 341 | 342 | Bumps [typed-ast](https://github.com/python/typed_ast) from 1.3.1 to 1.3.2. 343 | - [Release notes](https://github.com/python/typed_ast/releases) 344 | - [Changelog](https://github.com/python/typed_ast/blob/master/release_process.md) 345 | - [Commits](https://github.com/python/typed_ast/compare/1.3.1...1.3.2) 346 | 347 | Signed-off-by: dependabot[bot] 348 | 349 | commit 275e70b2c24a9b0757add2a4382524178d091a9e 350 | Author: Larry Smith Jr 351 | Date: Fri Oct 18 00:02:46 2019 -0400 352 | 353 | Added CLI arg to override password in distros.yml 354 | 355 | - Based on the fact that you might want to override the default password 356 | defined in distros.yml. You can now use the -p/--password flag to 357 | override the default password. 358 | - closes #49 359 | 360 | commit 9d4faaa1fae8ca27ad40de89bd56b55615a6827e 361 | Author: Larry Smith Jr 362 | Date: Thu Sep 19 15:50:48 2019 -0400 363 | 364 | Fixed issue with VMware Fusion builder 365 | 366 | - Needed to add vmware-vmx to list of valid vmware-iso builder defs. 367 | - Resolves #20 368 | 369 | commit 520b3a9be408d93624f2880603127a7693f23ee1 370 | Author: Larry Smith Jr 371 | Date: Thu Sep 19 10:18:06 2019 -0400 372 | 373 | Removed previously used test Virtualbox tools 374 | 375 | - We had to use test Virtualbox guest additions for building correctly 376 | on CentOS/Fedora. This is now not required. 377 | - Closes #43 378 | 379 | commit 47ba05d3948b0a5ec36f6ccfaf5606656559e2eb 380 | Author: Larry Smith Jr 381 | Date: Wed Sep 18 23:21:22 2019 -0400 382 | 383 | - Closes #27 384 | 385 | commit feb0948f187bebf93d80f8e6d6b44d5c9d5b696d 386 | Author: Larry Smith Jr 387 | Date: Wed Sep 18 22:23:58 2019 -0400 388 | 389 | Testing vars for worklow steps 390 | 391 | commit a23ef1a6bf6fc6593c923411ce02b66f987b82bf 392 | Author: Larry Smith Jr 393 | Date: Wed Sep 18 17:46:05 2019 -0400 394 | 395 | Fixed Fedora 28/29 ISO info 396 | 397 | - Resolves #34 398 | 399 | commit 70132346cf1736617ff5822758ab779b38b792c0 400 | Author: Larry Smith Jr 401 | Date: Wed Sep 18 17:43:47 2019 -0400 402 | 403 | Fixed Debian 10 ISO info 404 | 405 | - Resolves #33 406 | 407 | commit dbbfe6002dac163d6068ae4ef1a33863f4452521 408 | Author: Larry Smith Jr 409 | Date: Wed Sep 18 17:22:07 2019 -0400 410 | 411 | Closes #32 412 | 413 | commit b2571c8553472cc0dde1b7ae0424b10a6d68a52d 414 | Author: Larry Smith Jr 415 | Date: Wed Sep 18 17:15:10 2019 -0400 416 | 417 | Added step to generate Packer templates only 418 | 419 | commit e777445f2fb88a58c40119623d65bf859741f7f8 420 | Author: Larry Smith Jr 421 | Date: Wed Sep 18 17:12:14 2019 -0400 422 | 423 | Added installation of Packer 424 | 425 | commit 71c7c467fec32c3126af26e5256c97a90404b512 426 | Author: Larry Smith Jr 427 | Date: Wed Sep 18 17:05:46 2019 -0400 428 | 429 | Fixed pylint issues 430 | 431 | commit 3bc4f83b99658a4326d160cb1552ee6f8d04d0ce 432 | Author: Larry Smith Jr 433 | Date: Wed Sep 18 16:21:29 2019 -0400 434 | 435 | Fix pylint execution 436 | 437 | commit c71233784c864e5570d16f3141f0f0db7d384d83 438 | Author: Larry Smith Jr 439 | Date: Wed Sep 18 16:15:27 2019 -0400 440 | 441 | Update main.yml 442 | 443 | commit baaf84ea3747b6f18a995b771fff3640dc76f5c1 444 | Author: Larry Smith Jr 445 | Date: Tue Sep 17 23:40:16 2019 -0400 446 | 447 | Resolves #30 448 | 449 | commit 1bfdda464c876b72e94262e5870459c3ae5e6d6c 450 | Author: Larry Smith Jr 451 | Date: Wed Aug 7 00:19:30 2019 -0400 452 | 453 | Closes #28 454 | 455 | - Added distro, version as part of bootstrap config in order to separate 456 | out the applicable builds when generating configs. This will allow us to 457 | build specific versions if needed after generating configs. 458 | 459 | commit c994bf8b98a3839d9eeaf6de6492c00684df7703 460 | Author: Larry Smith Jr 461 | Date: Fri Jul 12 16:52:02 2019 -0400 462 | 463 | Cleaned up module imports 464 | 465 | I wanted to have a clean consistent method of importing modules. 466 | 467 | Importing from this module name rather than using . imports. 468 | 469 | Closes #25 470 | 471 | commit 17d4f27079381b3a078af081609bcf49c34f17ab 472 | Author: Larry Smith Jr 473 | Date: Fri Jul 12 15:53:50 2019 -0400 474 | 475 | First commit of basic logging 476 | 477 | Closes #3 478 | 479 | commit 04924c501caede3a06db67eaa23b00f6c2437f5b 480 | Author: Larry Smith Jr 481 | Date: Thu Jul 11 19:03:44 2019 -0400 482 | 483 | Resolves #21 484 | 485 | commit 780bccd4748ebc073d486bd87ee1d7f2776ca3f5 486 | Author: Larry Smith Jr 487 | Date: Mon Jul 8 22:56:06 2019 -0400 488 | 489 | Added workaround for Ubuntu libssl issue 490 | 491 | Resolves #18 492 | 493 | commit c1f4fe874f2ff88c53f6ebc516925f14fa6d9e79 494 | Author: Larry Smith Jr 495 | Date: Mon Jul 8 22:52:01 2019 -0400 496 | 497 | Added Debian 10 (Buster) 498 | 499 | Resolves #16 500 | 501 | commit 714d6c5d8497ca816feddb3b5470c19ffc61f443 502 | Author: Larry Smith Jr 503 | Date: Thu Jun 27 01:45:11 2019 -0400 504 | 505 | Added Alpine 3.10 distro 506 | 507 | Closes #14 508 | 509 | commit b69c96dc1854f5a1cf91008e208d29c9c752d119 510 | Author: Larry Smith Jr 511 | Date: Wed Jun 19 07:23:32 2019 -0400 512 | 513 | This resolves #7 to fix incorrect versions displayed. 514 | 515 | commit 75005a88ee307b23993dbb572be827520e031965 516 | Author: Larry Smith Jr 517 | Date: Wed Jun 19 01:16:24 2019 -0400 518 | 519 | Added check to ensure outputdir exists if defined 520 | 521 | commit 127eadcc5bcdad980adf88879719c87675bfff49 522 | Author: Larry Smith Jr 523 | Date: Wed Jun 19 01:15:24 2019 -0400 524 | 525 | Added comments 526 | 527 | commit 3dca0eedb8c68ca6d285903bb92a894b2e4b766f 528 | Author: Larry Smith Jr 529 | Date: Wed Jun 19 01:15:06 2019 -0400 530 | 531 | Added initial usage info for generating templates 532 | 533 | commit d695ce45e299a19e28b6121818d72f3bcf28ab25 534 | Author: Larry Smith Jr 535 | Date: Tue Jun 18 23:31:26 2019 -0400 536 | 537 | Added functionality to generate templates only 538 | 539 | This will allow us to generate the template based on distros defined, 540 | validate the template, and then save as distro-version.json for each 541 | template. 542 | 543 | Resolves #6 544 | 545 | commit 651dd6c9aaa1800d3e72c3fd649060dfdf8a3395 546 | Author: Larry Smith Jr 547 | Date: Tue Jun 18 23:31:26 2019 -0400 548 | 549 | Added functionality to generate templates only 550 | 551 | This will allow us to generate the template based on distros defined, 552 | validate the template, and then save as distro-version.json for each 553 | template. 554 | 555 | commit 90a6927b6d65b94e84510de8ae187fef1f2cff9e 556 | Author: Larry Smith Jr 557 | Date: Sat Jun 8 01:35:18 2019 -0400 558 | 559 | Resolves #8 560 | 561 | Added the additional installation instructions to successfully install 562 | vagrant-libvirt plugin on macOS. This needs to be tested a few more 563 | times. 564 | 565 | commit 2e98a24edadda9a0e1aebdf04e32eff527824987 566 | Author: bunchc 567 | Date: Wed Jun 5 23:47:07 2019 -0500 568 | 569 | Rework build logic 570 | 571 | This adds some checking to the build logic to match defined builders 572 | to those installed on the system. It also adds the ability to run 573 | user specified builders. 574 | 575 | commit 367799c443c5ff01bd23682873515c43d51ca86c 576 | Author: bunchc 577 | Date: Tue Jun 4 19:34:07 2019 -0500 578 | 579 | Not all systems ship with cpu-checker / kvm-ok 580 | 581 | Add some additional logic should the system not have `kvm-ok` or `cpu-checker` installed. 582 | 583 | This fix attempts a naive check of `/proc/cpuinfo` for some of the flags needed for nested virt. 584 | 585 | commit 7b059a3601d3738f8ed345bdf85bdf4723d13f2b 586 | Author: bunchc 587 | Date: Tue Jun 4 17:13:45 2019 -0500 588 | 589 | Check for hardware acceleration when using KVM on linux 590 | 591 | commit 8c9fe4c4d4d29ac7e8dfd1d3f2c09ff18687f639 592 | Author: Larry Smith Jr 593 | Date: Wed May 1 23:50:52 2019 -0400 594 | 595 | Updated scripts based on Fedora 30 596 | 597 | commit 39bcf94591b45eb91c6b8aa6e7a615e98f492efe 598 | Author: Larry Smith Jr 599 | Date: Wed May 1 23:50:38 2019 -0400 600 | 601 | Added Fedora 30 602 | 603 | commit 0fff29c1432e3bf5b8d4ea90824e339499e362bb 604 | Author: Larry Smith Jr 605 | Date: Tue Apr 30 00:28:04 2019 -0400 606 | 607 | Updated Debian 9 to 9.9.0 608 | 609 | commit 42b16538842193adc6e34ab5b31264c49bda3110 610 | Author: Larry Smith Jr 611 | Date: Fri Apr 19 11:08:59 2019 -0400 612 | 613 | Added Ubuntu 19.04 614 | 615 | commit 8ad954cd0e87f7c0ebffe19f1a16dc3a65ef81a4 616 | Author: Larry Smith Jr 617 | Date: Sat Apr 13 00:16:56 2019 -0400 618 | 619 | Added check for platform running QEMU to define accelerator 620 | 621 | commit 27df0fb8e3ce181744f8c7b3d3a6c0b35aa9f818 622 | Author: Larry Smith Jr 623 | Date: Wed Apr 3 08:41:43 2019 -0400 624 | 625 | Cleaned up help info 626 | 627 | commit 1b1033d2f7720953a0192b9b903506eb4fdd024e 628 | Author: Larry Smith Jr 629 | Date: Mon Apr 1 23:40:17 2019 -0400 630 | 631 | Added check for QEMU when both vBox/QEMU are defined as builders 632 | 633 | commit d8e93ccd1b88bfeb66869f189ce18cbc454d8375 634 | Author: Larry Smith Jr 635 | Date: Mon Apr 1 23:39:44 2019 -0400 636 | 637 | Added boot_wait for 30s per distro to account for timing 638 | 639 | commit 35132e379b79079dc0be03d2a258cd01575fb3fa 640 | Author: Larry Smith Jr 641 | Date: Sun Mar 31 23:59:25 2019 -0400 642 | 643 | Updated example help for cli args 644 | 645 | commit 3964dc16624d70ba1ed8a2489bc100112c2722d8 646 | Author: Larry Smith Jr 647 | Date: Sun Mar 31 23:58:14 2019 -0400 648 | 649 | Cleaned up formatting 650 | 651 | commit c1cb43be290aa11c7adb9840ce63a114a9e0499c 652 | Author: Larry Smith Jr 653 | Date: Sun Mar 31 23:58:02 2019 -0400 654 | 655 | Added ability to define number of days since last build 656 | 657 | commit 63e69d65a7b10895d71359a5bdc65648619da91e 658 | Author: Larry Smith Jr 659 | Date: Sun Mar 31 10:18:29 2019 -0400 660 | 661 | Fixed issue with builders not being defined 662 | 663 | commit 708e9d0603cbc97c05b5128c5dc91d2960c4a202 664 | Author: Larry Smith Jr 665 | Date: Sun Mar 31 10:13:33 2019 -0400 666 | 667 | Added logic to only build if older than 30 days 668 | 669 | commit 9bf86eb7245c788dc8c57eaa52e6da23770097bd 670 | Author: Larry Smith Jr 671 | Date: Sat Mar 30 23:43:36 2019 -0400 672 | 673 | Added custom build manifest 674 | 675 | commit 6547cd2fbc7c89741dba9a49c533ba44bd0ecd13 676 | Author: Larry Smith Jr 677 | Date: Sat Mar 30 10:14:04 2019 -0400 678 | 679 | Changed vagrant login shell to bash 680 | 681 | commit 26c9e5e0651f254e636cd00f8ee17e0d79e7bcb2 682 | Author: Larry Smith Jr 683 | Date: Sat Mar 30 09:14:32 2019 -0400 684 | 685 | Fixing vagrant setup 686 | 687 | commit 4b2767a5274c54baad9d0971afe7767b0595c270 688 | Author: Larry Smith Jr 689 | Date: Sat Mar 30 08:53:25 2019 -0400 690 | 691 | Fixed updating vagrant password 692 | 693 | commit 724e005ff0fc057b41a1b09b572819a01d28a7a0 694 | Author: Larry Smith Jr 695 | Date: Sat Mar 30 01:38:50 2019 -0400 696 | 697 | Fixing permission denied 698 | 699 | commit e735642a6e92b6ac3622c4b19171a904d4acb1a4 700 | Author: Larry Smith Jr 701 | Date: Fri Mar 29 23:37:58 2019 -0400 702 | 703 | Changed vagrant output to only exclude qemu when freenas 704 | 705 | commit a00d4fb4fe3affcb5f1fa3e85b1fad4a7a635cc2 706 | Author: Larry Smith Jr 707 | Date: Fri Mar 29 23:10:01 2019 -0400 708 | 709 | Added initial Vagrant support 710 | 711 | commit 779bdad0aabfe45760a27f0d81e9f077b0e17781 712 | Author: Larry Smith Jr 713 | Date: Fri Mar 29 19:37:38 2019 -0400 714 | 715 | Trying to fix FreeNAS build 716 | 717 | commit b844004f8e9f827cb14c5eb055e770ab589102a3 718 | Author: Larry Smith Jr 719 | Date: Fri Mar 29 18:59:44 2019 -0400 720 | 721 | Added longer wait for freenas 722 | 723 | commit d7f47779c1feeec244f2c51a3672c61a1fa1a788 724 | Author: Larry Smith Jr 725 | Date: Fri Mar 29 18:28:14 2019 -0400 726 | 727 | Added missing shutdown command for FreeNAS 728 | 729 | commit d44b0adae3700ce1ff55330c1b8736aff5095149 730 | Author: Larry Smith Jr 731 | Date: Fri Mar 29 18:26:53 2019 -0400 732 | 733 | Fixed typo for adding ssh info 734 | 735 | commit 88d94580f9fbd1de2521f7e0bb7444e3c9446041 736 | Author: Larry Smith Jr 737 | Date: Fri Mar 29 18:24:40 2019 -0400 738 | 739 | Fixed bootstrap_cfg for FreeNAS 740 | 741 | commit 553d9bb9b141b9ee279967e2cb82ea60cb87073f 742 | Author: Larry Smith Jr 743 | Date: Fri Mar 29 18:21:35 2019 -0400 744 | 745 | Fixing FreeNAS 746 | 747 | commit 1ba521e08db0f8175b6f6d5bde97e095454b5f6e 748 | Author: Larry Smith Jr 749 | Date: Fri Mar 29 18:19:18 2019 -0400 750 | 751 | Added FreeNAS 752 | 753 | commit 75498d2bfb08b54aa53104e3fc597c08caffabaf 754 | Author: Larry Smith Jr 755 | Date: Fri Mar 29 13:42:25 2019 -0400 756 | 757 | Changed arguments to allow list-distros to execute w/out add'l arguments 758 | 759 | commit 64dc857fdd313b4eabce8d8f8cf23bd1e409dbb3 760 | Author: Larry Smith Jr 761 | Date: Fri Mar 29 13:38:10 2019 -0400 762 | 763 | Cleaned up code, added docstrings, etc. 764 | 765 | commit a71141f1a6019d190f841f9746f7b9db0850f2eb 766 | Author: Larry Smith Jr 767 | Date: Fri Mar 29 11:00:09 2019 -0400 768 | 769 | Fixed disk_dev for Alpine 770 | 771 | commit 219792c3154c48596583db4ce173381c0c041c98 772 | Author: Larry Smith Jr 773 | Date: Fri Mar 29 10:06:03 2019 -0400 774 | 775 | Added Alpine support 776 | 777 | commit 43ddb6992af9f45aebe09ceea6352831d1ab4cf2 778 | Author: Larry Smith Jr 779 | Date: Fri Mar 29 01:04:26 2019 -0400 780 | 781 | Added ability to list distros and only build a specific distro 782 | 783 | commit 1e3c6a24e3f447f896d1fa961da6f73ab9f4a913 784 | Author: Larry Smith Jr 785 | Date: Fri Mar 29 01:03:27 2019 -0400 786 | 787 | Updated help info 788 | 789 | commit c1b59c94c0e19377274d4f36989e646ece047e65 790 | Author: Larry Smith Jr 791 | Date: Fri Mar 29 00:39:38 2019 -0400 792 | 793 | Added Fedora 794 | 795 | commit c5122859f451df82f468d02efefe4bd44a3fe6f3 796 | Author: Larry Smith Jr 797 | Date: Fri Mar 29 00:39:23 2019 -0400 798 | 799 | Cleaned up 800 | 801 | commit 330a9023b93667cd105549b157e6ace7d203c2dc 802 | Author: Larry Smith Jr 803 | Date: Fri Mar 29 00:30:06 2019 -0400 804 | 805 | Updated example 806 | 807 | commit 66ab538f30d30a2dee2259e4376ea7ee6ddfe1d1 808 | Author: Larry Smith Jr 809 | Date: Fri Mar 29 00:29:49 2019 -0400 810 | 811 | Split out execution to __main__.py 812 | 813 | commit 618903a07e8eef33aae56ffae3c01760c77a0e0d 814 | Author: Larry Smith Jr 815 | Date: Fri Mar 29 00:29:24 2019 -0400 816 | 817 | Changed file to default to distros.yml and not required 818 | 819 | commit 51474031d58a013141b744f94acd7e14ba2f8c90 820 | Author: Larry Smith Jr 821 | Date: Fri Mar 29 00:28:56 2019 -0400 822 | 823 | Added usage info 824 | 825 | commit 379c6875efc578582b514867b48b934fe6c01c3e 826 | Author: Larry Smith Jr 827 | Date: Thu Mar 28 22:11:00 2019 -0400 828 | 829 | Cleaned up code 830 | 831 | commit 0b941c35dcc2b631bd22219872ad736913bac0ba 832 | Author: Larry Smith Jr 833 | Date: Thu Mar 28 16:57:48 2019 -0400 834 | 835 | Removed vscode directory 836 | 837 | commit 71a017c4884121bd12d1da3b1a57732a8852273a 838 | Author: Larry Smith Jr 839 | Date: Thu Mar 28 00:24:08 2019 -0400 840 | 841 | Cleaned up code for a better flow 842 | 843 | commit 63b3735725a5feed3c56c9a91c0b92c003d738a8 844 | Author: Larry Smith Jr 845 | Date: Wed Mar 27 00:34:17 2019 -0400 846 | 847 | Added README 848 | 849 | commit c70872cfc9f46286afc0b14e71aa14953777c190 850 | Author: Larry Smith Jr 851 | Date: Wed Mar 27 00:30:52 2019 -0400 852 | 853 | first commit 854 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at mrlesmithjr@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to packer-builder 2 | 3 | ## Table Of Contents 4 | 5 | [Code of Conduct](#code-of-conduct) 6 | 7 | ## Code of Conduct 8 | 9 | This project and everyone participating in it is governed by the [packer-builder Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [mrlesmithjr@gmail.com](mailto:mrlesmithjr@gmail.com). 10 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | Larry Smith Jr. - mrlesmithjr@gmail.com 2 | Cody Bunch - bunchc@gmail.com 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Larry Smith Jr. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # packer-builder 2 | 3 | Using Packer **SHOULD** be straight forward and in most cases, it is. Packer builder abstracts many of the complexities of building images. With Packer builder, we wrap many of these complexities within code. By doing this, it provides us with a consistent model to build our images. We can inject logic which many times is not apparent. In addition to all of this, implement best practices into our builds. Is this builder for everyone? No. But for many, Packer can be a daunting process. So, we can minimize these processes, and make Packer builds more consumable. 4 | 5 | ## Build Status 6 | 7 | ### GitHub Actions 8 | 9 | ![Python Test](https://github.com/mrlesmithjr/packer-builder/workflows/Python%20Test/badge.svg) 10 | 11 | ### Travis CI 12 | 13 | [![Build Status](https://travis-ci.org/mrlesmithjr/packer-builder.svg?branch=master)](https://travis-ci.org/mrlesmithjr/packer-builder) 14 | 15 | ## Requirements 16 | 17 | Python >= `3.7`. 18 | 19 | - [requirements.txt](requirements.txt) 20 | - [requirements-dev.txt](requirements-dev.txt) 21 | 22 | ## Dependencies 23 | 24 | ## Documentation 25 | 26 | Checkout [https://mrlesmithjr.github.io/packer-builder](https://mrlesmithjr.github.io/packer-builder) for project documentation. 27 | 28 | ## License 29 | 30 | MIT 31 | 32 | ## Author Information 33 | 34 | Larry Smith Jr. 35 | 36 | - [@mrlesmithjr](https://twitter.com/mrlesmithjr) 37 | - [mrlesmithjr@gmail.com](mailto:mrlesmithjr@gmail.com) 38 | - [http://everythingshouldbevirtual.com](http://everythingshouldbevirtual.com) 39 | 40 | > NOTE: Repo has been created/updated using [https://github.com/mrlesmithjr/cookiecutter-python-project](https://github.com/mrlesmithjr/cookiecutter-python-project) as a template. 41 | -------------------------------------------------------------------------------- /distros.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Alpine: 3 | builders: 4 | - qemu 5 | - virtualbox-iso 6 | - vmware-iso 7 | cpus: 1 8 | disk_adapter_type: scsi 9 | disk_size: 36864 10 | memory: 1024 11 | password: P@55w0rd 12 | username: root 13 | vagrant_box: true 14 | versions: 15 | "3.8": 16 | iso_checksum: 20d20e0658b6cc361832cfb49367f0a4c33570ef1521f2e394e9164d2a9bd9df 17 | iso_url: http://dl-cdn.alpinelinux.org/alpine/v3.8/releases/x86_64/alpine-virt-3.8.4-x86_64.iso 18 | "3.9": 19 | iso_checksum: 75a784aa16ab6311dbf597bdec86259183ba5e74633e7e9201300d848d457216 20 | iso_url: http://dl-cdn.alpinelinux.org/alpine/v3.9/releases/x86_64/alpine-virt-3.9.2-x86_64.iso 21 | "3.10": 22 | iso_checksum: b3d8fe65c2777edcbc30b52cde7f5ae21dff8ecda612d5fe7b10d5c23cda40c4 23 | iso_url: http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-virt-3.10.0-x86_64.iso 24 | CentOS: 25 | builders: 26 | - qemu 27 | - virtualbox-iso 28 | - vmware-iso 29 | cpus: 1 30 | disk_adapter_type: scsi 31 | disk_size: 36864 32 | memory: 1024 33 | password: P@55w0rd 34 | username: root 35 | vagrant_box: true 36 | versions: 37 | "7": 38 | iso_checksum: 9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d 39 | iso_url: http://centos.mirror.constant.com/7/isos/x86_64/CentOS-7-x86_64-Minimal-1908.iso 40 | "8": 41 | iso_checksum: 3ee3f4ea1538e026fff763e2b284a6f20b259d91d1ad5688f5783a67d279423b 42 | iso_url: http://centos.mirror.constant.com/8/isos/x86_64/CentOS-8.1.1911-x86_64-dvd1.iso 43 | Debian: 44 | builders: 45 | - qemu 46 | - virtualbox-iso 47 | - vmware-iso 48 | cpus: 1 49 | disk_adapter_type: scsi 50 | disk_size: 36864 51 | memory: 1024 52 | # root password set to same password 53 | password: P@55w0rd 54 | username: debian 55 | vagrant_box: true 56 | versions: 57 | "8": 58 | iso_checksum: ea799ed959d77359783e7922ed4c94a7437b083a4ce6f09e9fe41a7af6ba60df 59 | iso_url: https://cdimage.debian.org/cdimage/archive/8.11.0/amd64/iso-cd/debian-8.11.0-amd64-netinst.iso 60 | "9": 61 | iso_checksum: d4a22c81c76a66558fb92e690ef70a5d67c685a08216701b15746586520f6e8e 62 | iso_url: https://cdimage.debian.org/cdimage/archive/9.9.0/amd64/iso-cd/debian-9.9.0-amd64-netinst.iso 63 | "10": 64 | iso_checksum: 6a901b5abe43d88b39d627e1339d15507cc38f980036b928f835e0f0e957d3d8 65 | iso_url: https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.3.0-amd64-netinst.iso 66 | Fedora: 67 | builders: 68 | - qemu 69 | - virtualbox-iso 70 | - vmware-iso 71 | cpus: 1 72 | disk_adapter_type: scsi 73 | disk_size: 36864 74 | memory: 1024 75 | password: P@55w0rd 76 | username: root 77 | vagrant_box: true 78 | versions: 79 | "28": 80 | iso_checksum: ea1efdc692356b3346326f82e2f468903e8da59324fdee8b10eac4fea83f23fe 81 | iso_url: https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/28/Server/x86_64/iso/Fedora-Server-netinst-x86_64-28-1.1.iso 82 | "29": 83 | iso_checksum: aa7fb0e6e5b71774ebdaab0dae76bdd9246a5bc7aedc28b7f1103aaaf9750654 84 | iso_url: https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/29/Server/x86_64/iso/Fedora-Server-netinst-x86_64-29-1.2.iso 85 | "30": 86 | iso_checksum: 5e4eac4566d8c572bfb3bcf54b7d6c82006ec3c6c882a2c9235c6d3494d7b100 87 | iso_url: http://fedora.mirrors.pair.com/linux/releases/30/Server/x86_64/iso/Fedora-Server-netinst-x86_64-30-1.2.iso 88 | FreeNAS: 89 | builders: 90 | - qemu 91 | - virtualbox-iso 92 | - vmware-iso 93 | cpus: 1 94 | disk_adapter_type: scsi 95 | disk_size: 36864 96 | memory: 1024 97 | password: P@55w0rd 98 | username: root 99 | vagrant_box: true 100 | versions: 101 | "11.2": 102 | iso_checksum: 3fb19c9304072bdf915d7c275e35ebc0a38d4b741e16f36a8f7af76413242092 103 | iso_url: https://download.freenas.org/11.2/STABLE/U3/x64/FreeNAS-11.2-U3.iso 104 | Ubuntu: 105 | builders: 106 | - qemu 107 | - virtualbox-iso 108 | - vmware-iso 109 | cpus: 1 110 | disk_adapter_type: scsi 111 | disk_size: 36864 112 | memory: 1024 113 | password: P@55w0rd 114 | username: ubuntu 115 | vagrant_box: true 116 | versions: 117 | "14.04": 118 | iso_checksum: b17d7c1e9d0321ad5810ba77b69aef43f0f29a5422b08120e6ee0576c4527c0e 119 | iso_url: http://releases.ubuntu.com/14.04/ubuntu-14.04.6-server-amd64.iso 120 | "16.04": 121 | iso_checksum: 16afb1375372c57471ea5e29803a89a5a6bd1f6aabea2e5e34ac1ab7eb9786ac 122 | iso_url: http://releases.ubuntu.com/16.04/ubuntu-16.04.6-server-amd64.iso 123 | "18.04": 124 | iso_checksum: e2ecdace33c939527cbc9e8d23576381c493b071107207d2040af72595f8990b 125 | iso_url: http://cdimage.ubuntu.com/releases/18.04/release/ubuntu-18.04.4-server-amd64.iso 126 | "18.10": 127 | iso_checksum: cf9250781dadd919f23c9d9612212cad653e35fccc2fbcf6853f67ad09e067ba 128 | iso_url: http://cdimage.ubuntu.com/releases/18.10/release/ubuntu-18.10-server-amd64.iso 129 | "19.04": 130 | iso_checksum: 7e8a0d07522f591dfee9bc9fcd7c05466763161e6cb0117906655bce1750b2fa 131 | iso_url: http://cdimage.ubuntu.com/releases/19.04/release/ubuntu-19.04-server-amd64.iso 132 | "20.04": 133 | iso_checksum: 36f15879bd9dfd061cd588620a164a82972663fdd148cce1f70d57d314c21b73 134 | iso_url: http://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/ubuntu-20.04-legacy-server-amd64.iso 135 | -------------------------------------------------------------------------------- /docs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/docs/.gitkeep -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About Packer Builder 2 | 3 | Packer Builder is completely open-source, and we welcome feedback, contributions, and recommendations. Start using Packer Builder now, by heading over to [https://github.com/mrlesmithjr/packer-builder](https://github.com/mrlesmithjr/packer-builder). 4 | 5 | ## Why Packer Builder 6 | 7 | ## Problems That Packer Builder Solves 8 | 9 | ## Concepts 10 | 11 | Using Packer **SHOULD** be straight forward and in most cases, it is. Packer builder abstracts many of the complexities of building images. With Packer builder, we wrap many of these complexities within code. By doing this, it provides us with a consistent model to build our images. We can inject logic which many times is not apparent. In addition to all of this, implement best practices into our builds. Is this builder for everyone? No. But for many, Packer can be a daunting process. So, we can minimize these processes, and make Packer builds more consumable. 12 | -------------------------------------------------------------------------------- /docs/USAGE.md: -------------------------------------------------------------------------------- 1 | # Packer Builder Usage 2 | 3 | ## Help 4 | 5 | ```bash 6 | python -m packer_builder --help 7 | ... 8 | usage: __main__.py [-h] [-d DISTRO] [-b BUILDER] [-f FILE] [-n NUMDAYS] 9 | [-o OUTPUTDIR] [-p PASSWORD] 10 | {build,generate-templates,list-distros,update-metadata} 11 | 12 | Packer builder. 13 | 14 | positional arguments: 15 | {build,generate-templates,list-distros,update-metadata} 16 | 17 | optional arguments: 18 | -h, --help show this help message and exit 19 | -d DISTRO, --distro DISTRO 20 | Only build specific distro. 21 | -b BUILDER, --builder BUILDER 22 | Only use specific builder. 23 | -f FILE, --file FILE Path to distro. 24 | -n NUMDAYS, --numdays NUMDAYS 25 | Define number of days since last build. 26 | -o OUTPUTDIR, --outputdir OUTPUTDIR 27 | Define path to save builds. 28 | -p PASSWORD, --password PASSWORD 29 | Define default password to override distros.yml 30 | ``` 31 | 32 | ## Examples 33 | 34 | ### Build All Distros For All Builders 35 | 36 | This will build all distros for all builders. 37 | 38 | ```bash 39 | python -m packer_builder build -o ~/projects/packer/builds 40 | ``` 41 | 42 | ### Build All Distros For A Specific Builder 43 | 44 | This will build all distros for a specific builder (virtualbox-iso in this 45 | example). 46 | 47 | ```bash 48 | python -m packer_builder build -o ~/projects/packer/builds -b virtualbox-iso 49 | ``` 50 | 51 | ### Build A Specific Distro For All Builders 52 | 53 | This will build a specific distro (CentOS in this example) for all builders. 54 | 55 | ```bash 56 | python -m packer_builder build -o ~/projects/packer/builds -d CentOS 57 | ``` 58 | 59 | ### Build A Specific Distro For A Specific Builder 60 | 61 | This will build a specific distro (CentOS in this example) for a specific 62 | builder (virtualbox-iso in this example). 63 | 64 | ```bash 65 | python -m packer_builder build -o ~/projects/packer/builds -d CentOS -b virtualbox-iso 66 | ``` 67 | 68 | ### Define Default Password At Runtime 69 | 70 | Because there might be a scenario in which you would want to override the password 71 | for all distros defined in `distros.yml`. You can pass this override password as 72 | part of the CLI arguments. 73 | 74 | ```bash 75 | python -m packer_builder build -o ~/projects/packer/builds -p SuperSecretPass 76 | ``` 77 | 78 | ### Generate Templates (ONLY) 79 | 80 | ```bash 81 | python -m packer_builder generate-templates --outputdir ~/projects/packer 82 | ``` 83 | 84 | ## vagrant-libvirt plugin on macOS 85 | 86 | ```bash 87 | brew install libiconv gcc libvirt 88 | ``` 89 | 90 | ```bash 91 | RV=$(/opt/vagrant/embedded/bin/ruby --version | awk '{ print $2 }'| awk '{ split($0, a, "p"); print a[1] }') 92 | CONFIGURE_ARGS='with-ldflags=-L/opt/vagrant/embedded/lib with-libvirt-include=/usr/local/include/libvirt with-libvirt-lib=/usr/local/lib' \ 93 | GEM_HOME=~/.vagrant.d/gems/$RV \ 94 | GEM_PATH=$GEM_HOME:/opt/vagrant/embedded/gems \ 95 | PATH=/opt/vagrant/embedded/bin:$PATH \ 96 | vagrant plugin install vagrant-libvirt 97 | ``` 98 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Packer Builder 2 | 3 | Welcome to Packer Builder. 4 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: packer-builder 2 | theme: readthedocs 3 | -------------------------------------------------------------------------------- /packer_builder/__init__.py: -------------------------------------------------------------------------------- 1 | """packer_builder/__init__.py""" 2 | -------------------------------------------------------------------------------- /packer_builder/__main__.py: -------------------------------------------------------------------------------- 1 | """packer_builder/__main__.py""" 2 | import os 3 | from packer_builder.cli import cli_args 4 | from packer_builder.build import Build 5 | from packer_builder.distros import Distros 6 | from packer_builder.templates import Templates 7 | from packer_builder.logger import setup_logger 8 | 9 | 10 | def build(args): 11 | """Build images.""" 12 | 13 | # Get dictionary of distros 14 | distros = Distros(args).get() 15 | # Build all distros 16 | Build(args, distros) 17 | 18 | 19 | def list_distros(args): 20 | """Get distros and display as JSON.""" 21 | 22 | # Get dictionary of distros 23 | distros = Distros(args) 24 | # List all distros as JSON output 25 | distros.list_() 26 | 27 | 28 | def generate_templates(args): 29 | """Generate templates without building.""" 30 | 31 | # Get dictionary of distros 32 | distros = Distros(args).get() 33 | # Generate all templates without building 34 | templates = Templates(args, distros) 35 | templates.generate() 36 | 37 | 38 | def main(): 39 | """Packer builder main execution.""" 40 | 41 | # Setup root logger 42 | setup_logger() 43 | 44 | # Capture CLI arguments 45 | args = cli_args() 46 | 47 | # Ensure output dir exists if defined 48 | if args.outputdir is not None: 49 | if not os.path.isdir: 50 | os.makedirs(args.outputdir) 51 | 52 | # Map actions to respective functions 53 | action_map = {'build': build, 'generate-templates': generate_templates, 54 | 'list-distros': list_distros} 55 | 56 | # Lookup action from map 57 | action = action_map[args.action] 58 | # Execute action 59 | action(args) 60 | 61 | 62 | if __name__ == '__main__': 63 | main() 64 | -------------------------------------------------------------------------------- /packer_builder/build.py: -------------------------------------------------------------------------------- 1 | """Build generated Packer template.""" 2 | import json 3 | import logging 4 | import os 5 | import subprocess 6 | import sys 7 | import time 8 | from datetime import datetime 9 | from shutil import which 10 | from packer_builder.template import Template 11 | 12 | 13 | # pylint: disable=too-many-instance-attributes 14 | class Build(): 15 | """Main builder process.""" 16 | 17 | def __init__(self, args, distros): 18 | # Setup logger 19 | self.logger = logging.getLogger(__name__) 20 | # Define distros 21 | self.distros = distros 22 | # Define build directory 23 | self.build_dir = args.outputdir 24 | # Log build directory 25 | self.logger.info('Build dir: %s', self.build_dir) 26 | # Define build manifest file 27 | self.build_manifest_file = os.path.join( 28 | self.build_dir, 'packer-builder.json') 29 | # Define number of days since last build 30 | self.num_days = args.numdays 31 | 32 | # Only build a single distro if passed 33 | if args.distro is not None: 34 | self.distro = args.distro 35 | # Build all distros 36 | else: 37 | self.distro = 'all' 38 | 39 | # Only build for a single builder 40 | if args.builder is not None: 41 | self.builder = args.builder 42 | # Build all builders 43 | else: 44 | self.builder = 'all' 45 | 46 | # Define password override if passed 47 | self.password_override = args.password 48 | self.load_build_manifest() 49 | self.iterate() 50 | 51 | def load_build_manifest(self): 52 | """Load up existing build manifest, otherwise create one.""" 53 | if os.path.isfile(self.build_manifest_file): 54 | with open(self.build_manifest_file, 'r') as stream: 55 | self.logger.info( 56 | 'Loading build manifest: %s', self.build_manifest_file) 57 | self.build_manifest = json.load(stream) 58 | else: 59 | self.build_manifest = dict() 60 | 61 | # pylint: disable=too-many-locals 62 | def iterate(self): 63 | """Iterate through defined distros and build them.""" 64 | 65 | # Define current directory 66 | self.current_dir = os.getcwd() 67 | # Log current directory 68 | self.logger.info('Current directory: %s', self.current_dir) 69 | 70 | # Iterate through distros 71 | for distro, distro_spec in self.distros.items(): 72 | # Log distro 73 | self.logger.info('distro: %s', distro) 74 | # Log distro spec 75 | self.logger.info('distro_spec: %s', distro_spec) 76 | # Get builders 77 | self.builders = distro_spec['builders'] 78 | 79 | # Check build manifest for distro 80 | distro_check = self.build_manifest.get(distro) 81 | # Log distro check 82 | self.logger.info('Distro check: %s', distro_check) 83 | 84 | if distro_check is None: 85 | self.build_manifest[distro] = dict() 86 | 87 | if self.distro == 'all' or (self.distro != 'all' and 88 | self.distro == distro): 89 | for version, version_spec in distro_spec['versions'].items(): 90 | version = str(version) 91 | version_check = self.build_manifest[distro].get(version) 92 | # Log version 93 | self.logger.info('version: %s', version) 94 | # Log version_check 95 | self.logger.info('version_check: %s', version_check) 96 | 97 | if version_check is None: 98 | self.build_manifest[distro][version] = { 99 | 'builds': []} 100 | 101 | build_image = False 102 | current_time_epoch = time.mktime( 103 | datetime.now().timetuple()) 104 | last_build_time_epoch = self.build_manifest[distro][ 105 | version].get('last_build_time') 106 | if last_build_time_epoch is not None: 107 | older_than_days_epoch = current_time_epoch - \ 108 | (86400 * self.num_days) 109 | older_than_days = int( 110 | (older_than_days_epoch/86400) + 25569) 111 | last_build_time = int( 112 | (float(last_build_time_epoch)/86400) + 25569) 113 | if last_build_time < older_than_days: 114 | build_image = True 115 | else: 116 | build_image = True 117 | 118 | self.logger.info('Build image: %s', build_image) 119 | 120 | if build_image: 121 | # Define data to pass to class 122 | data = {'output_dir': self.build_dir, 123 | 'password_override': self.password_override, 124 | 'distro': distro, 'distro_spec': distro_spec, 125 | 'version': version, 126 | 'version_spec': version_spec} 127 | 128 | # Generate the template 129 | template = Template(data=data) 130 | # Save template for processing 131 | template.save() 132 | 133 | # # Validate template 134 | # self.validate() 135 | template.validate() 136 | 137 | # Build image from template 138 | self.build() 139 | 140 | self.build_manifest[distro][version][ 141 | 'last_build_time'] = current_time_epoch 142 | 143 | build_info = { 144 | 'builder_types': self.builders, 145 | 'build_time': current_time_epoch 146 | } 147 | 148 | self.build_manifest[distro][version]['builds'].append( 149 | build_info) 150 | 151 | with open(self.build_manifest_file, 'w') as stream: 152 | self.logger.info( 153 | 'Saving build manifest: %s', 154 | self.build_manifest_file) 155 | stream.write(json.dumps( 156 | self.build_manifest, indent=4)) 157 | 158 | def build(self): 159 | """Build generated Packer template.""" 160 | 161 | os.chdir(self.build_dir) 162 | 163 | # Check which of the defined builders are available and only launch 164 | # those. Values in the dict are: 165 | # "builder-name" : ["executable", "names"] 166 | builder_defs = { 167 | "vmware-iso": [ 168 | "vmware", 169 | "vmplayer", 170 | "vmware-vmx" 171 | ], 172 | "virtualbox-iso": [ 173 | "virtualbox", 174 | ], 175 | "qemu": [ 176 | "qemu-system-x86_64", 177 | ], 178 | } 179 | builders_found = [b if which(builder_exec) else None 180 | for b, builder_execs in builder_defs.items() 181 | for builder_exec in builder_execs] 182 | self.logger.info('Builders found: %s', builders_found) 183 | 184 | if self.builder != 'all': 185 | if self.builder not in builders_found: 186 | self.logger.error('Builder %s not installed', self.builder) 187 | sys.exit(1) 188 | elif self.builder not in self.builders: 189 | self.logger.error('Builder %s is not defined.', self.builder) 190 | sys.exit(1) 191 | else: 192 | builders_avail = set(self.builder.split()) & set( 193 | self.builders) & set(builders_found) 194 | else: 195 | builders_avail = set(self.builders) & set(builders_found) 196 | 197 | self.logger.info('Builders avail: %s', builders_avail) 198 | 199 | # We need to account for QEMU and VirtualBox not being able to execute 200 | # at the same time. If found installed QEMU will run separately. QEMU 201 | # will more than likely be the one off use case. 202 | if 'qemu' in builders_avail: 203 | build_commands = ['packer', 'build', 204 | '-only=qemu', 'template.json'] 205 | self.logger.info('Build commands: %s', build_commands) 206 | self.process(build_commands) 207 | builders_avail.remove('qemu') 208 | 209 | # Now run everything else 210 | build_commands = ['packer', 'build', 211 | '-only={}'.format(','.join(builders_avail)), 212 | 'template.json'] 213 | 214 | self.logger.info('Build commands: %s', build_commands) 215 | self.process(build_commands) 216 | os.chdir(self.current_dir) 217 | 218 | def process(self, build_commands): 219 | """Process build based on commands passed.""" 220 | 221 | build = subprocess.run(build_commands, check=False) 222 | 223 | # Log and exit if failed 224 | if build.returncode != 0: 225 | self.logger.error(build) 226 | sys.exit(1) 227 | else: 228 | self.logger.info(build) 229 | -------------------------------------------------------------------------------- /packer_builder/cli.py: -------------------------------------------------------------------------------- 1 | """packer_builder/cli.py""" 2 | 3 | import argparse 4 | from packer_builder.release import __package_name__, __version__ 5 | 6 | 7 | def cli_args(): 8 | """Console script for packer_builder.""" 9 | parser = argparse.ArgumentParser(description="Packer builder.") 10 | parser.add_argument('action', choices=[ 11 | 'build', 'generate-templates', 'list-distros', 12 | 'update-metadata']) 13 | parser.add_argument('-d', '--distro', help='Only build specific distro.') 14 | parser.add_argument('-b', '--builder', help='Only use specific builder.') 15 | parser.add_argument( 16 | '-f', '--file', help='Path to distro.', default='distros.yml') 17 | parser.add_argument('-n', '--numdays', 18 | help='Define number of days since last build.', 19 | default=30) 20 | parser.add_argument('-o', '--outputdir', 21 | help='Define path to save builds.') 22 | parser.add_argument('-p', '--password', 23 | help='Define default password to override distros.yml') 24 | 25 | parser.add_argument('--version', action='version', 26 | version=f'{__package_name__} {__version__}') 27 | args = parser.parse_args() 28 | if (args.action in ['build', 'generate-templates'] and 29 | args.outputdir is None): 30 | parser.error('--outputdir is REQUIRED!') 31 | 32 | return args 33 | -------------------------------------------------------------------------------- /packer_builder/distros.py: -------------------------------------------------------------------------------- 1 | """Load distros YAML file for parsing.""" 2 | import json 3 | import logging 4 | import yaml 5 | 6 | 7 | class Distros(): 8 | """Main execution of loading and parsing distros YAML file.""" 9 | 10 | def __init__(self, args): 11 | """Init a thing.""" 12 | 13 | self.file = args.file 14 | # Setup logging 15 | self.logger = logging.getLogger(__name__) 16 | # Define distros dictionary 17 | self.distros = dict() 18 | # Load YAML 19 | self.load_file() 20 | # Parse YAML 21 | self.parse_file() 22 | 23 | def load_file(self): 24 | """Load distros YAML file for parsing.""" 25 | 26 | self.logger.info('Loading: %s', self.file) 27 | with open(self.file, 'r') as file: 28 | self.data = yaml.load(file, Loader=yaml.FullLoader) 29 | 30 | def parse_file(self): 31 | """Parse distros YAML file.""" 32 | 33 | self.logger.info('Parsing: %s', self.data) 34 | for key, value in self.data.items(): 35 | self.distros[key] = value 36 | 37 | def get(self): 38 | """Get distros found in YAML file.""" 39 | 40 | return self.distros 41 | 42 | def list_(self): 43 | """Return list of distros available.""" 44 | 45 | print(json.dumps(self.distros)) 46 | -------------------------------------------------------------------------------- /packer_builder/http/alpine/answers.j2: -------------------------------------------------------------------------------- 1 | KEYMAPOPTS="us us" 2 | HOSTNAMEOPTS="-n alpine-test" 3 | INTERFACESOPTS="auto lo 4 | iface lo inet loopback 5 | 6 | auto eth0 7 | iface eth0 inet dhcp 8 | hostname alpine-test 9 | " 10 | 11 | DNSOPTS="-d example.com 8.8.8.8" 12 | TIMEZONEOPTS="-z UTC" 13 | PROXYOPTS="none" 14 | APKREPOSOPTS="-r" 15 | SSHDOPTS="-c openssh" 16 | NTPOPTS="-c openntpd" 17 | DISKOPTS="-s 0 -m sys /dev/dev_replace" -------------------------------------------------------------------------------- /packer_builder/http/centos/ks.cfg.j2: -------------------------------------------------------------------------------- 1 | # Required settings 2 | lang en_US.UTF-8 3 | keyboard us 4 | rootpw {{ password }} 5 | authconfig --enableshadow --enablemd5 6 | timezone UTC 7 | 8 | # Optional settings 9 | autopart --nolvm 10 | bootloader --location=mbr 11 | cdrom 12 | clearpart --all --initlabel 13 | firewall --disabled 14 | firstboot --disabled 15 | install 16 | network --bootproto=dhcp 17 | reboot 18 | selinux --disabled 19 | skipx 20 | text 21 | zerombr 22 | 23 | # Packages 24 | %packages --ignoremissing 25 | @Base 26 | curl 27 | gcc 28 | kernel-devel 29 | kernel-headers 30 | make 31 | %end 32 | 33 | # Post 34 | %post 35 | # /usr/bin/yum -y update 36 | /usr/bin/yum -y install epel-release 37 | /usr/bin/yum -y install perl redhat-lsb-core sudo wget 38 | /usr/sbin/groupadd {{ username }} 39 | /usr/sbin/useradd {{ username }} -g {{ username }} -G wheel 40 | echo "{{ password }}"|passwd --stdin {{ username }} 41 | echo "{{ username }} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 42 | sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers 43 | %end 44 | -------------------------------------------------------------------------------- /packer_builder/http/debian/preseed.cfg.j2: -------------------------------------------------------------------------------- 1 | ### Localization 2 | d-i debian-installer/locale string en_US 3 | d-i debian-installer/language string en 4 | d-i debian-installer/country string US 5 | d-i debian-installer/locale string en_US.UTF-8 6 | d-i localechooser/supported-locales multiselect en_US.UTF-8 7 | 8 | # Keyboard selection. 9 | d-i console-tools/archs select at 10 | d-i console-keymaps-at/keymap select us 11 | 12 | d-i keyboard-configuration/xkb-keymap select us 13 | 14 | ### Network configuration 15 | d-i netcfg/choose_interface select auto 16 | d-i netcfg/get_domain string unassigned-domain 17 | d-i netcfg/get_hostname string unassigned-hostname 18 | d-i netcfg/wireless_wep string 19 | 20 | d-i hw-detect/load_firmware boolean true 21 | 22 | ### Mirror settings 23 | d-i mirror/country string manual 24 | d-i mirror/http/hostname string http.debian.net 25 | d-i mirror/http/directory string /debian 26 | d-i mirror/http/proxy string 27 | d-i mirror/suite string wheezy 28 | 29 | ### Account setup 30 | d-i passwd/root-password {{ password }} 31 | d-i passwd/root-password-again {{ password }} 32 | d-i passwd/user-fullname string {{ username }} Default User 33 | d-i passwd/username string {{ username }} 34 | d-i passwd/user-password password {{ password }} 35 | d-i passwd/user-password-again password {{ password }} 36 | 37 | ### Clock and time zone setup 38 | d-i clock-setup/utc boolean true 39 | d-i time/zone string GMT+0 40 | d-i clock-setup/ntp boolean true 41 | 42 | ### Partitioning 43 | d-i partman-auto/method string regular 44 | # d-i partman-auto/choose_recipe select atomic 45 | d-i partman-partitioning/confirm_write_new_label boolean true 46 | d-i partman/choose_partition select finish 47 | d-i partman/confirm boolean true 48 | d-i partman/confirm_nooverwrite boolean true 49 | d-i partman/mount_style select uuid 50 | d-i partman-auto/expert_recipe string \ 51 | scheme :: \ 52 | 1024 0 1024 ext4 \ 53 | $primary{ } \ 54 | $bootable{ } \ 55 | method{ format } \ 56 | format{ } \ 57 | use_filesystem{ } \ 58 | filesystem{ ext4 } \ 59 | mountpoint{ /boot } . \ 60 | 200% 0 200% linux-swap \ 61 | $primary{ } \ 62 | method{ swap } \ 63 | format{ } . \ 64 | 1 0 -1 ext4 \ 65 | $primary{ } \ 66 | method{ format } \ 67 | format{ } \ 68 | use_filesystem{ } \ 69 | filesystem{ ext4 } \ 70 | mountpoint{ / } . 71 | 72 | ### Apt setup 73 | # do not scan for other CDs 74 | # see http://serverfault.com/a/622818 75 | # maybe related to 4a2145d3a86a2c5dcec4e2571197ea5a10313b59 in apt-setup 76 | d-i apt-setup/cdrom/set-first boolean false 77 | d-i apt-setup/cdrom/set-next boolean false 78 | d-i apt-setup/cdrom/set-failed boolean false 79 | 80 | d-i apt-setup/non-free boolean false 81 | d-i apt-setup/contrib boolean false 82 | d-i apt-setup/services-select multiselect security 83 | d-i apt-setup/security_host string security.debian.org 84 | 85 | ### Package selection 86 | d-i pkgsel/include string bc curl lsb-release openssh-server ntp sudo wget 87 | d-i pkgsel/upgrade select safe-upgrade 88 | tasksel tasksel/first multiselect 89 | popularity-contest popularity-contest/participate boolean false 90 | 91 | ### GRUB 92 | d-i grub-installer/only_debian boolean true 93 | d-i grub-installer/bootdev string default 94 | 95 | ### Finishing up the installation 96 | d-i finish-install/keep-consoles boolean true 97 | d-i finish-install/reboot_in_progress note 98 | 99 | ### Late commands 100 | d-i preseed/late_command string \ 101 | in-target sed -i 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g' /etc/sudoers -------------------------------------------------------------------------------- /packer_builder/http/fedora/ks.cfg.j2: -------------------------------------------------------------------------------- 1 | # Required settings 2 | lang en_US.UTF-8 3 | keyboard us 4 | rootpw {{ password }} 5 | authconfig --enableshadow --enablemd5 6 | timezone UTC 7 | url --mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch 8 | 9 | # Optional settings 10 | autopart --nolvm 11 | bootloader --location=mbr 12 | network 13 | clearpart --all --initlabel 14 | firewall --disabled 15 | firstboot --disabled 16 | install 17 | network --bootproto=dhcp 18 | reboot 19 | selinux --disabled 20 | skipx 21 | text 22 | zerombr 23 | 24 | # Packages 25 | %packages --ignoremissing 26 | @Base 27 | curl 28 | gcc 29 | kernel-devel 30 | kernel-headers 31 | make 32 | %end 33 | 34 | # Post 35 | %post 36 | /usr/bin/dnf -y update 37 | /usr/bin/dnf -y install epel-release 38 | /usr/bin/dnf -y install perl redhat-lsb-core rsyslog sudo wget 39 | /usr/sbin/groupadd {{ username }} 40 | /usr/sbin/useradd {{ username }} -g {{ username }} -G wheel 41 | echo "{{ password }}"|passwd --stdin {{ username }} 42 | echo "{{ username }} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 43 | %end -------------------------------------------------------------------------------- /packer_builder/http/ubuntu/preseed.cfg.j2: -------------------------------------------------------------------------------- 1 | ### Localization 2 | d-i console-setup/ask_detect boolean false 3 | d-i console-setup/layout string USA 4 | d-i debian-installer/locale string en_US.utf8 5 | 6 | ### Network 7 | d-i netcfg/get_domain string unassigned-domain 8 | d-i netcfg/get_hostname string unassigned-hostname 9 | d-i netcfg/wireless_wep string 10 | 11 | ### Clock and timezone 12 | d-i clock-setup/utc boolean true 13 | d-i clock-setup/utc-auto boolean true 14 | d-i time/zone string UTC 15 | 16 | ### Keyboard 17 | d-i kbd-chooser/method select American English 18 | 19 | ### Partitioning 20 | d-i partman-auto/method string regular 21 | # d-i partman-auto/choose_recipe select atomic 22 | d-i partman-partitioning/confirm_write_new_label boolean true 23 | d-i partman/choose_partition select finish 24 | d-i partman/confirm boolean true 25 | d-i partman/confirm_nooverwrite boolean true 26 | d-i partman/mount_style select uuid 27 | d-i partman-auto/expert_recipe string \ 28 | scheme :: \ 29 | 1024 0 1024 ext4 \ 30 | $primary{ } \ 31 | $bootable{ } \ 32 | method{ format } \ 33 | format{ } \ 34 | use_filesystem{ } \ 35 | filesystem{ ext4 } \ 36 | mountpoint{ /boot } . \ 37 | 200% 0 200% linux-swap \ 38 | $primary{ } \ 39 | method{ swap } \ 40 | format{ } . \ 41 | 1 0 -1 ext4 \ 42 | $primary{ } \ 43 | method{ format } \ 44 | format{ } \ 45 | use_filesystem{ } \ 46 | filesystem{ ext4 } \ 47 | mountpoint{ / } . 48 | 49 | ### Accounts 50 | d-i passwd/user-fullname string {{ username }} 51 | d-i passwd/user-password password {{ password }} 52 | d-i passwd/user-password-again password {{ password }} 53 | d-i passwd/username string {{ username }} 54 | d-i user-setup/allow-password-weak boolean true 55 | d-i user-setup/encrypt-home boolean false 56 | 57 | ### Mirror 58 | choose-mirror-bin mirror/http/proxy string 59 | 60 | ### Package selections 61 | d-i base-installer/kernel/override-image string linux-server 62 | d-i debconf debconf/frontend select Noninteractive 63 | d-i pkgsel/include string bc curl lsb-release openssh-server ntp wget 64 | d-i pkgsel/install-language-support boolean false 65 | d-i pkgsel/update-policy select none 66 | d-i pkgsel/upgrade select full-upgrade 67 | tasksel tasksel/first multiselect standard, ubuntu-server 68 | 69 | ### Grub 70 | d-i grub-installer/only_debian boolean true 71 | d-i grub-installer/with_other_os boolean true 72 | 73 | ### Finish install 74 | d-i finish-install/reboot_in_progress note 75 | 76 | ### Late commands 77 | d-i preseed/late_command string \ 78 | in-target sed -i 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g' /etc/sudoers 79 | -------------------------------------------------------------------------------- /packer_builder/logger.py: -------------------------------------------------------------------------------- 1 | """packer_builder/logger.py""" 2 | 3 | import logging 4 | import os 5 | from logging.handlers import TimedRotatingFileHandler 6 | 7 | 8 | def setup_logger(): 9 | """Setup main logger.""" 10 | 11 | # Define parent directory to determine root log directory 12 | # Excluded in .gitignore 13 | parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 | # Define logs directory 15 | log_dir = os.path.join(parent_dir, 'logs') 16 | # Define log file 17 | log_file = os.path.join(log_dir, 'packer_builder.log') 18 | 19 | # Create logs directory if it does not exist 20 | if not os.path.isdir(log_dir): 21 | os.makedirs(log_dir) 22 | 23 | # Setup formatting 24 | formatter = logging.Formatter( 25 | '%(asctime)s - %(name)s - %(levelname)s - %(message)s') 26 | # Setup log 27 | logger = logging.getLogger() 28 | # Setup log level 29 | logger.setLevel(logging.DEBUG) 30 | 31 | # Setup console handler 32 | console_handler = logging.StreamHandler() 33 | # Setup console handler level 34 | console_handler.setLevel(logging.WARNING) 35 | # Add formatting to console handler 36 | console_handler.setFormatter(formatter) 37 | # Add console handler to log 38 | logger.addHandler(console_handler) 39 | 40 | # Setup file handler 41 | file_handler = TimedRotatingFileHandler( 42 | log_file, when='midnight', backupCount=7) 43 | # Setup file handler level 44 | file_handler.setLevel(logging.DEBUG) 45 | # Add formatting to file handler 46 | file_handler.setFormatter(formatter) 47 | # Add file handler to log 48 | logger.addHandler(file_handler) 49 | 50 | return logger 51 | -------------------------------------------------------------------------------- /packer_builder/release.py: -------------------------------------------------------------------------------- 1 | """packer_builder/release.py""" 2 | 3 | # Version tracking for package. 4 | __author__ = 'Larry Smith Jr.' 5 | __version__ = '0.1.0' 6 | __package_name__ = 'packer_builder' 7 | -------------------------------------------------------------------------------- /packer_builder/scripts/base.ps1: -------------------------------------------------------------------------------- 1 | $ansible_script = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1" 2 | $chocolatey_script = "https://chocolatey.org/install.ps1" 3 | 4 | # Install Chocolatey Package Manager 5 | Set-ExecutionPolicy Bypass -Scope Process -Force; iex ( 6 | (New-Object System.Net.WebClient).DownloadString($chocolatey_script)) 7 | 8 | # Enable Remote Desktop 9 | (Get-WmiObject Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).SetAllowTsConnections(1, 1) 10 | (Get-WmiObject -Class "Win32_TSGeneralSetting" -Namespace root\cimv2\TerminalServices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0) 11 | 12 | # Install Chocolatey Packages 13 | choco install -y 7zip sdelete 14 | 15 | if ($PSVersionTable.PSVersion.Major -lt 3) { 16 | Write-Host "Upgrading PowerShell" 17 | choco upgrade -y dotnet4.5 18 | choco upgrade -y powershell 19 | refreshenv 20 | } 21 | 22 | # Setup WinRM for Ansible Management 23 | Set-ExecutionPolicy Bypass -Scope Process -Force; iex ( 24 | (New-Object System.Net.WebClient).DownloadString($ansible_script)) 25 | -------------------------------------------------------------------------------- /packer_builder/scripts/base.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ -f /etc/os-release ]; then 7 | # shellcheck disable=SC1091 8 | source /etc/os-release 9 | id=$ID 10 | os_version_id=$VERSION_ID 11 | 12 | elif [ -f /etc/redhat-release ]; then 13 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 14 | os_version_id="$(awk '{ print $3 }' /etc/redhat-release | sed 's/"//g' | awk -F. '{ print $1 }')" 15 | fi 16 | 17 | if [[ $id == "ol" ]]; then 18 | os_version_id_short="$(echo $os_version_id | cut -f1 -d".")" 19 | else 20 | os_version_id_short="$(echo $os_version_id | cut -f1-2 -d".")" 21 | fi 22 | 23 | if [[ $id == "alpine" ]]; then 24 | chmod u+s /usr/bin/sudo 25 | apk add python alpine-sdk || true 26 | 27 | elif [[ $id == "arch" ]]; then 28 | yes | sudo pacman -Syyu && yes | sudo pacman -S gc guile autoconf automake \ 29 | binutils bison fakeroot file findutils flex gcc gettext grep \ 30 | groff gzip libtool m4 make pacman patch pkgconf sed sudo systemd \ 31 | texinfo util-linux which python-setuptools python-virtualenv python-pip \ 32 | python-pyopenssl python2-setuptools python2-virtualenv python2-pip \ 33 | python2-pyopenssl 34 | 35 | elif [[ $id == "centos" || $id == "ol" ]]; then 36 | if [[ $os_version_id_short -eq 5 ]]; then 37 | for F in /etc/yum.repos.d/*.repo; do 38 | sudo bash -c "echo '# EOL DISTRO' > $F" 39 | done 40 | cat <<_EOF_ | sudo bash -c "cat > /etc/yum.repos.d/Vault.repo" 41 | [base] 42 | name=CentOS-5.11 - Base 43 | baseurl=http://vault.centos.org/5.11/os/\$basearch/ 44 | gpgcheck=1 45 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 46 | enabled=1 47 | [updates] 48 | name=CentOS-5.11 - Updates 49 | baseurl=http://vault.centos.org/5.11/updates/\$basearch/ 50 | gpgcheck=1 51 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 52 | enabled=1 53 | [extras] 54 | name=CentOS-5.11 - Extras 55 | baseurl=http://vault.centos.org/5.11/extras/\$basearch/ 56 | gpgcheck=1 57 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 58 | enabled=1 59 | [centosplus] 60 | name=CentOS-5.11 - Plus 61 | baseurl=http://vault.centos.org/5.11/centosplus/\$basearch/ 62 | gpgcheck=1 63 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 64 | enabled=1 65 | _EOF_ 66 | fi 67 | 68 | if [[ $id != "ol" ]]; then 69 | sudo yum -y install epel-release 70 | else 71 | if [[ $os_version_id_short -eq 7 ]]; then 72 | sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 73 | 74 | elif [[ $os_version_id_short -eq 8 ]]; then 75 | sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 76 | fi 77 | fi 78 | 79 | if [[ $os_version_id_short -lt 8 ]]; then 80 | sudo yum -y install cloud-utils-growpart python-devel 81 | else 82 | sudo yum -y install cloud-utils-growpart platform-python-devel 83 | fi 84 | 85 | elif [[ $id == "debian" ]]; then 86 | sudo apt-get update 87 | echo "libc6:amd64 libraries/restart-without-asking boolean true" | sudo debconf-set-selections 88 | echo "libssl1.1:amd64 libssl1.1/restart-services string" | sudo debconf-set-selections 89 | sudo apt-get install -y python-minimal linux-headers-"$(uname -r)" \ 90 | build-essential zlib1g-dev libssl-dev libreadline-gplv2-dev unzip 91 | 92 | if [[ ! -f /etc/vyos_build ]]; then 93 | if [[ $os_version_id -gt 7 ]]; then 94 | sudo apt-get -y install cloud-initramfs-growroot 95 | fi 96 | fi 97 | 98 | elif [[ $id == "elementary" ]]; then 99 | sudo apt-get update 100 | echo "libc6:amd64 libraries/restart-without-asking boolean true" | sudo debconf-set-selections 101 | echo "libssl1.1:amd64 libssl1.1/restart-services string" | sudo debconf-set-selections 102 | sudo apt-get install -y python-minimal linux-headers-"$(uname -r)" \ 103 | build-essential zlib1g-dev libssl-dev libreadline-gplv2-dev unzip 104 | 105 | if [[ ! -f /etc/vyos_build ]]; then 106 | if [[ $os_version_id -gt 7 ]]; then 107 | sudo apt-get -y install cloud-initramfs-growroot 108 | fi 109 | fi 110 | 111 | elif [[ $id == "fedora" ]]; then 112 | if [[ $os_version_id -lt 30 ]]; then 113 | sudo dnf -y install python-devel python-dnf 114 | else 115 | sudo dnf -y install initscripts python-devel python3-dnf 116 | fi 117 | 118 | elif [[ $id == "linuxmint" ]]; then 119 | sudo apt-get update 120 | echo "libc6:amd64 libraries/restart-without-asking boolean true" | sudo debconf-set-selections 121 | echo "libssl1.1:amd64 libssl1.1/restart-services string" | sudo debconf-set-selections 122 | sudo apt-get install -y python-minimal linux-headers-"$(uname -r)" \ 123 | build-essential zlib1g-dev libssl-dev libreadline-gplv2-dev unzip 124 | 125 | if [[ ! -f /etc/vyos_build ]]; then 126 | if [[ $os_version_id -gt 7 ]]; then 127 | sudo apt-get -y install cloud-initramfs-growroot 128 | fi 129 | fi 130 | 131 | elif [[ $id == "opensuse" || $id == "opensuse-leap" ]]; then 132 | sudo zypper --non-interactive install python-devel 133 | 134 | elif [[ $id == "ubuntu" ]]; then 135 | if (($(echo $os_version_id '==' 12.04 | bc))); then 136 | sudo apt-get clean 137 | sudo rm -r /var/lib/apt/lists/* 138 | fi 139 | sudo apt-get update 140 | echo "libc6:amd64 libraries/restart-without-asking boolean true" | sudo debconf-set-selections 141 | echo "libssl1.1:amd64 libssl1.1/restart-services string" | sudo debconf-set-selections 142 | if [[ $os_version_id_short -lt 20.04 ]]; then 143 | sudo apt-get install -y python-minimal 144 | fi 145 | sudo apt-get install -y linux-headers-"$(uname -r)" \ 146 | build-essential zlib1g-dev libssl-dev libreadline-gplv2-dev unzip 147 | if [[ ! -f /etc/vyos_build ]]; then 148 | sudo apt-get -y install cloud-initramfs-growroot 149 | fi 150 | fi 151 | 152 | if [[ $id == "debian" || $id == "elementary" || $id == "linuxmint" || $id == "ubuntu" ]]; then 153 | if [[ $id == "elementary" || $id == "linuxmint" ]]; then 154 | # Remove /etc/rc.local used for provisioning 155 | sudo rm /etc/rc.local 156 | if [ -f /etc/rc.local.orig ]; then 157 | sudo mv /etc/rc.local.orig /etc/rc.local 158 | fi 159 | fi 160 | 161 | # Check for /etc/rc.local and create if needed. This has been depricated in 162 | # Debian 9 and later. So we need to resolve this in order to regenerate SSH host 163 | # keys. 164 | if [ ! -f /etc/rc.local ]; then 165 | sudo bash -c "echo '#!/bin/sh -e' > /etc/rc.local" 166 | sudo bash -c "echo 'test -f /etc/ssh/ssh_host_dsa_key || dpkg-reconfigure openssh-server' >> /etc/rc.local" 167 | sudo bash -c "echo 'exit 0' >> /etc/rc.local" 168 | sudo chmod +x /etc/rc.local 169 | sudo systemctl daemon-reload 170 | sudo systemctl enable rc-local 171 | sudo systemctl start rc-local 172 | else 173 | sudo bash -c "sed -i -e 's|exit 0||' /etc/rc.local" 174 | sudo bash -c "sed -i -e 's|.*test -f /etc/ssh/ssh_host_dsa_key.*||' /etc/rc.local" 175 | sudo bash -c "echo 'test -f /etc/ssh/ssh_host_dsa_key || dpkg-reconfigure openssh-server' >> /etc/rc.local" 176 | sudo bash -c "echo 'exit 0' >> /etc/rc.local" 177 | fi 178 | fi 179 | 180 | # Fix machine-id issue with duplicate IP addresses being assigned 181 | if [ -f /etc/machine-id ]; then 182 | sudo truncate -s 0 /etc/machine-id 183 | fi 184 | -------------------------------------------------------------------------------- /packer_builder/scripts/bootstrap.ps1: -------------------------------------------------------------------------------- 1 | # This script is called from the answerfile 2 | 3 | # Add The Oracle Cert For VirtualBox 4 | certutil -addstore -f "TrustedPublisher" a:\oracle-cert.cer 5 | 6 | # Supress network location Prompt 7 | New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Network\NewNetworkWindowOff" -Force 8 | 9 | # Set network to private 10 | $ifaceinfo = Get-NetConnectionProfile 11 | Set-NetConnectionProfile -InterfaceIndex $ifaceinfo.InterfaceIndex -NetworkCategory Private 12 | 13 | Function Enable-WinRM { 14 | Write-Host "Enable WinRM" 15 | netsh advfirewall firewall set rule group="remote administration" new enable=yes 16 | netsh advfirewall firewall add rule name="Open Port 5985" dir=in action=allow protocol=TCP localport=5985 17 | 18 | winrm quickconfig -q 19 | winrm quickconfig -transport:http 20 | winrm set winrm/config '@{MaxTimeoutms="7200000"}' 21 | winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' 22 | winrm set winrm/config/winrs '@{MaxProcessesPerShell="0"}' 23 | winrm set winrm/config/winrs '@{MaxShellsPerUser="0"}' 24 | winrm set winrm/config/service '@{AllowUnencrypted="true"}' 25 | winrm set winrm/config/service/auth '@{Basic="true"}' 26 | winrm set winrm/config/client/auth '@{Basic="true"}' 27 | 28 | net stop winrm 29 | sc.exe config winrm start= auto 30 | net start winrm 31 | 32 | } 33 | 34 | Enable-WinRM 35 | -------------------------------------------------------------------------------- /packer_builder/scripts/cleanup.ps1: -------------------------------------------------------------------------------- 1 | Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase 2 | Optimize-Volume -DriveLetter C 3 | sdelete -q -z c: -------------------------------------------------------------------------------- /packer_builder/scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ -f /etc/os-release ]; then 7 | # shellcheck disable=SC1091 8 | source /etc/os-release 9 | id=$ID 10 | 11 | elif [ -f /etc/redhat-release ]; then 12 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 13 | fi 14 | 15 | if [[ $id == "arch" ]]; then 16 | /usr/bin/yes | sudo /usr/bin/pacman -Scc 17 | 18 | elif [[ $id == "centos" || $id == "ol" ]]; then 19 | sudo yum clean all 20 | sudo rm -rf /var/cache/yum 21 | 22 | elif [[ $id == "debian" || $id == "elementary" || $id == "linuxmint" || $id == "ubuntu" ]]; then 23 | sudo apt-get clean 24 | 25 | elif [[ $id == "fedora" ]]; then 26 | sudo dnf clean all 27 | 28 | elif [[ $id == "opensuse" || $id == "opensuse-leap" ]]; then 29 | if [ -f /var/lib/misc/random-seed ]; then 30 | rm /var/lib/misc/random-seed 31 | fi 32 | if [ -f /var/lib/systemd/random-seed ]; then 33 | rm /var/lib/systemd/random-seed 34 | fi 35 | fi 36 | 37 | # Stop rsyslog service 38 | if [[ $id != "arch" ]]; then 39 | sudo service rsyslog stop 40 | fi 41 | 42 | #clear audit logs 43 | if [ -f /var/log/audit/audit.log ]; then 44 | sudo bash -c "cat /dev/null > /var/log/audit/audit.log" 45 | fi 46 | if [ -f /var/log/wtmp ]; then 47 | sudo bash -c "cat /dev/null > /var/log/wtmp" 48 | fi 49 | if [ -f /var/log/lastlog ]; then 50 | sudo bash -c "cat /dev/null > /var/log/lastlog" 51 | fi 52 | 53 | #cleanup persistent udev rules 54 | if [ -f /etc/udev/rules.d/70-persistent-net.rules ]; then 55 | sudo rm /etc/udev/rules.d/70-persistent-net.rules 56 | fi 57 | 58 | #cleanup /tmp directories 59 | sudo rm -rf /tmp/* 60 | sudo rm -rf /var/tmp/* 61 | 62 | #cleanup current ssh keys 63 | sudo rm -f /etc/ssh/ssh_host_* 64 | 65 | #reset hostname 66 | sudo bash -c "cat /dev/null > /etc/hostname" 67 | 68 | #cleanup shell history 69 | history -w 70 | history -c 71 | -------------------------------------------------------------------------------- /packer_builder/scripts/desktop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | USERNAME=vagrant 7 | 8 | if [ -f /etc/os-release ]; then 9 | # shellcheck disable=SC1091 10 | source /etc/os-release 11 | id=$ID 12 | os_version_id=$VERSION_ID 13 | 14 | elif [ -f /etc/redhat-release ]; then 15 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 16 | os_version_id="$(awk '{ print $3 }' /etc/redhat-release | sed 's/"//g' | awk -F. '{ print $1 }')" 17 | fi 18 | 19 | if [[ $id == "debian" ]]; then 20 | echo "==> Installing ubuntu-desktop" 21 | sudo apt-get install -y --no-install-recommends gnome-core xorg 22 | 23 | if [[ $os_version_id -lt 9 ]]; then 24 | GDM_CONFIG=/etc/gdm/daemon.conf 25 | else 26 | GDM_CONFIG=/etc/gdm3/daemon.conf 27 | fi 28 | 29 | sudo mkdir -p "$(dirname ${GDM_CONFIG})" 30 | sudo bash -c "echo "[daemon]" > $GDM_CONFIG" 31 | sudo bash -c "echo " # Enabling automatic login" >> $GDM_CONFIG" 32 | sudo bash -c "echo "AutomaticLoginEnable=True" >> $GDM_CONFIG" 33 | sudo bash -c "echo "AutomaticLogin=${USERNAME}" >> $GDM_CONFIG" 34 | # LIGHTDM_CONFIG=/etc/lightdm/lightdm.conf 35 | # echo "==> Configuring lightdm autologin" 36 | # sudo bash -c "echo "[SeatDefaults]" >> $LIGHTDM_CONFIG" 37 | # sudo bash -c "echo "autologin-user=${USERNAME}" >> $LIGHTDM_CONFIG" 38 | 39 | elif [[ $id == "elementary" || $id == "linuxmint" ]]; then 40 | GDM_CUSTOM_CONFIG=/etc/gdm3/custom.conf 41 | LIGHTDM_CONFIG=/etc/lightdm/lightdm.conf 42 | 43 | echo "==> Configuring lightdm autologin" 44 | sudo bash -c "echo "[SeatDefaults]" >> $LIGHTDM_CONFIG" 45 | sudo bash -c "echo "autologin-user=${USERNAME}" >> $LIGHTDM_CONFIG" 46 | 47 | sudo mkdir -p "$(dirname ${GDM_CUSTOM_CONFIG})" 48 | sudo bash -c "echo "[daemon]" >> $GDM_CUSTOM_CONFIG" 49 | sudo bash -c "echo " # Enabling automatic login" >> $GDM_CUSTOM_CONFIG" 50 | sudo bash -c "echo "AutomaticLoginEnable=True" >> $GDM_CUSTOM_CONFIG" 51 | sudo bash -c "echo "AutomaticLogin=${USERNAME}" >> $GDM_CUSTOM_CONFIG" 52 | 53 | elif [[ $id == "ubuntu" ]]; then 54 | echo "==> Installing ubuntu-desktop" 55 | sudo apt-get install -y --no-install-recommends ubuntu-desktop 56 | # Fixes issue with gnome-terminal starting 57 | sudo update-locale LANG="en_US.UTF-8" LANGUAGE 58 | 59 | if (($(echo $os_version_id '<' 17.04 | bc))); then 60 | GDM_CUSTOM_CONFIG=/etc/gdm/custom.conf 61 | LIGHTDM_CONFIG=/etc/lightdm/lightdm.conf 62 | echo "==> Configuring lightdm autologin" 63 | sudo bash -c "echo "[SeatDefaults]" >> $LIGHTDM_CONFIG" 64 | sudo bash -c "echo "autologin-user=${USERNAME}" >> $LIGHTDM_CONFIG" 65 | # Fix issue with Unity apps not showing up 66 | sudo apt-get install -y unity-lens-applications unity-lens-files 67 | else 68 | GDM_CUSTOM_CONFIG=/etc/gdm3/custom.conf 69 | fi 70 | 71 | sudo mkdir -p "$(dirname ${GDM_CUSTOM_CONFIG})" 72 | sudo bash -c "echo "[daemon]" >> $GDM_CUSTOM_CONFIG" 73 | sudo bash -c "echo " # Enabling automatic login" >> $GDM_CUSTOM_CONFIG" 74 | sudo bash -c "echo "AutomaticLoginEnable=True" >> $GDM_CUSTOM_CONFIG" 75 | sudo bash -c "echo "AutomaticLogin=${USERNAME}" >> $GDM_CUSTOM_CONFIG" 76 | 77 | elif [[ $id == "centos" ]]; then 78 | if [[ $os_version_id -gt 6 && $os_version_id -lt 8 ]]; then 79 | sudo yum -y groupinstall "X Window System" 80 | sudo yum -y install gnome-classic-session gnome-terminal \ 81 | nautilus-open-terminal control-center liberation-mono-fonts 82 | sudo ln -sf /lib/systemd/system/runlevel5.target /etc/systemd/system/default.target 83 | elif [[ $os_version_id -ge 8 ]]; then 84 | sudo yum -y update 85 | sudo yum -y group install "Server with GUI" 86 | sudo systemctl set-default graphical.target 87 | fi 88 | if [[ $os_version_id -gt 6 ]]; then 89 | GDM_CUSTOM_CONFIG=/etc/gdm/custom.conf 90 | sudo mkdir -p "$(dirname ${GDM_CUSTOM_CONFIG})" 91 | sudo bash -c "echo "[daemon]" > $GDM_CUSTOM_CONFIG" 92 | sudo bash -c "echo " # Enabling automatic login" >> $GDM_CUSTOM_CONFIG" 93 | sudo bash -c "echo "AutomaticLoginEnable=True" >> $GDM_CUSTOM_CONFIG" 94 | sudo bash -c "echo "AutomaticLogin=${USERNAME}" >> $GDM_CUSTOM_CONFIG" 95 | fi 96 | 97 | elif [[ $id == "fedora" ]]; then 98 | sudo dnf -y groupinstall "Basic Desktop" 99 | sudo dnf -y install gnome-classic-session gnome-terminal \ 100 | nautilus-open-terminal control-center liberation-mono-fonts 101 | sudo ln -sf /lib/systemd/system/runlevel5.target /etc/systemd/system/default.target 102 | GDM_CUSTOM_CONFIG=/etc/gdm/custom.conf 103 | sudo mkdir -p "$(dirname ${GDM_CUSTOM_CONFIG})" 104 | sudo bash -c "echo "[daemon]" > $GDM_CUSTOM_CONFIG" 105 | sudo bash -c "echo " # Enabling automatic login" >> $GDM_CUSTOM_CONFIG" 106 | sudo bash -c "echo "AutomaticLoginEnable=True" >> $GDM_CUSTOM_CONFIG" 107 | sudo bash -c "echo "AutomaticLogin=${USERNAME}" >> $GDM_CUSTOM_CONFIG" 108 | LIGHTDM_CONFIG=/etc/lightdm/lightdm.conf 109 | echo "==> Configuring lightdm autologin" 110 | sudo bash -c "echo "[SeatDefaults]" > $LIGHTDM_CONFIG" 111 | sudo bash -c "echo "autologin-user=${USERNAME}" >> $LIGHTDM_CONFIG" 112 | fi 113 | 114 | # We need to create artifact to trigger open-vm-tools-desktop install 115 | if [ "$PACKER_BUILDER_TYPE" = "vmware-iso" ]; then 116 | sudo touch /etc/vmware_desktop 117 | 118 | elif [ "$PACKER_BUILDER_TYPE" = "virtualbox-iso" ]; then 119 | sudo touch /etc/virtualbox_desktop 120 | fi 121 | -------------------------------------------------------------------------------- /packer_builder/scripts/freenas.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | curl -X POST \ 7 | -u $SSH_USER:$SSH_PASS \ 8 | http://localhost/api/v1.0/storage/volume/ \ 9 | -H 'Content-Type: application/json' \ 10 | -d '{ 11 | "volume_name": "tank", 12 | "layout": [ 13 | { 14 | "vdevtype": "stripe", 15 | "disks": [ 16 | "da1" 17 | ] 18 | } 19 | ] 20 | }' 21 | 22 | curl -X POST \ 23 | -u $SSH_USER:$SSH_PASS \ 24 | http://localhost/api/v1.0/storage/volume/tank/datasets/ \ 25 | -H 'Content-Type: application/json' \ 26 | -d '{ 27 | "name": "vagrant" 28 | }' 29 | 30 | curl -X POST \ 31 | -u $SSH_USER:$SSH_PASS \ 32 | http://localhost/api/v1.0/account/users/ \ 33 | -H 'Content-Type: application/json' \ 34 | -d '{ 35 | "bsdusr_username": "vagrant", 36 | "bsdusr_creategroup": true, 37 | "bsdusr_full_name": "Vagrant User", 38 | "bsdusr_password": "vagrant", 39 | "bsdusr_uid": 1001, 40 | "bsdusr_home": "/mnt/tank/vagrant", 41 | "bsdusr_shell": "/usr/local/bin/zsh", 42 | "bsdusr_sshpubkey": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key", 43 | "bsdusr_sudo": true 44 | }' 45 | 46 | # if [ "$PACKER_BUILDER_TYPE" == "vmware-iso" ]; then 47 | # pkg install --yes open-vm-tools-nox11 48 | # fi 49 | -------------------------------------------------------------------------------- /packer_builder/scripts/nethserver.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | sudo yum install -y http://mirror.nethserver.org/nethserver/nethserver-release-7.rpm 4 | sudo nethserver-install 5 | -------------------------------------------------------------------------------- /packer_builder/scripts/oracle-cert.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/packer_builder/scripts/oracle-cert.cer -------------------------------------------------------------------------------- /packer_builder/scripts/remove_default_apps.ps1: -------------------------------------------------------------------------------- 1 | function removeApp { 2 | Param ([string]$appName) 3 | Write-Output "Trying to remove $appName" 4 | Get-AppxPackage $appName -AllUsers | Remove-AppxPackage 5 | Get-AppXProvisionedPackage -Online | Where DisplayNam -like $appName | Remove-AppxProvisionedPackage -Online 6 | } 7 | 8 | $applicationList = @( 9 | "Microsoft.BingFinance" 10 | "Microsoft.3DBuilder" 11 | "Microsoft.BingFinance" 12 | "Microsoft.BingNews" 13 | "Microsoft.BingSports" 14 | "Microsoft.BingWeather" 15 | "Microsoft.CommsPhone" 16 | "Microsoft.Getstarted" 17 | "Microsoft.WindowsMaps" 18 | "*MarchofEmpires*" 19 | "Microsoft.GetHelp" 20 | "Microsoft.Messaging" 21 | "*Minecraft*" 22 | "Microsoft.MicrosoftOfficeHub" 23 | "Microsoft.OneConnect" 24 | "Microsoft.WindowsPhone" 25 | "Microsoft.SkypeApp" 26 | "Microsoft.WindowsSoundRecorder" 27 | "*Solitaire*" 28 | "Microsoft.MicrosoftStickyNotes" 29 | "Microsoft.Office.Sway" 30 | "Microsoft.XboxApp" 31 | "Microsoft.XboxIdentityProvider" 32 | "Microsoft.XboxGamingOverlay" 33 | "Microsoft.XboxSpeechToTextOverlay" 34 | "Microsoft.ZuneMusic" 35 | "Microsoft.ZuneVideo" 36 | "Microsoft.NetworkSpeedTest" 37 | "Microsoft.FreshPaint" 38 | "Microsoft.Print3D" 39 | 40 | #Non-Microsoft 41 | "*Autodesk*" 42 | "*BubbleWitch*" 43 | "king.com.CandyCrush*" 44 | "*Dell*" 45 | "*Dropbox*" 46 | "*Facebook*" 47 | "*Keeper*" 48 | "*Netflix*" 49 | "*Twitter*" 50 | "*Plex*" 51 | "*.Duolingo-LearnLanguagesforFree" 52 | "*.EclipseManager" 53 | "ActiproSoftwareLLC.562882FEEB491" # Code Writer 54 | "*.AdobePhotoshopExpress" 55 | "A278AB0D.DisneyMagicKingdoms" 56 | "828B5831.HiddenCityMysteryofShadows" 57 | ); 58 | 59 | foreach ($app in $applicationList) { 60 | removeApp $app 61 | } 62 | 63 | refreshenv -------------------------------------------------------------------------------- /packer_builder/scripts/vagrant.ps1: -------------------------------------------------------------------------------- 1 | # We first need to disable password complexity settings in order to add the vagrant user 2 | $seccfg = [IO.Path]::GetTempFileName() 3 | secedit /export /cfg $seccfg 4 | (Get-Content $seccfg) | Foreach-Object {$_ -replace "PasswordComplexity\s*=\s*1", "PasswordComplexity=0"} | Set-Content $seccfg 5 | secedit /configure /db $env:windir\security\new.sdb /cfg $seccfg /areas SECURITYPOLICY 6 | del $seccfg 7 | Write-Host "Complex Passwords have been disabled." -ForegroundColor Green 8 | 9 | # Create Vagrant user 10 | $userDirectory = [ADSI]"WinNT://localhost" 11 | $user = $userDirectory.Create("User", "vagrant") 12 | $user.SetPassword("vagrant") 13 | $user.SetInfo() 14 | $user.UserFlags = 64 + 65536 # ADS_UF_PASSWD_CANT_CHANGE + ADS_UF_DONT_EXPIRE_PASSWD 15 | $user.SetInfo() 16 | $user.FullName = "vagrant" 17 | $user.SetInfo() 18 | &net "localgroup" "administrators" "/add" "vagrant" 19 | Write-Host "User: 'vagrant' has been created as a local administrator." -ForegroundColor Green 20 | 21 | # We finally enable password complexity settings after adding the Vagrant user 22 | $seccfg = [IO.Path]::GetTempFileName() 23 | secedit /export /cfg $seccfg 24 | (Get-Content $seccfg) | Foreach-Object {$_ -replace "PasswordComplexity\s*=\s*0", "PasswordComplexity=1"} | Set-Content $seccfg 25 | secedit /configure /db $env:windir\security\new.sdb /cfg $seccfg /areas SECURITYPOLICY 26 | del $seccfg 27 | Write-Host "Complex Passwords have been enabled." -ForegroundColor Green -------------------------------------------------------------------------------- /packer_builder/scripts/vagrant.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ -f /etc/os-release ]; then 7 | # shellcheck disable=SC1091 8 | source /etc/os-release 9 | id=$ID 10 | 11 | elif [ -f /etc/redhat-release ]; then 12 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 13 | fi 14 | 15 | # Vagrant specific 16 | sudo bash -c "date > /etc/vagrant_box_build_time" 17 | 18 | # Installing vagrant keys 19 | if [ -f /etc/vyos_build ]; then 20 | WRAPPER=/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper 21 | PUBLIC_KEY=$(curl -fsSL -A curl 'https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub') 22 | KEY_TYPE=$(echo "$PUBLIC_KEY" | awk '{print $1}') 23 | KEY=$(echo "$PUBLIC_KEY" | awk '{print $2}') 24 | $WRAPPER begin 25 | $WRAPPER set system login user vagrant authentication public-keys vagrant type "$KEY_TYPE" 26 | $WRAPPER set system login user vagrant authentication public-keys vagrant key "$KEY" 27 | $WRAPPER commit 28 | $WRAPPER save 29 | $WRAPPER end 30 | else 31 | sudo groupadd vagrant 32 | if [[ $id == "debian" || $id == "ubuntu" ]]; then 33 | sudo useradd vagrant -g vagrant -G sudo -s /bin/bash 34 | elif [[ $id == "centos" || $id == "fedora" ]]; then 35 | sudo useradd vagrant -g vagrant -G wheel -s /bin/bash 36 | elif [[ $id == "alpine" ]]; then 37 | sudo useradd vagrant -g vagrant -G wheel -s /bin/bash 38 | fi 39 | echo -e "vagrant\nvagrant" | sudo passwd vagrant 40 | sudo mkdir -pm 700 /home/vagrant/.ssh 41 | sudo sh -c "curl -L https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys" 42 | sudo chmod 0600 /home/vagrant/.ssh/authorized_keys 43 | sudo chown -R vagrant /home/vagrant/.ssh 44 | fi 45 | # We need to do this here as our autoinst.xml does not do it for us 46 | if [[ $id == "opensuse" || $id == "opensuse-leap" ]]; then 47 | echo "vagrant ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers 48 | fi 49 | -------------------------------------------------------------------------------- /packer_builder/scripts/virtualbox.ps1: -------------------------------------------------------------------------------- 1 | if ($env:PACKER_BUILDER_TYPE -eq "virtualbox-iso") { 2 | Write-Host "Installing Guest Additions" 3 | if (Test-Path d:\VBoxWindowsAdditions.exe) { 4 | Write-Host "Mounting Drive with VBoxWindowsAdditions" 5 | Start-Process -FilePath "d:\VBoxWindowsAdditions.exe" -ArgumentList "/S" -Wait 6 | } 7 | if (Test-Path e:\VBoxWindowsAdditions.exe) { 8 | Write-Host "Mounting Drive with VBoxWindowsAdditions" 9 | Start-Process -FilePath "e:\VBoxWindowsAdditions.exe" -ArgumentList "/S" -Wait 10 | } 11 | } -------------------------------------------------------------------------------- /packer_builder/scripts/virtualbox.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | if [ "$PACKER_BUILDER_TYPE" != "virtualbox-iso" ]; then 6 | exit 0 7 | fi 8 | 9 | if [ -f /etc/os-release ]; then 10 | # shellcheck disable=SC1091 11 | source /etc/os-release 12 | id=$ID 13 | os_version_id=$VERSION_ID 14 | 15 | elif [ -f /etc/redhat-release ]; then 16 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 17 | os_version_id="$(awk '{ print $3 }' /etc/redhat-release | sed 's/"//g' | awk -F. '{ print $1 }')" 18 | fi 19 | 20 | if [[ $id == "ol" ]]; then 21 | os_version_id_short="$(echo $os_version_id | cut -f1 -d".")" 22 | else 23 | os_version_id_short="$(echo $os_version_id | cut -f1-2 -d".")" 24 | fi 25 | 26 | if [[ $id == "alpine" ]]; then 27 | echo http://dl-cdn.alpinelinux.org/alpine/edge/community >>/etc/apk/repositories 28 | apk update 29 | if (($(echo $os_version_id_short '==' 3.7 | bc))); then 30 | apk add -U virtualbox-guest-additions virtualbox-guest-modules-virthardened || true 31 | else 32 | apk add -U virtualbox-guest-additions virtualbox-guest-modules-virt || true 33 | fi 34 | echo vboxsf >>/etc/modules 35 | apk add nfs-utils || true 36 | rc-update add rpc.statd 37 | rc-update add nfsmount 38 | 39 | elif [[ $id == "arch" ]]; then 40 | sudo /usr/bin/pacman -S --noconfirm linux-headers virtualbox-guest-utils virtualbox-guest-modules-arch nfs-utils 41 | sudo bash -c "echo -e 'vboxguest\nvboxsf\nvboxvideo' > /etc/modules-load.d/virtualbox.conf" 42 | sudo /usr/bin/systemctl enable vboxservice.service 43 | sudo /usr/bin/systemctl enable rpcbind.service 44 | sudo /usr/bin/usermod --append --groups vagrant,vboxsf vagrant 45 | 46 | elif [[ $id == "centos" || $id == "ol" ]]; then 47 | sudo yum -y install gcc kernel-devel-"$(uname -r)" kernel-headers-"$(uname -r)" dkms make bzip2 perl && 48 | sudo yum -y groupinstall "Development Tools" 49 | if [[ $id == "ol" ]]; then 50 | sudo yum -y install elfutils-libelf-devel 51 | if [[ $os_version_id_short -eq 7 ]]; then 52 | sudo yum -y install kernel-devel kernel-headers dkms 53 | fi 54 | fi 55 | 56 | elif [[ $id == "debian" || $id == "linuxmint" || $id == "ubuntu" ]]; then 57 | if [ -f /etc/virtualbox_desktop ]; then 58 | sudo apt-get install -y xserver-xorg-video-vmware 59 | fi 60 | 61 | elif [[ $id == "fedora" ]]; then 62 | sudo dnf -y install gcc kernel-devel-"$(uname -r)" kernel-headers-"$(uname -r)" dkms make bzip2 perl && 63 | sudo dnf -y groupinstall "Development Tools" 64 | if [[ $os_version_id -ge 28 ]]; then 65 | sudo dnf -y remove virtualbox-guest-additions 66 | fi 67 | 68 | elif [[ $id == "opensuse" || $id == "opensuse-leap" ]]; then 69 | sudo zypper --non-interactive install gcc kernel-devel \ 70 | make bzip2 perl 71 | fi 72 | 73 | if [[ $id != "alpine" && $id != "arch" ]]; then 74 | if [[ -f /home/vagrant/VBoxGuestAdditions.iso ]]; then 75 | vbox_guest_additions_path="/home/vagrant/VBoxGuestAdditions.iso" 76 | 77 | elif [[ -f /root/VBoxGuestAdditions.iso ]]; then 78 | vbox_guest_additions_path="/root/VBoxGuestAdditions.iso" 79 | fi 80 | sudo mkdir -p /mnt/virtualbox 81 | sudo mount -o loop "$vbox_guest_additions_path" /mnt/virtualbox 82 | sudo sh /mnt/virtualbox/VBoxLinuxAdditions.run 83 | if [[ $id == "ol" ]]; then 84 | sudo /sbin/rcvboxadd quicksetup all 85 | fi 86 | sudo umount /mnt/virtualbox 87 | sudo rm -rf "$vbox_guest_additions_path" 88 | fi 89 | 90 | if [ -f /home/vagrant/VBoxGuestAdditions.iso ]; then 91 | sudo rm -rf /home/vagrant/VBoxGuestAdditions.iso 92 | elif [ -f /root/VBoxGuestAdditions.iso ]; then 93 | sudo rm -rf /root/VBoxGuestAdditions.iso 94 | fi 95 | -------------------------------------------------------------------------------- /packer_builder/scripts/vmware.ps1: -------------------------------------------------------------------------------- 1 | if ($env:PACKER_BUILDER_TYPE -eq "vmware-iso") { 2 | $vmware_tools_iso = "c:\Windows\Temp\windows.iso" 3 | Write-Output "Mounting VMware Tools ISO - $vmware_tools_iso" 4 | Mount-DiskImage -ImagePath $vmware_tools_iso 5 | $vmware_tools_exe = ( 6 | (Get-DiskImage -ImagePath $vmware_tools_iso | Get-Volume).Driveletter + ':\setup.exe') 7 | $vmware_tools_install_params = '/S /v "/qr REBOOT=R"' 8 | Start-Process $vmware_tools_exe $vmware_tools_install_params -Wait 9 | } -------------------------------------------------------------------------------- /packer_builder/scripts/vmware.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [ "$PACKER_BUILDER_TYPE" != "vmware-iso" ]; then 7 | exit 0 8 | fi 9 | 10 | if [ -f /etc/os-release ]; then 11 | # shellcheck disable=SC1091 12 | source /etc/os-release 13 | id=$ID 14 | os_version_id=$VERSION_ID 15 | 16 | elif [ -f /etc/redhat-release ]; then 17 | id="$(awk '{ print tolower($1) }' /etc/redhat-release | sed 's/"//g')" 18 | os_version_id="$(awk '{ print $3 }' /etc/redhat-release | sed 's/"//g' | awk -F. '{ print $1 }')" 19 | fi 20 | 21 | if [[ $id == "ol" ]]; then 22 | os_version_id_short="$(echo $os_version_id | cut -f1 -d".")" 23 | else 24 | os_version_id_short="$(echo $os_version_id | cut -f1-2 -d".")" 25 | fi 26 | 27 | if [[ $id == "alpine" ]]; then 28 | apk add open-vm-tools || true 29 | rc-update add open-vm-tools default 30 | modprobe fuse 31 | echo "fuse" >>/etc/modules 32 | mkdir -p /mnt/hgfs 33 | echo "vmhgfs-fuse /mnt/hgfs fuse defaults,allow_other 0 0" >>/etc/fstab 34 | 35 | elif [[ $id == "arch" ]]; then 36 | sudo /usr/bin/pacman -S --noconfirm linux-headers open-vm-tools nfs-utils 37 | sudo /usr/bin/systemctl enable vmtoolsd.service 38 | sudo /usr/bin/systemctl enable rpcbind.service 39 | 40 | elif [[ $id == "debian" || $id == "elementary" || $id == "linuxmint" || $id == "ubuntu" ]]; then 41 | if [ -f /etc/vmware_desktop ]; then 42 | sudo apt-get install -y open-vm-tools-desktop 43 | else 44 | sudo apt-get install -y open-vm-tools 45 | fi 46 | if [[ $id == "ubuntu" ]]; then 47 | if (($(echo $os_version_id '>=' 18.04 | bc))); then 48 | # This is the fix for https://kb.vmware.com/s/article/56409 49 | sudo bash -c "sed -i '2iAfter=dbus.service' /lib/systemd/system/open-vm-tools.service" 50 | fi 51 | fi 52 | 53 | elif [[ $id == "centos" || $id == "ol" ]]; then 54 | if [[ $os_version_id_short -ge 6 ]]; then 55 | if [ -f /etc/vmware_desktop ]; then 56 | sudo yum -y install open-vm-tools-desktop 57 | else 58 | sudo yum -y install open-vm-tools 59 | fi 60 | elif [[ $os_version_id_short -eq 5 ]]; then 61 | export PATH=$PATH:/sbin 62 | sudo yum -y install net-tools perl 63 | sudo mkdir -p /mnt/vmware 64 | sudo mount -o loop /home/vagrant/linux.iso /mnt/vmware 65 | cd /tmp 66 | cp /mnt/vmware/VMwareTools-*.gz . 67 | tar zxvf VMwareTools-*.gz 68 | sudo ./vmware-tools-distrib/vmware-install.pl --default 69 | sudo umount /mnt/vmware 70 | sudo rm -rf /home/vagrant/linux.iso 71 | fi 72 | if [[ $os_version_id_short -ge 7 ]]; then 73 | sudo /bin/systemctl restart vmtoolsd.service 74 | elif [[ $os_version_id_short -eq 6 ]]; then 75 | sudo service vmtoolsd restart 76 | fi 77 | 78 | elif [[ $id == "fedora" ]]; then 79 | if [ -f /etc/vmware_desktop ]; then 80 | sudo dnf -y install open-vm-tools-desktop 81 | else 82 | sudo dnf -y install open-vm-tools 83 | fi 84 | sudo /bin/systemctl restart vmtoolsd.service 85 | 86 | elif [[ $id == "opensuse" || $id == "opensuse-leap" ]]; then 87 | sudo zypper --non-interactive install open-vm-tools 88 | fi 89 | -------------------------------------------------------------------------------- /packer_builder/scripts/windows_updates.ps1: -------------------------------------------------------------------------------- 1 | # Notify for download and notify for install 2 | $WindowsUpdatePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\" 3 | $AutoUpdatePath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" 4 | 5 | If (Test-Path -Path $WindowsUpdatePath) { 6 | Remove-Item -Path $WindowsUpdatePath -Recurse 7 | } 8 | New-Item $WindowsUpdatePath -Force 9 | New-Item $AutoUpdatePath -Force 10 | Set-ItemProperty -Path $AutoUpdatePath -Name NoAutoUpdate -Value 0 11 | Set-ItemProperty -Path $AutoUpdatePath -Name AUOptions -Value 2 12 | Set-ItemProperty -Path $AutoUpdatePath -Name ScheduledInstallDay -Value 0 13 | Set-ItemProperty -Path $AutoUpdatePath -Name ScheduledInstallTime -Value 3 -------------------------------------------------------------------------------- /packer_builder/scripts/zerodisk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Zero out the free space to save space in the final image: 4 | sudo dd if=/dev/zero of=/EMPTY bs=1M 5 | sudo rm -f /EMPTY 6 | 7 | # Sync to ensure that the delete completes before this moves on. 8 | sudo sync 9 | sudo sync 10 | sudo sync 11 | -------------------------------------------------------------------------------- /packer_builder/specs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/packer_builder/specs/__init__.py -------------------------------------------------------------------------------- /packer_builder/specs/builders/__init__.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/__init__.py""" 2 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/common.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/common.py""" 2 | 3 | # pylint: disable=line-too-long 4 | 5 | 6 | def common_builder(**kwargs): 7 | """Common builder specs.""" 8 | 9 | # Setup vars from kwargs 10 | build_dir = kwargs['data']['build_dir'] 11 | builder_spec = kwargs['data']['builder_spec'] 12 | distro = kwargs['data']['distro'] 13 | 14 | builder_spec.update({ 15 | 'cpus': '{{ user `cpus` }}', 16 | 'disk_size': '{{ user `disk_size` }}', 17 | 'headless': True, 18 | 'http_directory': 'http', 19 | 'iso_checksum': '{{ user `iso_checksum` }}', 20 | 'iso_url': '{{ user `iso_url` }}', 21 | 'memory': '{{ user `memory` }}', 22 | 'output_directory': f'{build_dir}''/{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}', # noqa: E501 23 | 'vm_name': '{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}' 24 | }) 25 | 26 | if distro != 'windows': 27 | builder_spec.update({ 28 | 'ssh_password': '{{ user `password` }}', 29 | 'ssh_username': '{{ user `username` }}', 30 | 'ssh_timeout': '60m' 31 | }) 32 | 33 | return builder_spec 34 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distro.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/distro.py""" 2 | 3 | import os 4 | import jinja2 5 | from packer_builder.specs.builders.distros.alpine import alpine_spec 6 | from packer_builder.specs.builders.distros.centos import centos_spec 7 | from packer_builder.specs.builders.distros.debian import debian_spec 8 | from packer_builder.specs.builders.distros.fedora import fedora_spec 9 | from packer_builder.specs.builders.distros.freenas import freenas_spec 10 | from packer_builder.specs.builders.distros.ubuntu import ubuntu_spec 11 | 12 | # pylint: disable=too-many-locals 13 | 14 | 15 | def distro_builder(**kwargs): 16 | """Distro specific builder specs.""" 17 | 18 | # Setup vars from kwargs 19 | builder = kwargs['data']['builder'] 20 | builder_spec = kwargs['data']['builder_spec'] 21 | distro = kwargs['data']['distro'] 22 | distro_spec = kwargs['data']['distro_spec'] 23 | http_dir = kwargs['data']['http_dir'] 24 | script_dir = kwargs['data']['script_dir'] 25 | version = kwargs['data']['version'] 26 | 27 | # Define username, password from distro spec 28 | username = distro_spec['username'] 29 | password = distro_spec['password'] 30 | 31 | # Check to ensure http_dir exists in build dir 32 | if not os.path.isdir(http_dir): 33 | os.makedirs(http_dir) 34 | 35 | # Define data to pass as kwargs to distro mapping function 36 | data = {'builder': builder, 'builder_spec': builder_spec, 'distro': distro, 37 | 'version': version} 38 | 39 | # Define distro map to function 40 | distro_map = {'alpine': alpine_spec, 41 | 'centos': centos_spec, 'debian': debian_spec, 42 | 'fedora': fedora_spec, 'freenas': freenas_spec, 43 | 'ubuntu': ubuntu_spec} 44 | 45 | # Get distro mapping function 46 | distro_mapping = distro_map[distro] 47 | # Execute distro mapping function 48 | bootstrap_cfg, builder_spec = distro_mapping(data=data) 49 | 50 | # If bootstrap config is not none generate config from Jinja2 template 51 | if bootstrap_cfg is not None: 52 | # Define Jinja2 template directory 53 | j2_template_dir = os.path.join( 54 | script_dir, 'http', distro) 55 | # Define Jinja2 template 56 | j2_template = jinja2.Environment( 57 | loader=jinja2.FileSystemLoader(j2_template_dir), 58 | trim_blocks=True) 59 | # Render Jinja2 template 60 | bootstrap_template = j2_template.get_template( 61 | bootstrap_cfg + '.j2').render(username=username, 62 | password=password) 63 | # Define bootstrap file 64 | bootstrap_file = os.path.join( 65 | http_dir, 66 | f'{distro}-{version}-{bootstrap_cfg}') 67 | 68 | # Remove existing bootstrap file if it exists 69 | if os.path.isfile(bootstrap_file): 70 | os.remove(bootstrap_file) 71 | 72 | # Write new bootstrap file 73 | with open(bootstrap_file, 'w') as bootstrap_cfg: 74 | bootstrap_cfg.write(bootstrap_template) 75 | bootstrap_cfg.close() 76 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/packer_builder/specs/builders/distros/__init__.py -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/alpine.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/alpine.py""" 2 | 3 | 4 | # pylint: disable=line-too-long 5 | def alpine_spec(**kwargs): 6 | """Alpine specs.""" 7 | 8 | # Setup vars from kwargs 9 | builder = kwargs['data']['builder'] 10 | builder_spec = kwargs['data']['builder_spec'] 11 | distro = kwargs['data']['distro'] 12 | version = kwargs['data']['version'] 13 | 14 | if builder == 'qemu': 15 | disk_dev = 'vda' 16 | else: 17 | disk_dev = 'sda' 18 | 19 | bootstrap_cfg = 'answers' 20 | 21 | builder_spec.update( 22 | { 23 | 'boot_command': [ 24 | 'root', 25 | 'ifconfig eth0 up && udhcpc -i eth0', 26 | 'wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/'f'{distro}-{version}-answers', # noqa: E501 27 | f'sed -i \'s/dev_replace/{disk_dev}/g\' 'f'$PWD/{distro}-{version}-answers', # noqa: E501 28 | f'setup-alpine -f $PWD/{distro}-{version}-answers', # noqa: E501 29 | '{{ user `password` }}', 30 | '{{ user `password` }}', 31 | '', 32 | 'y', 33 | '', 34 | 'rc-service sshd stop', 35 | 'mount /dev/'f'{disk_dev}''2 /mnt/', 36 | 'echo \'PermitRootLogin yes\' >> /mnt/etc/ssh/sshd_config', # noqa: E501 37 | 'echo http://dl-cdn.alpinelinux.org/alpine/edge/community >> /mnt/etc/apk/repositories', # noqa: E501 38 | 'mount -t proc none /mnt/proc', 39 | 'mount -o bind /sys /mnt/sys', 40 | 'mount -o bind /dev /mnt/dev', 41 | 'chroot /mnt /bin/sh -l', 42 | 'apk update', 43 | 'apk add bash curl rsyslog ruby shadow sudo', 44 | '', 45 | 'exit', 46 | 'umount /mnt/proc', 47 | 'umount /mnt/sys', 48 | 'umount /mnt/dev', 49 | 'umount /mnt', 50 | 'reboot' 51 | ], 52 | 'boot_wait': '30s', 53 | 'shutdown_command': '/sbin/poweroff', 54 | } 55 | ) 56 | 57 | return bootstrap_cfg, builder_spec 58 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/centos.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/centos.py""" 2 | 3 | 4 | # pylint: disable=line-too-long 5 | def centos_spec(**kwargs): 6 | """CentOS specs.""" 7 | 8 | # Setup vars from kwargs 9 | builder_spec = kwargs['data']['builder_spec'] 10 | distro = kwargs['data']['distro'] 11 | version = kwargs['data']['version'] 12 | 13 | bootstrap_cfg = 'ks.cfg' 14 | builder_spec.update( 15 | { 16 | 'boot_command': [ 17 | ' inst.text ', 18 | 'inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'f'{distro}-{version}-{bootstrap_cfg}', # noqa: E501 19 | '' 20 | ], 21 | 'boot_wait': '30s', 22 | 'shutdown_command': '/sbin/halt -h -p', 23 | } 24 | ) 25 | 26 | return bootstrap_cfg, builder_spec 27 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/debian.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/debian.py""" 2 | 3 | # pylint: disable=line-too-long 4 | 5 | 6 | def debian_spec(**kwargs): 7 | "Debian specs." 8 | 9 | # Setup vars from kwargs 10 | builder_spec = kwargs['data']['builder_spec'] 11 | distro = kwargs['data']['distro'] 12 | version = kwargs['data']['version'] 13 | 14 | bootstrap_cfg = 'preseed.cfg' 15 | builder_spec.update( 16 | { 17 | 'boot_command': [ 18 | '', 19 | 'install', 20 | ' auto=true', 21 | '', 22 | ' priority=critical', 23 | '', 24 | ' url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'f'{distro}-{version}-{bootstrap_cfg}', # noqa: E501 25 | ' ' 26 | ], 27 | 'boot_wait': '30s', 28 | 'shutdown_command': 'sudo /sbin/halt -h -p' 29 | } 30 | ) 31 | 32 | return bootstrap_cfg, builder_spec 33 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/fedora.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/fedora.py""" 2 | 3 | 4 | # pylint: disable=line-too-long 5 | def fedora_spec(**kwargs): 6 | """Fedora specs.""" 7 | 8 | # Setup vars from kwargs 9 | builder_spec = kwargs['data']['builder_spec'] 10 | distro = kwargs['data']['distro'] 11 | version = kwargs['data']['version'] 12 | 13 | bootstrap_cfg = 'ks.cfg' 14 | builder_spec.update( 15 | { 16 | 'boot_command': [ 17 | ' inst.text ', 18 | 'inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'f'{distro}-{version}-{bootstrap_cfg}', # noqa: E501 19 | '' 20 | ], 21 | 'boot_wait': '30s', 22 | 'shutdown_command': '/sbin/halt -h -p', 23 | } 24 | ) 25 | 26 | return bootstrap_cfg, builder_spec 27 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/freenas.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/freenas.py""" 2 | 3 | 4 | # pylint: disable=line-too-long 5 | def freenas_spec(**kwargs): 6 | """FreeNAS specs.""" 7 | 8 | # Setup vars from kwargs 9 | builder_spec = kwargs['data']['builder_spec'] 10 | 11 | bootstrap_cfg = None 12 | builder_spec.update( 13 | { 14 | 'boot_command': [ 15 | '', 16 | '1', 17 | 'y', 18 | 'o', 19 | '', 20 | '{{ user `password` }}{{ user `password` }}', 21 | '', 22 | '', 23 | '', 24 | '3', 25 | '', 26 | '9', 27 | 'curl -X PUT -u {{ user `username` }}:{{ user `password` }} -H \'Content-Type: application/json\' -d \'{\"ssh_rootlogin\": true}\' http://localhost/api/v1.0/services/ssh/', # noqa: E501 28 | 'curl -X PUT -u {{ user `username` }}:{{ user `password` }} -H \'Content-Type: application/json\' -d \'{\"srv_enable\": true}\' http://localhost/api/v1.0/services/services/ssh/' # noqa: E501 29 | ], 30 | 'boot_wait': '30s', 31 | 'shutdown_command': 'shutdown -p now', 32 | } 33 | ) 34 | 35 | return bootstrap_cfg, builder_spec 36 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/distros/ubuntu.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builder/distros/ubuntu.py""" 2 | 3 | 4 | # pylint: disable=line-too-long 5 | def ubuntu_spec(**kwargs): 6 | """Ubuntu specs.""" 7 | 8 | # Setup vars from kwargs 9 | builder = kwargs['data']['builder'] 10 | builder_spec = kwargs['data']['builder_spec'] 11 | distro = kwargs['data']['distro'] 12 | version = kwargs['data']['version'] 13 | 14 | bootstrap_cfg = 'preseed.cfg' 15 | 16 | # https://github.com/mrlesmithjr/packer-builder/issues/83 17 | if builder == 'qemu': 18 | boot_wait = '5s' 19 | else: 20 | boot_wait = '30s' 21 | 22 | builder_spec.update( 23 | { 24 | 'boot_command': [ 25 | '', 26 | '', 27 | '', 28 | '', 29 | '', 30 | '', 31 | '', 32 | '', 33 | '', 34 | '/install/vmlinuz', 35 | '', 36 | ' initrd=/install/initrd.gz', 37 | '', 38 | ' auto=true', 39 | '', 40 | ' priority=critical', 41 | '', 42 | ' url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'f'{distro}-{version}-{bootstrap_cfg}', # noqa: E501 43 | '', 44 | '' 45 | ], 46 | 'boot_wait': f'{boot_wait}', 47 | 'shutdown_command': 'sudo /sbin/halt -h -p' 48 | } 49 | ) 50 | 51 | return bootstrap_cfg, builder_spec 52 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/qemu.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/qemu.py""" 2 | 3 | import subprocess 4 | from shutil import which 5 | from sys import platform 6 | 7 | 8 | def qemu_builder(**kwargs): 9 | """Qemu specific builder specs.""" 10 | 11 | # Setup vars from kwargs 12 | builder_spec = kwargs['data']['builder_spec'] 13 | 14 | # Check which platform QEMU is running on to set accelerator correctly 15 | # https://www.packer.io/docs/builders/qemu.html#accelerator 16 | if platform in ('linux', 'linux2'): 17 | if which('kvm-ok'): 18 | process = subprocess.Popen(["kvm-ok"]) 19 | process.wait() 20 | if process.returncode == 0: 21 | accelerator = 'kvm' 22 | else: 23 | accelerator = 'tcg' 24 | else: 25 | with open('/proc/cpuinfo') as cpuinfo: 26 | if 'vmx' in cpuinfo.read(): 27 | accelerator = 'kvm' 28 | elif 'svm' in cpuinfo.read(): 29 | accelerator = 'kvm' 30 | else: 31 | accelerator = 'tcg' 32 | elif platform == "darwin": 33 | accelerator = 'hvf' 34 | else: 35 | accelerator = 'none' 36 | 37 | builder_spec.update({ 38 | 'accelerator': accelerator, 39 | 'type': 'qemu', 40 | 'disk_interface': 'virtio', 41 | 'format': 'qcow2', 42 | }) 43 | 44 | return builder_spec 45 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/virtualbox.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/virtualbox.py""" 2 | 3 | 4 | def virtualbox_builder(**kwargs): 5 | """Virtualbox specific builder specs.""" 6 | 7 | # Setup vars from kwargs 8 | builder_spec = kwargs['data']['builder_spec'] 9 | distro = kwargs['data']['distro'] 10 | vagrant_box = kwargs['data']['vagrant_box'] 11 | 12 | builder_spec.update({ 13 | 'type': 'virtualbox-iso', 14 | 'hard_drive_interface': '{{ user `disk_adapter_type` }}', 15 | }) 16 | 17 | # Define OS type map for distro to guest OS type 18 | os_type_map = {'alpine': 'Linux26_64', 'centos': 'RedHat_64', 19 | 'debian': 'Debian_64', 'fedora': 'Fedora_64', 20 | 'freenas': 'FreeBSD_64', 'ubuntu': 'Ubuntu_64'} 21 | 22 | # Lookup distro OS type 23 | guest_os_type = os_type_map[distro] 24 | 25 | # If FreeNAS, add storage devices if Vagrant to ensure we can provision 26 | if distro == 'freenas' and vagrant_box: 27 | builder_spec.update( 28 | { 29 | 'vboxmanage': [ 30 | [ 31 | 'createhd', 32 | '--format', 33 | 'VDI', 34 | '--filename', 35 | 'disk2.vdi', 36 | '--size', 37 | '{{ user `disk_size` }}' 38 | ], 39 | [ 40 | 'storageattach', 41 | '{{ .Name }}', 42 | '--storagectl', 43 | 'SCSI Controller', 44 | '--port', 45 | '1', 46 | '--device', 47 | '0', 48 | '--type', 49 | 'hdd', 50 | '--medium', 51 | 'disk2.vdi' 52 | ] 53 | ] 54 | }) 55 | 56 | builder_spec.update({'guest_os_type': guest_os_type}) 57 | 58 | return builder_spec 59 | -------------------------------------------------------------------------------- /packer_builder/specs/builders/vmware.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/builders/vmware.py""" 2 | 3 | 4 | def vmware_builder(**kwargs): 5 | """VMware specific builder specs.""" 6 | 7 | # Setup vars from kwargs 8 | builder_spec = kwargs['data']['builder_spec'] 9 | distro = kwargs['data']['distro'] 10 | vagrant_box = kwargs['data']['vagrant_box'] 11 | 12 | builder_spec.update({ 13 | 'type': 'vmware-iso', 14 | 'disk_adapter_type': '{{ user `disk_adapter_type` }}', 15 | 'disk_type_id': 0, 16 | 'version': '10', 17 | 'vmx_data': { 18 | 'ethernet0.pciSlotNumber': '32' 19 | }, 20 | 'vmx_remove_ethernet_interfaces': True 21 | }) 22 | 23 | # Define OS type map for distro to guest OS type 24 | os_type_map = {'alpine': 'other3xlinux-64', 'centos': 'centos-64', 25 | 'debian': 'debian8-64', 'fedora': 'fedora-64', 26 | 'freenas': 'FreeBSD-64', 'ubuntu': 'ubuntu-64'} 27 | 28 | # Lookup distro OS type 29 | guest_os_type = os_type_map[distro] 30 | 31 | # If FreeNAS, add storage devices if Vagrant to ensure we can provision 32 | if distro == 'freenas' and vagrant_box: 33 | builder_spec.update( 34 | {'disk_additional_size': ['{{ user `disk_size` }}']}) 35 | 36 | builder_spec.update({'guest_os_type': guest_os_type}) 37 | 38 | return builder_spec 39 | -------------------------------------------------------------------------------- /packer_builder/specs/provisioners/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/packer_builder/specs/provisioners/__init__.py -------------------------------------------------------------------------------- /packer_builder/specs/provisioners/freenas.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/provisioners/freenas.py""" 2 | 3 | # pylint: disable=line-too-long 4 | 5 | 6 | def freenas_provisioners(**kwargs): 7 | """FreeNAS specific provisioners.""" 8 | 9 | scripts = [] 10 | 11 | # Setup vars from kwargs 12 | vagrant_box = kwargs['data']['vagrant_box'] 13 | build_scripts_dir = kwargs['data']['build_scripts_dir'] 14 | template = kwargs['data']['template'] 15 | 16 | if vagrant_box: 17 | scripts.append(f'{build_scripts_dir}/freenas.sh') 18 | 19 | provisioner_spec = { 20 | 'type': 'shell', 21 | 'environment_vars': [ 22 | 'SSH_USER={{ user `username` }}', 23 | 'SSH_PASS={{ user `password` }}' 24 | ], 25 | 'scripts': scripts 26 | } 27 | 28 | template['provisioners'].append(provisioner_spec) 29 | 30 | return template 31 | -------------------------------------------------------------------------------- /packer_builder/specs/provisioners/linux.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/provisioners/linux.py""" 2 | 3 | 4 | def linux_provisioners(**kwargs): 5 | """Linux specific provisioners.""" 6 | 7 | # Setup vars from kwargs 8 | vagrant_box = kwargs['data']['vagrant_box'] 9 | build_scripts_dir = kwargs['data']['build_scripts_dir'] 10 | template = kwargs['data']['template'] 11 | 12 | scripts = [ 13 | f'{build_scripts_dir}/base.sh', 14 | f'{build_scripts_dir}/virtualbox.sh', 15 | f'{build_scripts_dir}/vmware.sh', 16 | f'{build_scripts_dir}/cleanup.sh', 17 | f'{build_scripts_dir}/zerodisk.sh' 18 | ] 19 | if vagrant_box: 20 | scripts.insert( 21 | 3, f'{build_scripts_dir}/vagrant.sh') 22 | provisioner_spec = { 23 | 'type': 'shell', 24 | 'scripts': scripts 25 | } 26 | template['provisioners'].append(provisioner_spec) 27 | 28 | return template 29 | -------------------------------------------------------------------------------- /packer_builder/specs/provisioners/windows.py: -------------------------------------------------------------------------------- 1 | """packer_builder/specs/provisioners/windows.py""" 2 | 3 | 4 | def windows_provisioners(**kwargs): 5 | """Windows specific provisioners.""" 6 | 7 | # Setup vars from kwargs 8 | # vagrant_box = kwargs['data']['vagrant_box'] 9 | # build_scripts_dir = kwargs['data']['build_scripts_dir'] 10 | template = kwargs['data']['template'] 11 | 12 | return template 13 | -------------------------------------------------------------------------------- /packer_builder/template.py: -------------------------------------------------------------------------------- 1 | """Generates the Packer build template.""" 2 | import os 3 | import json 4 | import logging 5 | import subprocess 6 | from subprocess import PIPE 7 | import sys 8 | from packer_builder.specs.builders.common import common_builder 9 | from packer_builder.specs.builders.distro import distro_builder 10 | from packer_builder.specs.builders.qemu import qemu_builder 11 | from packer_builder.specs.builders.virtualbox import virtualbox_builder 12 | from packer_builder.specs.builders.vmware import vmware_builder 13 | from packer_builder.specs.provisioners.freenas import freenas_provisioners 14 | from packer_builder.specs.provisioners.linux import linux_provisioners 15 | from packer_builder.specs.provisioners.windows import windows_provisioners 16 | 17 | # pylint: disable=too-many-arguments 18 | # pylint: disable=too-many-instance-attributes 19 | 20 | 21 | class Template(): 22 | """Main Packer template execution.""" 23 | 24 | def __init__(self, **kwargs): 25 | 26 | # Setup logger 27 | self.logger = logging.getLogger(__name__) 28 | # Obtain script dir from absolute path of this module 29 | self.script_dir = os.path.dirname(os.path.abspath(__file__)) 30 | 31 | # Setup vars for class usage 32 | self.build_dir = kwargs['data']['output_dir'] 33 | self.build_scripts_dir = os.path.join(self.script_dir, 'scripts') 34 | self.distro = kwargs['data']['distro'].lower() 35 | self.distro_spec = kwargs['data']['distro_spec'] 36 | self.http_dir = os.path.join(self.build_dir, 'http') 37 | self.password_override = kwargs['data']['password_override'] 38 | self.version = kwargs['data']['version'] 39 | self.version_spec = kwargs['data']['version_spec'] 40 | 41 | # Define template dictionary 42 | self.template = dict() 43 | 44 | # Check if Vagrant box is to be built or not 45 | self.vagrant_box = self.distro_spec.get('vagrant_box') 46 | if self.vagrant_box is None: 47 | self.vagrant_box = False 48 | 49 | def get_vars(self): 50 | """Define user specific variables.""" 51 | self.template['variables'] = { 52 | 'compression_level': '6', 53 | 'cpus': str(self.distro_spec['cpus']), 54 | 'memory': str(self.distro_spec['memory']), 55 | 'disk_adapter_type': self.distro_spec['disk_adapter_type'], 56 | 'disk_size': str(self.distro_spec['disk_size']), 57 | 'iso_checksum': self.version_spec['iso_checksum'], 58 | 'iso_url': self.version_spec['iso_url'], 59 | 'username': self.distro_spec['username'], 60 | 'password': self.distro_spec['password'], 61 | 'vm_name': f'{self.distro}-{self.version}', # noqa: E999 62 | } 63 | if self.password_override is not None: 64 | self.template['variables']['password'] = self.password_override 65 | 66 | def get_builders(self): 67 | """Direct builder configurations based on builder type.""" 68 | self.template['builders'] = [] 69 | for builder_ in self.distro_spec['builders']: 70 | # Define build spec dictionary 71 | builder_spec = dict() 72 | # Get builder as lowercase 73 | builder = builder_.lower() 74 | 75 | # Define data to pass as kwargs 76 | data = {'build_dir': self.build_dir, 'http_dir': self.http_dir, 77 | 'distro_spec': self.distro_spec, 'distro': self.distro, 78 | 'script_dir': self.script_dir, 'builder': builder, 79 | 'builder_spec': builder_spec, 'version': self.version, 80 | 'vagrant_box': self.vagrant_box} 81 | 82 | # Define common builder specs 83 | builder_spec = common_builder(data=data) 84 | 85 | # Define distro builder specs 86 | distro_builder(data=data) 87 | 88 | # Define builder map to define function 89 | builder_map = {'qemu': qemu_builder, 90 | 'virtualbox-iso': virtualbox_builder, 91 | 'vmware-iso': vmware_builder} 92 | 93 | builder_mapping = builder_map[builder] 94 | builder_spec = builder_mapping(data=data) 95 | 96 | self.template['builders'].append(builder_spec) 97 | 98 | def get_provisioners(self): 99 | """Direct provisioners based on distro type.""" 100 | 101 | self.template['provisioners'] = [] 102 | 103 | # Define data to pass as kwargs 104 | data = {'build_scripts_dir': self.build_scripts_dir, 105 | 'template': self.template, 106 | 'vagrant_box': self.vagrant_box} 107 | 108 | if self.distro == 'freenas': 109 | self.template = freenas_provisioners(data=data) 110 | elif self.distro == 'windows': 111 | self.template = windows_provisioners(data=data) 112 | else: 113 | self.template = linux_provisioners(data=data) 114 | 115 | def get_post_processors(self): 116 | """Post processors for builds.""" 117 | 118 | # pylint: disable=line-too-long 119 | vmx_file = f'{self.build_dir}''/{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}/{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}.vmx' # noqa: E501 120 | ovf_file = f'{self.build_dir}''/{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}/{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}.ovf' # noqa: E501 121 | 122 | # Get list of builder types to properly add post processors 123 | builder_types = list() 124 | for build_type in self.template['builders']: 125 | builder_types.append(build_type['type']) 126 | 127 | # Build post processors based on builder_types 128 | post_processors = list() 129 | if 'vmware-iso' in builder_types: 130 | post_processors.append({ 131 | 'type': 'shell-local', 132 | 'inline': f'ovftool {vmx_file} {ovf_file}', 133 | 'only': ['vmware-iso'] 134 | }) 135 | if self.vagrant_box: 136 | vagrant_post_proc = { 137 | 'compression_level': '{{ user `compression_level` }}', 138 | 'keep_input_artifact': True, 139 | 'output': '{{ user `vm_name` }}-{{ build_type }}-{{ timestamp }}.box', # noqa: E501 140 | 'type': 'vagrant' 141 | } 142 | if self.distro == 'freenas': 143 | vagrant_post_proc.update( 144 | {'only': ['virtualbox-iso', 'vmware-iso']}) 145 | # self.template['post-processors'].insert(1, vagrant_post_proc) 146 | post_processors.append(vagrant_post_proc) 147 | post_processors.append({ 148 | 'type': 'manifest', 149 | 'strip_path': True 150 | }) 151 | self.template['post-processors'] = post_processors 152 | 153 | def save(self): 154 | """Save generated template for building.""" 155 | 156 | self.get_vars() 157 | self.get_builders() 158 | self.get_provisioners() 159 | self.get_post_processors() 160 | 161 | template_json = json.dumps(self.template, indent=4) 162 | template_file = os.path.join(self.build_dir, 'template.json') 163 | 164 | # If template file exists, remove it 165 | if os.path.isfile(template_file): 166 | os.remove(template_file) 167 | 168 | # Write new template file 169 | with open(template_file, 'w') as packer_template: 170 | packer_template.write(template_json) 171 | packer_template.close() 172 | 173 | def validate(self): 174 | """Validate generated Packer template.""" 175 | 176 | current_dir = os.getcwd() 177 | os.chdir(self.build_dir) 178 | 179 | validate = subprocess.run( 180 | ['packer', 'validate', 'template.json'], check=False, 181 | stderr=PIPE, stdout=PIPE) 182 | 183 | # Display output back to stdout for visibility 184 | print(validate.stdout.decode("utf-8")) 185 | 186 | # Log and exit if failed 187 | if validate.returncode != 0: 188 | self.logger.error(validate) 189 | sys.exit(1) 190 | 191 | os.chdir(current_dir) 192 | -------------------------------------------------------------------------------- /packer_builder/templates.py: -------------------------------------------------------------------------------- 1 | """Generate Packer templates for offline execution/review.""" 2 | import os 3 | import logging 4 | import shutil 5 | from packer_builder.template import Template 6 | 7 | 8 | # pylint: disable=too-few-public-methods 9 | class Templates(): 10 | """Generate Packer templates without building.""" 11 | 12 | def __init__(self, args, distros): 13 | """Init a thing.""" 14 | 15 | # Setup logger 16 | self.logger = logging.getLogger(__name__) 17 | # self.args = args 18 | self.distros = distros 19 | self.build_dir = args.outputdir 20 | self.password_override = args.password 21 | # self.current_dir = os.getcwd() 22 | 23 | def generate(self): 24 | """Generate templates and rename them into the defined output dir.""" 25 | 26 | # Iterate through defined distros 27 | for distro, distro_spec in self.distros.items(): 28 | # Iterate through versions defined in distros 29 | for version, version_spec in distro_spec['versions'].items(): 30 | version = str(version) 31 | 32 | # Define data to pass to class 33 | data = {'output_dir': self.build_dir, 34 | 'password_override': self.password_override, 35 | 'distro': distro, 'distro_spec': distro_spec, 36 | 'version': version, 'version_spec': version_spec} 37 | 38 | # Generate the template 39 | template = Template(data=data) 40 | # Save template for processing 41 | template.save() 42 | # Validate the generated template 43 | self.logger.info( 44 | 'Validating distro: %s, distro_spec: %s', distro, 45 | distro_spec) 46 | template.validate() 47 | 48 | # Rename the generated template as distro and version 49 | generated_template = os.path.join( 50 | self.build_dir, 'template.json') 51 | self.logger.info('generated_template: %s', generated_template) 52 | 53 | renamed_template = os.path.join( 54 | self.build_dir, f'{distro}-{version}.json') # noqa: E999 55 | self.logger.info('renamed_template: %s', renamed_template) 56 | shutil.move(generated_template, renamed_template) 57 | -------------------------------------------------------------------------------- /pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # A comma-separated list of package or module names from where C extensions may 4 | # be loaded. Extensions are loading into the active Python interpreter and may 5 | # run arbitrary code 6 | extension-pkg-whitelist= 7 | 8 | # Add files or directories to the blacklist. They should be base names, not 9 | # paths. 10 | ignore=CVS 11 | 12 | # Add files or directories matching the regex patterns to the blacklist. The 13 | # regex matches against base names, not paths. 14 | ignore-patterns= 15 | 16 | # Python code to execute, usually for sys.path manipulation such as 17 | # pygtk.require(). 18 | #init-hook= 19 | 20 | # Use multiple processes to speed up Pylint. 21 | jobs=1 22 | 23 | # List of plugins (as comma separated values of python modules names) to load, 24 | # usually to register additional checkers. 25 | load-plugins= 26 | 27 | # Pickle collected data for later comparisons. 28 | persistent=yes 29 | 30 | # Specify a configuration file. 31 | #rcfile= 32 | 33 | # When enabled, pylint would attempt to guess common misconfiguration and emit 34 | # user-friendly hints instead of false-positive error messages 35 | suggestion-mode=yes 36 | 37 | # Allow loading of arbitrary C extensions. Extensions are imported into the 38 | # active Python interpreter and may run arbitrary code. 39 | unsafe-load-any-extension=no 40 | 41 | 42 | [MESSAGES CONTROL] 43 | 44 | # Only show warnings with the listed confidence levels. Leave empty to show 45 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED 46 | confidence= 47 | 48 | # Disable the message, report, category or checker with the given id(s). You 49 | # can either give multiple identifiers separated by comma (,) or put this 50 | # option multiple times (only on the command line, not in the configuration 51 | # file where it should appear only once).You can also use "--disable=all" to 52 | # disable everything first and then reenable specific checks. For example, if 53 | # you want to run only the similarities checker, you can use "--disable=all 54 | # --enable=similarities". If you want to run only the classes checker, but have 55 | # no Warning level messages displayed, use"--disable=all --enable=classes 56 | # --disable=W" 57 | disable=print-statement, 58 | parameter-unpacking, 59 | unpacking-in-except, 60 | old-raise-syntax, 61 | backtick, 62 | long-suffix, 63 | old-ne-operator, 64 | old-octal-literal, 65 | import-star-module-level, 66 | non-ascii-bytes-literal, 67 | invalid-unicode-literal, 68 | raw-checker-failed, 69 | bad-inline-option, 70 | locally-disabled, 71 | locally-enabled, 72 | file-ignored, 73 | suppressed-message, 74 | useless-suppression, 75 | deprecated-pragma, 76 | apply-builtin, 77 | basestring-builtin, 78 | buffer-builtin, 79 | cmp-builtin, 80 | coerce-builtin, 81 | execfile-builtin, 82 | file-builtin, 83 | long-builtin, 84 | raw_input-builtin, 85 | reduce-builtin, 86 | standarderror-builtin, 87 | unicode-builtin, 88 | xrange-builtin, 89 | coerce-method, 90 | delslice-method, 91 | getslice-method, 92 | setslice-method, 93 | no-absolute-import, 94 | old-division, 95 | dict-iter-method, 96 | dict-view-method, 97 | next-method-called, 98 | metaclass-assignment, 99 | indexing-exception, 100 | raising-string, 101 | reload-builtin, 102 | oct-method, 103 | hex-method, 104 | nonzero-method, 105 | cmp-method, 106 | input-builtin, 107 | round-builtin, 108 | intern-builtin, 109 | unichr-builtin, 110 | map-builtin-not-iterating, 111 | zip-builtin-not-iterating, 112 | range-builtin-not-iterating, 113 | filter-builtin-not-iterating, 114 | using-cmp-argument, 115 | eq-without-hash, 116 | div-method, 117 | idiv-method, 118 | rdiv-method, 119 | exception-message-attribute, 120 | invalid-str-codec, 121 | sys-max-int, 122 | bad-python3-import, 123 | deprecated-string-function, 124 | deprecated-str-translate-call, 125 | deprecated-itertools-function, 126 | deprecated-types-field, 127 | next-method-defined, 128 | dict-items-not-iterating, 129 | dict-keys-not-iterating, 130 | dict-values-not-iterating, 131 | deprecated-operator-function, 132 | deprecated-urllib-function, 133 | xreadlines-attribute, 134 | deprecated-sys-function, 135 | exception-escape, 136 | comprehension-escape, 137 | R0801 138 | 139 | # Enable the message, report, category or checker with the given id(s). You can 140 | # either give multiple identifier separated by comma (,) or put this option 141 | # multiple time (only on the command line, not in the configuration file where 142 | # it should appear only once). See also the "--disable" option for examples. 143 | enable=c-extension-no-member 144 | 145 | 146 | [REPORTS] 147 | 148 | # Python expression which should return a note less than 10 (10 is the highest 149 | # note). You have access to the variables errors warning, statement which 150 | # respectively contain the number of errors / warnings messages and the total 151 | # number of statements analyzed. This is used by the global evaluation report 152 | # (RP0004). 153 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 154 | 155 | # Template used to display messages. This is a python new-style format string 156 | # used to format the message information. See doc for all details 157 | #msg-template= 158 | 159 | # Set the output format. Available formats are text, parseable, colorized, json 160 | # and msvs (visual studio).You can also give a reporter class, eg 161 | # mypackage.mymodule.MyReporterClass. 162 | output-format=text 163 | 164 | # Tells whether to display a full report or only the messages 165 | reports=no 166 | 167 | # Activate the evaluation score. 168 | score=yes 169 | 170 | 171 | [REFACTORING] 172 | 173 | # Maximum number of nested blocks for function / method body 174 | max-nested-blocks=5 175 | 176 | # Complete name of functions that never returns. When checking for 177 | # inconsistent-return-statements if a never returning function is called then 178 | # it will be considered as an explicit return statement and no message will be 179 | # printed. 180 | never-returning-functions=optparse.Values,sys.exit 181 | 182 | 183 | [LOGGING] 184 | 185 | # Logging modules to check that the string format arguments are in logging 186 | # function parameter format 187 | logging-modules=logging 188 | 189 | 190 | [SPELLING] 191 | 192 | # Limits count of emitted suggestions for spelling mistakes 193 | max-spelling-suggestions=4 194 | 195 | # Spelling dictionary name. Available dictionaries: none. To make it working 196 | # install python-enchant package. 197 | spelling-dict= 198 | 199 | # List of comma separated words that should not be checked. 200 | spelling-ignore-words= 201 | 202 | # A path to a file that contains private dictionary; one word per line. 203 | spelling-private-dict-file= 204 | 205 | # Tells whether to store unknown words to indicated private dictionary in 206 | # --spelling-private-dict-file option instead of raising a message. 207 | spelling-store-unknown-words=no 208 | 209 | 210 | [MISCELLANEOUS] 211 | 212 | # List of note tags to take in consideration, separated by a comma. 213 | notes=FIXME, 214 | XXX, 215 | TODO 216 | 217 | 218 | [SIMILARITIES] 219 | 220 | # Ignore comments when computing similarities. 221 | ignore-comments=yes 222 | 223 | # Ignore docstrings when computing similarities. 224 | ignore-docstrings=yes 225 | 226 | # Ignore imports when computing similarities. 227 | ignore-imports=no 228 | 229 | # Minimum lines number of a similarity. 230 | min-similarity-lines=4 231 | 232 | 233 | [TYPECHECK] 234 | 235 | # List of decorators that produce context managers, such as 236 | # contextlib.contextmanager. Add to this list to register other decorators that 237 | # produce valid context managers. 238 | contextmanager-decorators=contextlib.contextmanager 239 | 240 | # List of members which are set dynamically and missed by pylint inference 241 | # system, and so shouldn't trigger E1101 when accessed. Python regular 242 | # expressions are accepted. 243 | generated-members= 244 | 245 | # Tells whether missing members accessed in mixin class should be ignored. A 246 | # mixin class is detected if its name ends with "mixin" (case insensitive). 247 | ignore-mixin-members=yes 248 | 249 | # This flag controls whether pylint should warn about no-member and similar 250 | # checks whenever an opaque object is returned when inferring. The inference 251 | # can return multiple potential results while evaluating a Python object, but 252 | # some branches might not be evaluated, which results in partial inference. In 253 | # that case, it might be useful to still emit no-member and other checks for 254 | # the rest of the inferred objects. 255 | ignore-on-opaque-inference=yes 256 | 257 | # List of class names for which member attributes should not be checked (useful 258 | # for classes with dynamically set attributes). This supports the use of 259 | # qualified names. 260 | ignored-classes=optparse.Values,thread._local,_thread._local 261 | 262 | # List of module names for which member attributes should not be checked 263 | # (useful for modules/projects where namespaces are manipulated during runtime 264 | # and thus existing member attributes cannot be deduced by static analysis. It 265 | # supports qualified module names, as well as Unix pattern matching. 266 | ignored-modules= 267 | 268 | # Show a hint with possible names when a member name was not found. The aspect 269 | # of finding the hint is based on edit distance. 270 | missing-member-hint=yes 271 | 272 | # The minimum edit distance a name should have in order to be considered a 273 | # similar match for a missing member name. 274 | missing-member-hint-distance=1 275 | 276 | # The total number of similar names that should be taken in consideration when 277 | # showing a hint for a missing member. 278 | missing-member-max-choices=1 279 | 280 | 281 | [VARIABLES] 282 | 283 | # List of additional names supposed to be defined in builtins. Remember that 284 | # you should avoid to define new builtins when possible. 285 | additional-builtins= 286 | 287 | # Tells whether unused global variables should be treated as a violation. 288 | allow-global-unused-variables=yes 289 | 290 | # List of strings which can identify a callback function by name. A callback 291 | # name must start or end with one of those strings. 292 | callbacks=cb_, 293 | _cb 294 | 295 | # A regular expression matching the name of dummy variables (i.e. expectedly 296 | # not used). 297 | dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ 298 | 299 | # Argument names that match this expression will be ignored. Default to name 300 | # with leading underscore 301 | ignored-argument-names=_.*|^ignored_|^unused_ 302 | 303 | # Tells whether we should check for unused import in __init__ files. 304 | init-import=no 305 | 306 | # List of qualified module names which can have objects that can redefine 307 | # builtins. 308 | redefining-builtins-modules=six.moves,past.builtins,future.builtins,io,builtins 309 | 310 | 311 | [FORMAT] 312 | 313 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 314 | expected-line-ending-format= 315 | 316 | # Regexp for a line that is allowed to be longer than the limit. 317 | ignore-long-lines=^\s*(# )??$ 318 | 319 | # Number of spaces of indent required inside a hanging or continued line. 320 | indent-after-paren=4 321 | 322 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 323 | # tab). 324 | indent-string=' ' 325 | 326 | # Maximum number of characters on a single line. 327 | max-line-length=100 328 | 329 | # Maximum number of lines in a module 330 | max-module-lines=1000 331 | 332 | # List of optional constructs for which whitespace checking is disabled. `dict- 333 | # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. 334 | # `trailing-comma` allows a space between comma and closing bracket: (a, ). 335 | # `empty-line` allows space-only lines. 336 | no-space-check=trailing-comma, 337 | dict-separator 338 | 339 | # Allow the body of a class to be on the same line as the declaration if body 340 | # contains single statement. 341 | single-line-class-stmt=no 342 | 343 | # Allow the body of an if to be on the same line as the test if there is no 344 | # else. 345 | single-line-if-stmt=no 346 | 347 | 348 | [BASIC] 349 | 350 | # Naming style matching correct argument names 351 | argument-naming-style=snake_case 352 | 353 | # Regular expression matching correct argument names. Overrides argument- 354 | # naming-style 355 | #argument-rgx= 356 | 357 | # Naming style matching correct attribute names 358 | attr-naming-style=snake_case 359 | 360 | # Regular expression matching correct attribute names. Overrides attr-naming- 361 | # style 362 | #attr-rgx= 363 | 364 | # Bad variable names which should always be refused, separated by a comma 365 | bad-names=foo, 366 | bar, 367 | baz, 368 | toto, 369 | tutu, 370 | tata 371 | 372 | # Naming style matching correct class attribute names 373 | class-attribute-naming-style=any 374 | 375 | # Regular expression matching correct class attribute names. Overrides class- 376 | # attribute-naming-style 377 | #class-attribute-rgx= 378 | 379 | # Naming style matching correct class names 380 | class-naming-style=PascalCase 381 | 382 | # Regular expression matching correct class names. Overrides class-naming-style 383 | #class-rgx= 384 | 385 | # Naming style matching correct constant names 386 | const-naming-style=UPPER_CASE 387 | 388 | # Regular expression matching correct constant names. Overrides const-naming- 389 | # style 390 | #const-rgx= 391 | 392 | # Minimum line length for functions/classes that require docstrings, shorter 393 | # ones are exempt. 394 | docstring-min-length=-1 395 | 396 | # Naming style matching correct function names 397 | function-naming-style=snake_case 398 | 399 | # Regular expression matching correct function names. Overrides function- 400 | # naming-style 401 | #function-rgx= 402 | 403 | # Good variable names which should always be accepted, separated by a comma 404 | good-names=i, 405 | j, 406 | k, 407 | ex, 408 | Run, 409 | _ 410 | 411 | # Include a hint for the correct naming format with invalid-name 412 | include-naming-hint=no 413 | 414 | # Naming style matching correct inline iteration names 415 | inlinevar-naming-style=any 416 | 417 | # Regular expression matching correct inline iteration names. Overrides 418 | # inlinevar-naming-style 419 | #inlinevar-rgx= 420 | 421 | # Naming style matching correct method names 422 | method-naming-style=snake_case 423 | 424 | # Regular expression matching correct method names. Overrides method-naming- 425 | # style 426 | #method-rgx= 427 | 428 | # Naming style matching correct module names 429 | module-naming-style=snake_case 430 | 431 | # Regular expression matching correct module names. Overrides module-naming- 432 | # style 433 | #module-rgx= 434 | 435 | # Colon-delimited sets of names that determine each other's naming style when 436 | # the name regexes allow several styles. 437 | name-group= 438 | 439 | # Regular expression which should only match function or class names that do 440 | # not require a docstring. 441 | no-docstring-rgx=^_ 442 | 443 | # List of decorators that produce properties, such as abc.abstractproperty. Add 444 | # to this list to register other decorators that produce valid properties. 445 | property-classes=abc.abstractproperty 446 | 447 | # Naming style matching correct variable names 448 | variable-naming-style=snake_case 449 | 450 | # Regular expression matching correct variable names. Overrides variable- 451 | # naming-style 452 | #variable-rgx= 453 | 454 | 455 | [DESIGN] 456 | 457 | # Maximum number of arguments for function / method 458 | max-args=5 459 | 460 | # Maximum number of attributes for a class (see R0902). 461 | max-attributes=7 462 | 463 | # Maximum number of boolean expressions in a if statement 464 | max-bool-expr=5 465 | 466 | # Maximum number of branch for function / method body 467 | max-branches=12 468 | 469 | # Maximum number of locals for function / method body 470 | max-locals=15 471 | 472 | # Maximum number of parents for a class (see R0901). 473 | max-parents=7 474 | 475 | # Maximum number of public methods for a class (see R0904). 476 | max-public-methods=20 477 | 478 | # Maximum number of return / yield for function / method body 479 | max-returns=6 480 | 481 | # Maximum number of statements in function / method body 482 | max-statements=50 483 | 484 | # Minimum number of public methods for a class (see R0903). 485 | min-public-methods=2 486 | 487 | 488 | [CLASSES] 489 | 490 | # List of method names used to declare (i.e. assign) instance attributes. 491 | defining-attr-methods=__init__, 492 | __new__, 493 | setUp 494 | 495 | # List of member names, which should be excluded from the protected access 496 | # warning. 497 | exclude-protected=_asdict, 498 | _fields, 499 | _replace, 500 | _source, 501 | _make 502 | 503 | # List of valid names for the first argument in a class method. 504 | valid-classmethod-first-arg=cls 505 | 506 | # List of valid names for the first argument in a metaclass class method. 507 | valid-metaclass-classmethod-first-arg=mcs 508 | 509 | 510 | [IMPORTS] 511 | 512 | # Allow wildcard imports from modules that define __all__. 513 | allow-wildcard-with-all=no 514 | 515 | # Analyse import fallback blocks. This can be used to support both Python 2 and 516 | # 3 compatible code, which means that the block might have code that exists 517 | # only in one or another interpreter, leading to false positives when analysed. 518 | analyse-fallback-blocks=no 519 | 520 | # Deprecated modules which should not be used, separated by a comma 521 | deprecated-modules=regsub, 522 | TERMIOS, 523 | Bastion, 524 | rexec 525 | 526 | # Create a graph of external dependencies in the given file (report RP0402 must 527 | # not be disabled) 528 | ext-import-graph= 529 | 530 | # Create a graph of every (i.e. internal and external) dependencies in the 531 | # given file (report RP0402 must not be disabled) 532 | import-graph= 533 | 534 | # Create a graph of internal dependencies in the given file (report RP0402 must 535 | # not be disabled) 536 | int-import-graph= 537 | 538 | # Force import order to recognize a module as part of the standard 539 | # compatibility libraries. 540 | known-standard-library= 541 | 542 | # Force import order to recognize a module as part of a third party library. 543 | known-third-party=enchant 544 | 545 | 546 | [EXCEPTIONS] 547 | 548 | # Exceptions that will emit a warning when being caught. Defaults to 549 | # "Exception" 550 | overgeneral-exceptions=Exception 551 | -------------------------------------------------------------------------------- /requirements-dev.in: -------------------------------------------------------------------------------- 1 | # Python requirements for development 2 | -c requirements.txt 3 | autopep8 4 | flake8 5 | mkdocs 6 | pycodestyle 7 | pylint 8 | tox 9 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile requirements-dev.in 6 | # 7 | appdirs==1.4.4 # via virtualenv 8 | astroid==2.4.1 # via pylint 9 | autopep8==1.5.2 # via -r requirements-dev.in 10 | click==7.1.2 # via -c requirements.txt, mkdocs, nltk 11 | distlib==0.3.0 # via virtualenv 12 | filelock==3.0.12 # via tox, virtualenv 13 | flake8==3.8.1 # via -r requirements-dev.in 14 | future==0.18.2 # via lunr 15 | importlib-metadata==1.6.0 # via flake8, markdown, pluggy, tox, virtualenv 16 | isort==4.3.21 # via pylint 17 | jinja2==2.11.2 # via -c requirements.txt, mkdocs 18 | joblib==0.14.1 # via nltk 19 | lazy-object-proxy==1.4.3 # via astroid 20 | livereload==2.6.1 # via mkdocs 21 | lunr[languages]==0.5.8 # via mkdocs 22 | markdown==3.2.2 # via mkdocs 23 | markupsafe==1.1.1 # via -c requirements.txt, jinja2 24 | mccabe==0.6.1 # via flake8, pylint 25 | mkdocs==1.1.2 # via -r requirements-dev.in 26 | nltk==3.5 # via lunr 27 | packaging==20.3 # via tox 28 | pluggy==0.13.1 # via tox 29 | py==1.8.1 # via tox 30 | pycodestyle==2.6.0 # via -r requirements-dev.in, autopep8, flake8 31 | pyflakes==2.2.0 # via flake8 32 | pylint==2.5.2 # via -r requirements-dev.in 33 | pyparsing==2.4.7 # via packaging 34 | pyyaml==5.3.1 # via -c requirements.txt, mkdocs 35 | regex==2020.5.14 # via nltk 36 | six==1.14.0 # via -c requirements.txt, astroid, livereload, lunr, packaging, tox, virtualenv 37 | toml==0.10.1 # via pylint, tox 38 | tornado==6.0.4 # via livereload, mkdocs 39 | tox==3.15.0 # via -r requirements-dev.in 40 | tqdm==4.46.0 # via nltk 41 | typed-ast==1.4.1 # via astroid 42 | virtualenv==20.0.20 # via tox 43 | wrapt==1.12.1 # via astroid 44 | zipp==3.1.0 # via importlib-metadata 45 | -------------------------------------------------------------------------------- /requirements.in: -------------------------------------------------------------------------------- 1 | # Python requirements for executing 2 | Jinja2 3 | pip-tools 4 | PyYAML 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile 6 | # 7 | click==7.1.2 # via pip-tools 8 | jinja2==2.11.2 # via -r requirements.in 9 | markupsafe==1.1.1 # via jinja2 10 | pip-tools==5.1.2 # via -r requirements.in 11 | pyyaml==5.3.1 # via -r requirements.in 12 | six==1.14.0 # via pip-tools 13 | 14 | # The following packages are considered to be unsafe in a requirements file: 15 | # pip 16 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """The setup script.""" 4 | 5 | from setuptools import setup, find_packages 6 | 7 | with open('README.md') as readme_file: 8 | readme = readme_file.read() 9 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlesmithjr/packer-builder/ff07b48740062c1a3050e670187bcd620a901b1c/tests/.gitkeep --------------------------------------------------------------------------------