kopia lustrzana https://github.com/jedie/PyInventory
commit
7e609e4762
3
.flake8
3
.flake8
|
@ -1,3 +1,6 @@
|
||||||
|
#
|
||||||
|
# Move to pyproject.toml after: https://gitlab.com/pycqa/flake8/-/issues/428
|
||||||
|
#
|
||||||
[flake8]
|
[flake8]
|
||||||
exclude = .tox, .pytest_cache, *.egg-info, */migrations/*, volumes
|
exclude = .tox, .pytest_cache, *.egg-info, */migrations/*, volumes
|
||||||
#ignore = E402
|
#ignore = E402
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
.*
|
.*
|
||||||
!.github
|
|
||||||
!.editorconfig
|
|
||||||
!.flake8
|
!.flake8
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.isort.cfg
|
!.isort.cfg
|
||||||
|
|
23
.isort.cfg
23
.isort.cfg
|
@ -1,23 +0,0 @@
|
||||||
# Configuring isort
|
|
||||||
# https://github.com/timothycrosley/isort/wiki/isort-Settings
|
|
||||||
|
|
||||||
[settings]
|
|
||||||
atomic=true
|
|
||||||
line_length=120
|
|
||||||
case_sensitive=false
|
|
||||||
|
|
||||||
skip_glob=*/migrations/*,*/volumes/*
|
|
||||||
|
|
||||||
# https://github.com/timothycrosley/isort#multi-line-output-modes
|
|
||||||
# 3 - Vertical Hanging Indent
|
|
||||||
multi_line_output=3
|
|
||||||
include_trailing_comma=true
|
|
||||||
|
|
||||||
known_first_party=inventory,inventory_project,inventory_tests
|
|
||||||
|
|
||||||
no_lines_before=LOCALFOLDER
|
|
||||||
|
|
||||||
default_section=THIRDPARTY
|
|
||||||
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
|
|
||||||
|
|
||||||
lines_after_imports=2
|
|
13
.style.yapf
13
.style.yapf
|
@ -1,13 +0,0 @@
|
||||||
# https://github.com/google/yapf#formatting-style
|
|
||||||
# https://github.com/google/yapf/blob/master/yapf/yapflib/style.py
|
|
||||||
|
|
||||||
[style]
|
|
||||||
based_on_style = google
|
|
||||||
# max-line-length = 119 from django, see: https://github.com/django/django/blob/master/setup.cfg
|
|
||||||
BLANK_LINE_BEFORE_MODULE_DOCSTRING = True
|
|
||||||
COLUMN_LIMIT = 119
|
|
||||||
DEDENT_CLOSING_BRACKETS = True
|
|
||||||
EACH_DICT_ENTRY_ON_SEPARATE_LINE = True
|
|
||||||
SPLIT_BEFORE_DICT_SET_GENERATOR = False
|
|
||||||
ALLOW_SPLIT_BEFORE_DICT_VALUE = False
|
|
||||||
COALESCE_BRACKETS = True
|
|
|
@ -37,13 +37,13 @@ Plan:
|
||||||
any many more... ;)
|
any many more... ;)
|
||||||
|
|
||||||
|
|
||||||
== git branches
|
== Project structure
|
||||||
|
|
||||||
Currently we have two main branches:
|
There are two main directories:
|
||||||
|
|
||||||
|= git branch |= description
|
|= directory |= description
|
||||||
| **[[https://github.com/jedie/PyInventory/tree/master|master]]** | The main PyInventory source code
|
| **[[https://github.com/jedie/PyInventory/tree/master/src|/src/]]** | The main PyInventory source code
|
||||||
| **[[https://github.com/jedie/PyInventory/tree/deployment|deployment]]** | separate project to deploy PyInventory for production use case
|
| **[[https://github.com/jedie/PyInventory/tree/master/deployment|/deployment/]]** | deploy PyInventory for production use case
|
||||||
|
|
||||||
== install
|
== install
|
||||||
|
|
||||||
|
@ -52,16 +52,16 @@ There exists two kind of installation/usage:
|
||||||
* local development installation using poetry
|
* local development installation using poetry
|
||||||
* production use with docker-compose
|
* production use with docker-compose
|
||||||
|
|
||||||
This README (in git **master** branch) contains only the information about local develompment installation.
|
This README contains only the information about local development installation.
|
||||||
|
|
||||||
Read [[https://github.com/jedie/PyInventory/tree/deployment#readme|deployment README]] for instruction to install PyInventory on a root server.
|
Read [[https://github.com/jedie/PyInventory/tree/master/deployment#readme|/deployment/README]] for instruction to install PyInventory on a root server.
|
||||||
|
|
||||||
|
|
||||||
=== prepare
|
=== prepare
|
||||||
|
|
||||||
{{{
|
{{{
|
||||||
~$ git clone https://github.com/jedie/PyInventory.git
|
~$ git clone https://github.com/jedie/PyInventory.git
|
||||||
~$ cd PyInventory
|
~$ cd PyInventory/
|
||||||
~/PyInventory$ make
|
~/PyInventory$ make
|
||||||
help List all commands
|
help List all commands
|
||||||
install-poetry install or update poetry
|
install-poetry install or update poetry
|
||||||
|
@ -156,6 +156,7 @@ Nothing, yet ;)
|
||||||
== history
|
== history
|
||||||
|
|
||||||
* [[https://github.com/jedie/PyInventory/compare/v0.4.2...master|compare v0.4.2...master]] **dev**
|
* [[https://github.com/jedie/PyInventory/compare/v0.4.2...master|compare v0.4.2...master]] **dev**
|
||||||
|
* Merge seperate git branches into one: "/src/" and "/development/" [[https://github.com/jedie/PyInventory/issues/19|#19]]
|
||||||
** tbc
|
** tbc
|
||||||
* [[https://github.com/jedie/PyInventory/compare/v0.4.1...v0.4.2|v0.4.2 - 13.11.2020]]
|
* [[https://github.com/jedie/PyInventory/compare/v0.4.1...v0.4.2|v0.4.2 - 13.11.2020]]
|
||||||
** Serve static files by Caddy
|
** Serve static files by Caddy
|
||||||
|
|
36
README.rst
36
README.rst
|
@ -69,22 +69,22 @@ Plan:
|
||||||
|
|
||||||
any many more... ;)
|
any many more... ;)
|
||||||
|
|
||||||
------------
|
-----------------
|
||||||
git branches
|
Project structure
|
||||||
------------
|
-----------------
|
||||||
|
|
||||||
Currently we have two main branches:
|
There are two main directories:
|
||||||
|
|
||||||
+-------------------+----------------------------------------------------------------+
|
+---------------------+--------------------------------------------+
|
||||||
| git branch | description |
|
| directory | description |
|
||||||
+===================+================================================================+
|
+=====================+============================================+
|
||||||
| **`master`_** | The main PyInventory source code |
|
| **`/src/`_** | The main PyInventory source code |
|
||||||
+-------------------+----------------------------------------------------------------+
|
+---------------------+--------------------------------------------+
|
||||||
| **`deployment`_** | separate project to deploy PyInventory for production use case |
|
| **`/deployment/`_** | deploy PyInventory for production use case |
|
||||||
+-------------------+----------------------------------------------------------------+
|
+---------------------+--------------------------------------------+
|
||||||
|
|
||||||
.. _master: https://github.com/jedie/PyInventory/tree/master
|
.. _/src/: https://github.com/jedie/PyInventory/tree/master/src
|
||||||
.. _deployment: https://github.com/jedie/PyInventory/tree/deployment
|
.. _/deployment/: https://github.com/jedie/PyInventory/tree/master/deployment
|
||||||
|
|
||||||
-------
|
-------
|
||||||
install
|
install
|
||||||
|
@ -96,9 +96,9 @@ There exists two kind of installation/usage:
|
||||||
|
|
||||||
* production use with docker-compose
|
* production use with docker-compose
|
||||||
|
|
||||||
This README (in git **master** branch) contains only the information about local develompment installation.
|
This README contains only the information about local development installation.
|
||||||
|
|
||||||
Read `deployment README <https://github.com/jedie/PyInventory/tree/deployment#readme>`_ for instruction to install PyInventory on a root server.
|
Read `/deployment/README <https://github.com/jedie/PyInventory/tree/master/deployment#readme>`_ for instruction to install PyInventory on a root server.
|
||||||
|
|
||||||
prepare
|
prepare
|
||||||
=======
|
=======
|
||||||
|
@ -106,7 +106,7 @@ prepare
|
||||||
::
|
::
|
||||||
|
|
||||||
~$ git clone https://github.com/jedie/PyInventory.git
|
~$ git clone https://github.com/jedie/PyInventory.git
|
||||||
~$ cd PyInventory
|
~$ cd PyInventory/
|
||||||
~/PyInventory$ make
|
~/PyInventory$ make
|
||||||
help List all commands
|
help List all commands
|
||||||
install-poetry install or update poetry
|
install-poetry install or update poetry
|
||||||
|
@ -216,6 +216,8 @@ history
|
||||||
|
|
||||||
* `compare v0.4.2...master <https://github.com/jedie/PyInventory/compare/v0.4.2...master>`_ **dev**
|
* `compare v0.4.2...master <https://github.com/jedie/PyInventory/compare/v0.4.2...master>`_ **dev**
|
||||||
|
|
||||||
|
* Merge seperate git branches into one: "/src/" and "/development/" `#19 <https://github.com/jedie/PyInventory/issues/19>`_
|
||||||
|
|
||||||
* tbc
|
* tbc
|
||||||
|
|
||||||
* `v0.4.2 - 13.11.2020 <https://github.com/jedie/PyInventory/compare/v0.4.1...v0.4.2>`_
|
* `v0.4.2 - 13.11.2020 <https://github.com/jedie/PyInventory/compare/v0.4.1...v0.4.2>`_
|
||||||
|
@ -315,4 +317,4 @@ donation
|
||||||
|
|
||||||
------------
|
------------
|
||||||
|
|
||||||
``Note: this file is generated from README.creole 2020-11-13 09:09:36 with "python-creole"``
|
``Note: this file is generated from README.creole 2020-11-13 21:51:42 with "python-creole"``
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
|
@ -0,0 +1,79 @@
|
||||||
|
.*
|
||||||
|
!.github
|
||||||
|
!.dockerignore
|
||||||
|
!.editorconfig
|
||||||
|
!.flake8
|
||||||
|
!.gitignore
|
||||||
|
!.isort.cfg
|
||||||
|
!/.travis.yml
|
||||||
|
!/.style.yapf
|
||||||
|
!.coveralls.yml
|
||||||
|
|
||||||
|
poetry.lock
|
||||||
|
|
||||||
|
# for django-dbbackup
|
||||||
|
/backups/
|
||||||
|
!/backups/.gitkeep
|
||||||
|
|
||||||
|
# from test projects:
|
||||||
|
/static/
|
||||||
|
/media/
|
||||||
|
*.sqlite3
|
||||||
|
|
||||||
|
# docker-compose usage:
|
||||||
|
volumes
|
||||||
|
|
||||||
|
# Django
|
||||||
|
secret.txt
|
||||||
|
|
||||||
|
# Coverage HTML Report files:
|
||||||
|
htmlcov
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.tox
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
db.sqlite3
|
||||||
|
coverage_html/
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
FROM python:3.9-slim-buster
|
||||||
|
# https://hub.docker.com/_/python
|
||||||
|
|
||||||
|
# Install deps
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-mark auto $(apt-mark showinstall) \
|
||||||
|
&& apt-get install -y postgresql-client-11 python3-pip \
|
||||||
|
&& apt autoremove \
|
||||||
|
&& apt -y full-upgrade \
|
||||||
|
&& rm -rf /var/lib/apt \
|
||||||
|
&& python3 -m pip install -U pip \
|
||||||
|
&& pip install -U psycopg2-binary
|
||||||
|
|
||||||
|
WORKDIR /inventory
|
||||||
|
|
||||||
|
RUN pip install "pyinventory>=0.4.2"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
help: ## List all commands
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9 -_]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
check-poetry:
|
||||||
|
@if [[ "$(shell poetry --version 2>/dev/null)" == *"Poetry"* ]] ; \
|
||||||
|
then \
|
||||||
|
echo "Poetry found, ok." ; \
|
||||||
|
else \
|
||||||
|
echo 'Please install poetry first, with e.g.:' ; \
|
||||||
|
echo 'make install-poetry' ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
install-poetry: ## install or update poetry
|
||||||
|
@if [[ "$(shell poetry --version 2>/dev/null)" == *"Poetry"* ]] ; \
|
||||||
|
then \
|
||||||
|
echo 'Update poetry' ; \
|
||||||
|
poetry self update ; \
|
||||||
|
else \
|
||||||
|
echo 'Install poetry' ; \
|
||||||
|
curl -sSL "https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py" | python3 ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
install: check-poetry ## install requirements to setup project
|
||||||
|
poetry install
|
||||||
|
|
||||||
|
update: check-poetry ## update the sources and docker containers
|
||||||
|
git fetch --all
|
||||||
|
git pull origin deployment
|
||||||
|
poetry update
|
||||||
|
./compose.sh build --pull
|
||||||
|
$(MAKE) restart
|
||||||
|
|
||||||
|
check-compose:
|
||||||
|
@if [[ "$(shell poetry run docker-compose --version 2>/dev/null)" = *"docker-compose version"* ]] ; \
|
||||||
|
then \
|
||||||
|
echo "docker-compose found, ok." ; \
|
||||||
|
else \
|
||||||
|
echo 'Please install extras first, with e.g.:' ; \
|
||||||
|
echo 'make install-compose' ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
up: check-compose ## Start containers via docker-compose
|
||||||
|
./compose.sh up -d
|
||||||
|
$(MAKE) prune
|
||||||
|
./compose.sh logs --tail=500 --follow
|
||||||
|
|
||||||
|
down: ## Stop all containers
|
||||||
|
./compose.sh down
|
||||||
|
|
||||||
|
prune: ## Cleanup docker
|
||||||
|
docker system prune --force --all --filter until=4464h
|
||||||
|
|
||||||
|
build: check-compose ## Update docker container build
|
||||||
|
./compose.sh build --pull
|
||||||
|
|
||||||
|
init_postgres: ## Create postgres database
|
||||||
|
./compose.sh exec postgres ./docker/postgres_init.sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
createsuperuser: ## Create super user
|
||||||
|
./compose.sh exec inventory ./manage.sh createsuperuser
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
shell_inventory: ## Go into bash shell in inventory container
|
||||||
|
./compose.sh exec inventory /bin/bash
|
||||||
|
|
||||||
|
shell_postgres: ## Go into bash shell in postgres container
|
||||||
|
./compose.sh exec postgres /bin/bash
|
||||||
|
|
||||||
|
shell_caddy: ## Go into bash shell in caddy container
|
||||||
|
./compose.sh exec caddy /bin/ash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
caddy_environ: ## Prints the caddy environment
|
||||||
|
./compose.sh exec caddy /usr/bin/caddy environ
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
logs: ## Display docker logs from all containers
|
||||||
|
./compose.sh logs --tail=500 --follow
|
||||||
|
|
||||||
|
logs_postgres: ## Display docker logs from postgres container
|
||||||
|
./compose.sh logs --tail=500 --follow postgres
|
||||||
|
|
||||||
|
logs_inventory: ## Display docker logs from inventory container
|
||||||
|
./compose.sh logs --tail=500 --follow inventory
|
||||||
|
|
||||||
|
logs_caddy: ## Display docker logs from caddy container
|
||||||
|
./compose.sh logs --tail=500 --follow caddy
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
dbbackup: ## Backup database
|
||||||
|
./compose.sh exec inventory ./manage.sh dbbackup
|
||||||
|
|
||||||
|
dbrestore: ## Restore a database backup
|
||||||
|
./compose.sh exec inventory ./manage.sh dbrestore
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
restart: down up ## Restart all containers
|
||||||
|
|
||||||
|
upgrade_inventory: ## Upgrade "inventory" container and restart it
|
||||||
|
$(MAKE) build
|
||||||
|
./compose.sh stop inventory
|
||||||
|
$(MAKE) up
|
||||||
|
|
||||||
|
restart_caddy: ## Restart caddy container
|
||||||
|
./compose.sh stop caddy
|
||||||
|
$(MAKE) up
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
reload_caddy: ## Reload Caddy server
|
||||||
|
./compose.sh exec caddy caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
|
$(MAKE) logs_caddy
|
||||||
|
|
||||||
|
reload_inventory: ## Reload server in "inventory" container
|
||||||
|
./compose.sh exec inventory ./docker/kill_python.sh
|
||||||
|
./compose.sh logs --tail=500 --follow inventory
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
.PHONY: help
|
|
@ -0,0 +1,221 @@
|
||||||
|
= PyInventory - deployment instruction
|
||||||
|
|
||||||
|
Web based management to catalog things including state and location etc. using Python/Django.
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
* This README contains only the instruction to install PyInventory on a root server.
|
||||||
|
* Read [[https://github.com/jedie/PyInventory/tree/master#readme|the main README]] for local development installation.
|
||||||
|
|
||||||
|
Pull requests welcome!
|
||||||
|
|
||||||
|
|
||||||
|
== Project structure
|
||||||
|
|
||||||
|
There are two main directories:
|
||||||
|
|
||||||
|
|= directory |= description
|
||||||
|
| **[[https://github.com/jedie/PyInventory/tree/master/src|/src/]]** | The main PyInventory source code
|
||||||
|
| **[[https://github.com/jedie/PyInventory/tree/master/deployment|/deployment/]]** | deploy PyInventory for production use case
|
||||||
|
|
||||||
|
|
||||||
|
== deploy
|
||||||
|
|
||||||
|
Install PyInventory on a root server:
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
* Running a public web server is a lot of work and brings some risks.
|
||||||
|
* This instructions are only the basics to get PyInventory working.
|
||||||
|
* To run the server safely, more work should be done, which is not explained here.
|
||||||
|
* Run at your own risk! No warranty is given.
|
||||||
|
|
||||||
|
|
||||||
|
=== prepare root server
|
||||||
|
|
||||||
|
Here some steps for a fresh created root server:
|
||||||
|
|
||||||
|
Update all packages, e.g.:
|
||||||
|
{{{
|
||||||
|
apt update && apt -y full-upgrade
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Setup a normal user. You may use [[https://github.com/jedie/PyInventory/blob/deployment/scripts/setup_user.sh|scripts/setup_user.sh]]
|
||||||
|
|
||||||
|
|
||||||
|
=== Setup SSH services
|
||||||
|
|
||||||
|
{{{
|
||||||
|
~# nano /etc/ssh/sshd_config
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Change e.g.:
|
||||||
|
{{{
|
||||||
|
Port xxxx
|
||||||
|
PermitRootLogin no
|
||||||
|
PasswordAuthentication no
|
||||||
|
}}}
|
||||||
|
(Changing the Port may need to change a firewall/network settings)
|
||||||
|
|
||||||
|
{{{
|
||||||
|
# restart SSH deamon:
|
||||||
|
~# service ssh restart
|
||||||
|
|
||||||
|
# Display and follow the ssh log output to see connection errors:
|
||||||
|
~# journalctl -f -u ssh
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* Keep the current SSH session (with the log output) open!
|
||||||
|
* Update your {{{~/.ssh/config}}}
|
||||||
|
* Try to connect as the new, normal user in a **separate** terminal
|
||||||
|
|
||||||
|
Only after a working new connection: Terminate the first root SSH session ;)
|
||||||
|
|
||||||
|
|
||||||
|
=== setup unattended-upgrades
|
||||||
|
|
||||||
|
{{{
|
||||||
|
~$ sudo apt install unattended-upgrades
|
||||||
|
~$ sudo dpkg-reconfigure unattended-upgrades
|
||||||
|
~$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
=== install requirements
|
||||||
|
|
||||||
|
Install docker, see: https://docs.docker.com/engine/install/ubuntu/
|
||||||
|
|
||||||
|
install some base packages, e.g.:
|
||||||
|
{{{
|
||||||
|
~$ sudo apt install git make
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== install PyInventory
|
||||||
|
|
||||||
|
{{{
|
||||||
|
# Checkout the deployment branch:
|
||||||
|
~$ git clone https://github.com/jedie/PyInventory.git
|
||||||
|
~$ cd PyInventory/deployment/
|
||||||
|
|
||||||
|
# Theses Makefile targets exists:
|
||||||
|
~/PyInventory/deployment$ make
|
||||||
|
help List all commands
|
||||||
|
install-poetry install or update poetry
|
||||||
|
install install requirements to setup project
|
||||||
|
update update the sources and docker containers
|
||||||
|
up Start containers via docker-compose
|
||||||
|
down Stop all containers
|
||||||
|
prune Cleanup docker
|
||||||
|
build Update docker container build
|
||||||
|
init_postgres Create postgres database
|
||||||
|
createsuperuser Create super user
|
||||||
|
shell_inventory Go into bash shell in inventory container
|
||||||
|
shell_postgres Go into bash shell in postgres container
|
||||||
|
shell_caddy Go into bash shell in caddy container
|
||||||
|
caddy_environ Prints the caddy environment
|
||||||
|
logs Display docker logs from all containers
|
||||||
|
logs_postgres Display docker logs from postgres container
|
||||||
|
logs_inventory Display docker logs from inventory container
|
||||||
|
logs_caddy Display docker logs from caddy container
|
||||||
|
dbbackup Backup database
|
||||||
|
dbrestore Restore a database backup
|
||||||
|
restart Restart all containers
|
||||||
|
upgrade_inventory Upgrade "inventory" container and restart it
|
||||||
|
restart_caddy Restart caddy container
|
||||||
|
reload_caddy Reload Caddy server
|
||||||
|
reload_inventory Reload server in "inventory" container
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Install, e.g.:
|
||||||
|
|
||||||
|
{{{
|
||||||
|
# install or update poetry:
|
||||||
|
~/PyInventory/deployment$ make install-poetry
|
||||||
|
}}}
|
||||||
|
|
||||||
|
To keep poetry running (PATH must be expand) just logout and login ;)
|
||||||
|
|
||||||
|
{{{
|
||||||
|
# install requirements (e.g.: docker-compose) via poetry:
|
||||||
|
~/PyInventory/deployment$ make install
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Create a {{{.env}}} file in project root directory with these content, e.g.:
|
||||||
|
{{{
|
||||||
|
~/PyInventory/deployment$ touch .env
|
||||||
|
~/PyInventory/deployment$ nano .env
|
||||||
|
~/PyInventory/deployment$ cat .env
|
||||||
|
# Your Public domain:
|
||||||
|
HOSTNAME=domain.tld
|
||||||
|
|
||||||
|
# eMail address for Let's encrypt:
|
||||||
|
LETSENCRYPT_EMAIL=webmaster@domain.tld
|
||||||
|
}}}
|
||||||
|
|
||||||
|
For local testing of the docker-compose setup, used this values:
|
||||||
|
{{{
|
||||||
|
HOSTNAME=localhost
|
||||||
|
LETSENCRYPT_EMAIL=internal
|
||||||
|
}}}
|
||||||
|
(Caddy will create a self signed https certificate)
|
||||||
|
|
||||||
|
Start containers via docker-compose:
|
||||||
|
{{{
|
||||||
|
~/PyInventory/deployment$ make up
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Notes: At the first start it takes a little while until the database is created ;)
|
||||||
|
|
||||||
|
Create first super user:
|
||||||
|
{{{
|
||||||
|
~/PyInventory/deployment$ make docker_createsuperuser
|
||||||
|
}}}
|
||||||
|
|
||||||
|
* Now you should be able to connect to your PyInventory installation and login with created super user.
|
||||||
|
* Redirect from **http** to **https** should work.
|
||||||
|
* Let's Encrypt certificate should be installed and valid.
|
||||||
|
* Containers should be restarted after a server reboot
|
||||||
|
|
||||||
|
|
||||||
|
=== Maintenance
|
||||||
|
|
||||||
|
TO keep everything up-to-date do the following steps:
|
||||||
|
|
||||||
|
Update the OS call:
|
||||||
|
{{{
|
||||||
|
~/PyInventory/deployment$ sudo ./scripts/apt-distupgrade.sh
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Update PyInventory installation and docker containers:
|
||||||
|
{{{
|
||||||
|
~/PyInventory/deployment$ make update
|
||||||
|
}}}
|
||||||
|
|
||||||
|
This will do:
|
||||||
|
|
||||||
|
* update the source code
|
||||||
|
* update docker-compose and all requirements
|
||||||
|
* Pull and rebuild all docker containers
|
||||||
|
* restart all docker containers
|
||||||
|
|
||||||
|
Take a look at [[https://github.com/jedie/PyInventory/blob/deployment/scripts/apt-cleanup.sh|scripts/apt-cleanup.sh]] to keep your system clean.
|
||||||
|
|
||||||
|
|
||||||
|
== links ==
|
||||||
|
|
||||||
|
| Homepage | http://github.com/jedie/PyInventory
|
||||||
|
|
||||||
|
Web server stuff:
|
||||||
|
|
||||||
|
* https://help.ubuntu.com/community/Security
|
||||||
|
* https://help.ubuntu.com/lts/serverguide/automatic-updates.html
|
||||||
|
* https://help.ubuntu.com/community/AutomaticSecurityUpdate
|
||||||
|
|
||||||
|
|
||||||
|
== donation ==
|
||||||
|
|
||||||
|
* [[https://www.paypal.me/JensDiemer|paypal.me/JensDiemer]]
|
||||||
|
* [[https://flattr.com/submit/auto?uid=jedie&url=https%3A%2F%2Fgithub.com%2Fjedie%2FPyInventory%2F|Flattr This!]]
|
||||||
|
* Send [[http://www.bitcoin.org/|Bitcoins]] to [[https://blockexplorer.com/address/1823RZ5Md1Q2X5aSXRC5LRPcYdveCiVX6F|1823RZ5Md1Q2X5aSXRC5LRPcYdveCiVX6F]]
|
|
@ -0,0 +1,31 @@
|
||||||
|
# https://caddyserver.com/docs/caddyfile
|
||||||
|
|
||||||
|
{$HOSTNAME} {
|
||||||
|
tls {$LETSENCRYPT_EMAIL}
|
||||||
|
|
||||||
|
log {
|
||||||
|
output stdout
|
||||||
|
format console
|
||||||
|
level WARN
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
X-Robots-Tag "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
respond /robots.txt 200 {
|
||||||
|
body "User-agent: *
|
||||||
|
Disallow: /"
|
||||||
|
close
|
||||||
|
}
|
||||||
|
|
||||||
|
route {
|
||||||
|
file_server /static/* {
|
||||||
|
root /srv/
|
||||||
|
}
|
||||||
|
file_server /media/* {
|
||||||
|
root /srv/
|
||||||
|
}
|
||||||
|
reverse_proxy inventory:8000
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
DB_NAME=pyinventory
|
||||||
|
DB_USER=postgres
|
||||||
|
DB_PASS=postgres
|
||||||
|
DB_HOST=postgres
|
||||||
|
DB_PORT=5432
|
||||||
|
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# e.g.: pip cache:
|
||||||
|
XDG_CACHE_HOME="/var/cache"
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ -f .env ]]; then
|
||||||
|
echo "Read '.env' file..."
|
||||||
|
source .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
exec poetry run docker-compose "$@"
|
|
@ -0,0 +1,55 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
caddy: # https://hub.docker.com/_/caddy
|
||||||
|
image: caddy:2-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
- ./volumes/static/:/srv/static/:ro
|
||||||
|
- ./volumes/media/:/srv/media/:ro
|
||||||
|
environment:
|
||||||
|
- HOSTNAME=${HOSTNAME:-localhost}
|
||||||
|
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL:-internal}
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
restart: unless-stopped
|
||||||
|
hostname: inventory
|
||||||
|
ports:
|
||||||
|
- "8000"
|
||||||
|
env_file: ./common.env
|
||||||
|
environment:
|
||||||
|
- DJANGO_SETTINGS_MODULE=inventory_settings
|
||||||
|
- HOSTNAME=${HOSTNAME:-localhost}
|
||||||
|
links:
|
||||||
|
- postgres:postgres
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- caddy
|
||||||
|
volumes:
|
||||||
|
- ./inventory/:/inventory/
|
||||||
|
- ./volumes/static/:/static/:rw
|
||||||
|
- ./volumes/media/:/media/:rw
|
||||||
|
# e.g.: pip cache must be the same value as $XDG_CACHE_HOME !
|
||||||
|
- ./volumes/cache/:/var/cache/:rw
|
||||||
|
entrypoint: /inventory/entrypoint.sh
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
# https://hub.docker.com/_/postgres
|
||||||
|
image: postgres:11-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
hostname: postgres
|
||||||
|
ports:
|
||||||
|
- "5432"
|
||||||
|
env_file: ./common.env
|
||||||
|
environment:
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||||
|
volumes:
|
||||||
|
- ./postgres/init-user-db.sh:/docker-entrypoint-initdb.d/init-user-db.sh:ro
|
||||||
|
- ./volumes/postgresql/data/:/var/lib/postgresql/data/:rw
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
restart_error_handler() {
|
||||||
|
(
|
||||||
|
echo "Restart ${0} in 3 sec..."
|
||||||
|
sleep 1
|
||||||
|
echo "Restart ${0} in 2 sec..."
|
||||||
|
sleep 1
|
||||||
|
echo "Restart ${0} in 1 sec..."
|
||||||
|
sleep 1
|
||||||
|
)
|
||||||
|
exec ${0}
|
||||||
|
}
|
||||||
|
trap restart_error_handler 0
|
||||||
|
|
||||||
|
echo "_______________________________________________________________________"
|
||||||
|
echo "$(date +%c) - ${0}"
|
||||||
|
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
|
||||||
|
pip3 install -U pyinventory
|
||||||
|
|
||||||
|
./manage.py collectstatic --noinput
|
||||||
|
./manage.py migrate
|
||||||
|
|
||||||
|
uwsgi \
|
||||||
|
--http inventory:8000 \
|
||||||
|
--chdir /inventory/ \
|
||||||
|
--wsgi-file /inventory/wsgi.py \
|
||||||
|
--master \
|
||||||
|
--processes 2 \
|
||||||
|
--threads 2 \
|
||||||
|
--ignore-sigpipe \
|
||||||
|
--ignore-write-errors \
|
||||||
|
--disable-write-exception \
|
||||||
|
--http-auto-chunked \
|
||||||
|
--http-keepalive
|
||||||
|
echo "uwsgi terminated with exit code: $?"
|
||||||
|
sleep 3
|
||||||
|
exit 1
|
||||||
|
)
|
||||||
|
|
||||||
|
exit 2
|
|
@ -0,0 +1,43 @@
|
||||||
|
"""
|
||||||
|
Django settings for docker usage
|
||||||
|
"""
|
||||||
|
import os as __os
|
||||||
|
|
||||||
|
from inventory_project.settings.base import * # noqa
|
||||||
|
|
||||||
|
|
||||||
|
HOSTNAME = __os.environ['HOSTNAME']
|
||||||
|
|
||||||
|
|
||||||
|
if HOSTNAME != 'localhost':
|
||||||
|
print(f'Production mode on domain: {HOSTNAME!r}')
|
||||||
|
DEBUG = False
|
||||||
|
INTERNAL_IPS = ()
|
||||||
|
else:
|
||||||
|
print('Local development mode')
|
||||||
|
DEBUG = True
|
||||||
|
INTERNAL_IPS = ('127.0.0.1', '0.0.0.0', 'localhost')
|
||||||
|
|
||||||
|
|
||||||
|
SERVE_FILES = False # Caddy serve static/media files
|
||||||
|
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = (HOSTNAME,)
|
||||||
|
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
'NAME': __os.environ['DB_NAME'],
|
||||||
|
'USER': __os.environ['DB_USER'],
|
||||||
|
'PASSWORD': __os.environ['DB_PASS'],
|
||||||
|
'HOST': __os.environ['DB_HOST'],
|
||||||
|
'PORT': __os.environ['DB_PORT'],
|
||||||
|
'DEBUG_NAME': 'default',
|
||||||
|
'CONN_MAX_AGE': 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# docker volumes:
|
||||||
|
STATIC_ROOT = '/static/'
|
||||||
|
MEDIA_ROOT = '/media/'
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
for pid in $(pidof python3); do kill $pid; done
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
assert 'DJANGO_SETTINGS_MODULE' in os.environ, 'No "DJANGO_SETTINGS_MODULE" in environment!'
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
psql -U postgres -c "CREATE DATABASE $DB_NAME OWNER $DB_USER"
|
|
@ -0,0 +1,16 @@
|
||||||
|
[tool.poetry]
|
||||||
|
name = "pyinventory-deployment"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "production deployment for PyInventory project with docker-compose usage"
|
||||||
|
authors = ["JensDiemer <git@jensdiemer.de>"]
|
||||||
|
license = "GPL"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = ">=3.7,<4.0.0"
|
||||||
|
docker-compose = "*"
|
||||||
|
|
||||||
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Cleanup installed packages by using apt-mark:
|
||||||
|
#
|
||||||
|
# 1. mark all packages as "auto"
|
||||||
|
# 2. install really needed packages "manual"
|
||||||
|
# 3. call "autoremove" to deinstall all not needed packages
|
||||||
|
#
|
||||||
|
# WARNING: You may need some more packages depend on your cloud provider!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# Remove this lines:
|
||||||
|
echo "Adjust this script first, before you use it!"
|
||||||
|
exit 1
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$(whoami)" != "root" ]; then
|
||||||
|
echo "Please start with 'sudo' !"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
# These packages should be installed:
|
||||||
|
PACKAGES=(
|
||||||
|
linux-image-virtual ubuntu-minimal acpid
|
||||||
|
qemu-guest-agent
|
||||||
|
command-not-found
|
||||||
|
update-manager-core
|
||||||
|
unattended-upgrades
|
||||||
|
openssh-server
|
||||||
|
rsync
|
||||||
|
lshw htop mc nano
|
||||||
|
git make
|
||||||
|
apt-transport-https curl gnupg-agent software-properties-common
|
||||||
|
docker-ce docker-ce-cli containerd.io
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
apt update
|
||||||
|
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
|
||||||
|
# Mark all installed packages as "auto":
|
||||||
|
apt-mark auto $(apt-mark showinstall)
|
||||||
|
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
|
||||||
|
# Install the really needed packages:
|
||||||
|
apt -y install "${PACKAGES[@]}"
|
||||||
|
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
|
||||||
|
# Update all installed packages:
|
||||||
|
apt -y full-upgrade
|
||||||
|
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
|
||||||
|
# Deinstall all not needed packages:
|
||||||
|
apt autoremove
|
||||||
|
)
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
sudo apt update
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
sudo apt -y full-upgrade
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
sudo apt -y autoremove
|
||||||
|
{ echo "---------------------------------------------------"; } 2>/dev/null
|
||||||
|
# Delete old entries:
|
||||||
|
sudo journalctl --vacuum-size=1G
|
||||||
|
sudo journalctl --vacuum-time=1years
|
||||||
|
)
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ "$(whoami)" != "root" ]; then
|
||||||
|
echo "Please start with 'sudo' !"
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
id
|
||||||
|
exit 1
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
export USERNAME=${1}
|
||||||
|
|
||||||
|
adduser --disabled-password --gecos "" --home=/home/${USERNAME} ${USERNAME}
|
||||||
|
mkdir -p /home/${USERNAME}/.ssh
|
||||||
|
cp /root/.ssh/authorized_keys /home/${USERNAME}/.ssh/
|
||||||
|
chown -Rfc ${USERNAME}.${USERNAME} /home/${USERNAME}/
|
||||||
|
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL">/etc/sudoers.d/${USERNAME}
|
11
manage.py
11
manage.py
|
@ -1,11 +1,20 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
BASE_PATH = Path(__file__).parent
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
assert 'DJANGO_SETTINGS_MODULE' in os.environ, 'No "DJANGO_SETTINGS_MODULE" in environment!'
|
assert 'DJANGO_SETTINGS_MODULE' in os.environ, 'No "DJANGO_SETTINGS_MODULE" in environment!'
|
||||||
|
|
||||||
|
# Change to /src/ and add it to sys.path
|
||||||
|
src_path = Path(BASE_PATH, 'src').resolve()
|
||||||
|
assert src_path.is_dir(), f'Path not exists: {src_path}'
|
||||||
|
sys.path.insert(0, str(src_path))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
|
|
|
@ -627,7 +627,7 @@ python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "model-bakery"
|
name = "model-bakery"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
description = "Smart object creation facility for Django."
|
description = "Smart object creation facility for Django."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -951,7 +951,7 @@ version = "5.3.1"
|
||||||
description = "YAML parser and emitter for Python"
|
description = "YAML parser and emitter for Python"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "readme-renderer"
|
name = "readme-renderer"
|
||||||
|
@ -972,7 +972,7 @@ md = ["cmarkgfm (>=0.2.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.24.0"
|
version = "2.25.0"
|
||||||
description = "Python HTTP for Humans."
|
description = "Python HTTP for Humans."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -982,7 +982,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
certifi = ">=2017.4.17"
|
certifi = ">=2017.4.17"
|
||||||
chardet = ">=3.0.2,<4"
|
chardet = ">=3.0.2,<4"
|
||||||
idna = ">=2.5,<3"
|
idna = ">=2.5,<3"
|
||||||
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
urllib3 = ">=1.21.1,<1.27"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||||
|
@ -1143,7 +1143,7 @@ tqdm = ">=4.14"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "1.25.11"
|
version = "1.26.2"
|
||||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -1326,6 +1326,7 @@ chardet = [
|
||||||
]
|
]
|
||||||
colorama = [
|
colorama = [
|
||||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||||
|
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||||
]
|
]
|
||||||
colorlog = [
|
colorlog = [
|
||||||
{file = "colorlog-4.6.2-py2.py3-none-any.whl", hash = "sha256:edd5ada5de03e880e42b2526f8be5570fd9b692f8eb7cf6b1fdcac3e3fb23976"},
|
{file = "colorlog-4.6.2-py2.py3-none-any.whl", hash = "sha256:edd5ada5de03e880e42b2526f8be5570fd9b692f8eb7cf6b1fdcac3e3fb23976"},
|
||||||
|
@ -1508,6 +1509,7 @@ importlib-metadata = [
|
||||||
{file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"},
|
{file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"},
|
||||||
]
|
]
|
||||||
iniconfig = [
|
iniconfig = [
|
||||||
|
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||||
]
|
]
|
||||||
isort = [
|
isort = [
|
||||||
|
@ -1538,8 +1540,8 @@ mccabe = [
|
||||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||||
]
|
]
|
||||||
model-bakery = [
|
model-bakery = [
|
||||||
{file = "model_bakery-1.2.0-py2.py3-none-any.whl", hash = "sha256:b25f400b392067f02d841a0ef33e861543c04b1702dc004020bdd50e1dbce05f"},
|
{file = "model_bakery-1.2.1-py2.py3-none-any.whl", hash = "sha256:d3260bd055c25998b54eda2082a507ba7fd113fe071156bdad065da426b14851"},
|
||||||
{file = "model_bakery-1.2.0.tar.gz", hash = "sha256:088698cdf62e5ccedeb97e55ceb966c974cc79e2514928aec9beab27a8c1faf4"},
|
{file = "model_bakery-1.2.1.tar.gz", hash = "sha256:c2b3521a866b2b25ee0b5f953bfa385ef7d27ad75f30abf5e2de6dd61160c404"},
|
||||||
]
|
]
|
||||||
odfpy = [
|
odfpy = [
|
||||||
{file = "odfpy-1.4.1-py2.7.egg", hash = "sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"},
|
{file = "odfpy-1.4.1-py2.7.egg", hash = "sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"},
|
||||||
|
@ -1637,6 +1639,8 @@ psycopg2-binary = [
|
||||||
{file = "psycopg2_binary-2.8.6-cp39-cp39-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83"},
|
{file = "psycopg2_binary-2.8.6-cp39-cp39-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83"},
|
||||||
{file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52"},
|
{file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52"},
|
||||||
{file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd"},
|
{file = "psycopg2_binary-2.8.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd"},
|
||||||
|
{file = "psycopg2_binary-2.8.6-cp39-cp39-win32.whl", hash = "sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056"},
|
||||||
|
{file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"},
|
||||||
]
|
]
|
||||||
py = [
|
py = [
|
||||||
{file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"},
|
{file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"},
|
||||||
|
@ -1753,8 +1757,8 @@ readme-renderer = [
|
||||||
{file = "readme_renderer-28.0.tar.gz", hash = "sha256:6b7e5aa59210a40de72eb79931491eaf46fefca2952b9181268bd7c7c65c260a"},
|
{file = "readme_renderer-28.0.tar.gz", hash = "sha256:6b7e5aa59210a40de72eb79931491eaf46fefca2952b9181268bd7c7c65c260a"},
|
||||||
]
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"},
|
{file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"},
|
||||||
{file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"},
|
{file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"},
|
||||||
]
|
]
|
||||||
requests-toolbelt = [
|
requests-toolbelt = [
|
||||||
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
||||||
|
@ -1805,8 +1809,8 @@ twine = [
|
||||||
{file = "twine-3.2.0.tar.gz", hash = "sha256:34352fd52ec3b9d29837e6072d5a2a7c6fe4290e97bba46bb8d478b5c598f7ab"},
|
{file = "twine-3.2.0.tar.gz", hash = "sha256:34352fd52ec3b9d29837e6072d5a2a7c6fe4290e97bba46bb8d478b5c598f7ab"},
|
||||||
]
|
]
|
||||||
urllib3 = [
|
urllib3 = [
|
||||||
{file = "urllib3-1.25.11-py2.py3-none-any.whl", hash = "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"},
|
{file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"},
|
||||||
{file = "urllib3-1.25.11.tar.gz", hash = "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"},
|
{file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"},
|
||||||
]
|
]
|
||||||
uwsgi = [
|
uwsgi = [
|
||||||
{file = "uWSGI-2.0.19.1.tar.gz", hash = "sha256:faa85e053c0b1be4d5585b0858d3a511d2cd10201802e8676060fd0a109e5869"},
|
{file = "uWSGI-2.0.19.1.tar.gz", hash = "sha256:faa85e053c0b1be4d5585b0858d3a511d2cd10201802e8676060fd0a109e5869"},
|
||||||
|
|
|
@ -4,8 +4,8 @@ version = "0.4.2"
|
||||||
description = "Web based management to catalog things including state and location etc. using Python/Django."
|
description = "Web based management to catalog things including state and location etc. using Python/Django."
|
||||||
authors = ["JensDiemer <git@jensdiemer.de>"]
|
authors = ["JensDiemer <git@jensdiemer.de>"]
|
||||||
packages = [
|
packages = [
|
||||||
{ include = "inventory" },
|
{ include = "inventory", from = "src" },
|
||||||
{ include = "inventory_project" },
|
{ include = "inventory_project", from = "src" },
|
||||||
]
|
]
|
||||||
keywords=['inventory','django']
|
keywords=['inventory','django']
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
@ -84,11 +84,73 @@ manage = "inventory_project.manage:main"
|
||||||
update_rst_readme = "inventory_project.publish:update_readme"
|
update_rst_readme = "inventory_project.publish:update_readme"
|
||||||
publish = "inventory_project.publish:publish"
|
publish = "inventory_project.publish:publish"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry>=0.12"]
|
||||||
|
build-backend = "poetry.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
[tool.autopep8]
|
[tool.autopep8]
|
||||||
# https://github.com/hhatto/autopep8#pyprojecttoml
|
# https://github.com/hhatto/autopep8#pyprojecttoml
|
||||||
max_line_length = 120
|
max_line_length = 120
|
||||||
exclude = "*/migrations/*"
|
exclude = "*/migrations/*"
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry>=0.12"]
|
[tool.isort]
|
||||||
build-backend = "poetry.masonry.api"
|
# https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format
|
||||||
|
atomic=true
|
||||||
|
line_length=120
|
||||||
|
case_sensitive=false
|
||||||
|
skip_glob=["*/migrations/*","*/volumes/*"]
|
||||||
|
multi_line_output=3
|
||||||
|
include_trailing_comma=true
|
||||||
|
known_first_party=["inventory","inventory_project","inventory_tests"]
|
||||||
|
no_lines_before="LOCALFOLDER"
|
||||||
|
default_section="THIRDPARTY"
|
||||||
|
sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"]
|
||||||
|
lines_after_imports=2
|
||||||
|
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
# https://docs.pytest.org/en/latest/customize.html#pyproject-toml
|
||||||
|
minversion = "6.0"
|
||||||
|
DJANGO_SETTINGS_MODULE="inventory_project.settings.tests"
|
||||||
|
norecursedirs = ".* .git __pycache__ coverage* dist"
|
||||||
|
# sometimes helpfull "addopts" arguments:
|
||||||
|
# -vv
|
||||||
|
# --verbose
|
||||||
|
# --capture=no
|
||||||
|
# --trace-config
|
||||||
|
# --full-trace
|
||||||
|
# -p no:warnings
|
||||||
|
addopts = """
|
||||||
|
--import-mode=importlib
|
||||||
|
--ignore-glob=deployment/inventory/*
|
||||||
|
--reuse-db
|
||||||
|
--nomigrations
|
||||||
|
--cov=.
|
||||||
|
--cov-report term-missing
|
||||||
|
--cov-report html
|
||||||
|
--cov-report xml
|
||||||
|
--no-cov-on-fail
|
||||||
|
--showlocals
|
||||||
|
--doctest-modules
|
||||||
|
--failed-first
|
||||||
|
--last-failed-no-failures all
|
||||||
|
--new-first
|
||||||
|
-p no:randomly
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
[tool.tox]
|
||||||
|
# https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini
|
||||||
|
legacy_tox_ini = """
|
||||||
|
[tox]
|
||||||
|
isolated_build = True
|
||||||
|
envlist = py39,py38,py37
|
||||||
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
whitelist_externals = pytest
|
||||||
|
commands =
|
||||||
|
pytest --pyargs inventory inventory_project
|
||||||
|
"""
|
||||||
|
|
46
pytest.ini
46
pytest.ini
|
@ -1,46 +0,0 @@
|
||||||
#
|
|
||||||
# http://doc.pytest.org/en/latest/customize.html#builtin-configuration-file-options
|
|
||||||
# https://pytest-django.readthedocs.io/en/latest/
|
|
||||||
|
|
||||||
[pytest]
|
|
||||||
DJANGO_SETTINGS_MODULE=inventory_project.settings.tests
|
|
||||||
testpaths =
|
|
||||||
inventory/tests/
|
|
||||||
inventory_project/tests/
|
|
||||||
|
|
||||||
# http://doc.pytest.org/en/latest/customize.html#confval-norecursedirs
|
|
||||||
norecursedirs = .* .git __pycache__ coverage* dist
|
|
||||||
addopts =
|
|
||||||
--reuse-db
|
|
||||||
--nomigrations
|
|
||||||
|
|
||||||
# coverage:
|
|
||||||
--cov=.
|
|
||||||
--cov-report term-missing
|
|
||||||
--cov-report html
|
|
||||||
--cov-report xml
|
|
||||||
--no-cov-on-fail
|
|
||||||
|
|
||||||
--showlocals
|
|
||||||
|
|
||||||
--doctest-modules
|
|
||||||
|
|
||||||
# run the last failures first:
|
|
||||||
--failed-first
|
|
||||||
|
|
||||||
# run all tests if no tests failed in the last run:
|
|
||||||
--last-failed-no-failures all
|
|
||||||
|
|
||||||
# sort new tests first:
|
|
||||||
--new-first
|
|
||||||
|
|
||||||
# randomly is sometimes helpfull, comment this:
|
|
||||||
-p no:randomly
|
|
||||||
|
|
||||||
# sometimes helpfull:
|
|
||||||
#-vv
|
|
||||||
#--verbose
|
|
||||||
#--capture=no
|
|
||||||
#--trace-config
|
|
||||||
#--full-trace
|
|
||||||
#-p no:warnings
|
|
|
@ -8,7 +8,7 @@ from poetry_publish.utils.subprocess_utils import verbose_check_call
|
||||||
import inventory
|
import inventory
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_ROOT = Path(inventory.__file__).parent.parent
|
PACKAGE_ROOT = Path(inventory.__file__).parent.parent.parent
|
||||||
|
|
||||||
|
|
||||||
def update_readme():
|
def update_readme():
|
|
@ -8,8 +8,9 @@ from pathlib import Path as __Path
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
# Build paths inside the project:
|
# Build paths relative to the current working directory:
|
||||||
BASE_PATH = __Path(__file__).resolve().parent.parent.parent
|
BASE_PATH = __Path().cwd().resolve()
|
||||||
|
print(f'BASE_PATH:{BASE_PATH}')
|
||||||
|
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
|
@ -7,7 +7,6 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys as __sys
|
import sys as __sys
|
||||||
from pathlib import Path as __Path
|
|
||||||
|
|
||||||
from inventory_project.settings.base import * # noqa
|
from inventory_project.settings.base import * # noqa
|
||||||
|
|
||||||
|
@ -31,8 +30,7 @@ ALLOWED_HOSTS = INTERNAL_IPS
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': str(__Path(BASE_PATH.parent, 'PyInventory-database.sqlite3')),
|
'NAME': str(BASE_PATH / 'PyInventory-database.sqlite3'),
|
||||||
# 'NAME': ':memory:'
|
|
||||||
# https://docs.djangoproject.com/en/dev/ref/databases/#database-is-locked-errors
|
# https://docs.djangoproject.com/en/dev/ref/databases/#database-is-locked-errors
|
||||||
'timeout': 30,
|
'timeout': 30,
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ from pathlib import Path
|
||||||
import inventory
|
import inventory
|
||||||
|
|
||||||
|
|
||||||
BASE_PATH = Path(inventory.__file__).parent.parent
|
BASE_PATH = Path(inventory.__file__).parent.parent.parent
|
||||||
|
|
||||||
|
|
||||||
def test_lint():
|
def test_lint():
|
|
@ -8,7 +8,7 @@ from creole.setup_utils import update_rst_readme
|
||||||
import inventory
|
import inventory
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_ROOT = Path(inventory.__file__).parent.parent
|
PACKAGE_ROOT = Path(inventory.__file__).parent.parent.parent
|
||||||
|
|
||||||
|
|
||||||
def assert_file_contains_string(file_path, string):
|
def assert_file_contains_string(file_path, string):
|
|
@ -0,0 +1,9 @@
|
||||||
|
"""
|
||||||
|
WSGI config
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
11
tox.ini
11
tox.ini
|
@ -1,11 +0,0 @@
|
||||||
[tox]
|
|
||||||
isolated_build = True
|
|
||||||
envlist = py39,py38,py37
|
|
||||||
skip_missing_interpreters = True
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
whitelist_externals = make
|
|
||||||
commands =
|
|
||||||
make install
|
|
||||||
make pytest
|
|
||||||
|
|
Ładowanie…
Reference in New Issue