Merge branch 'mysql-install'

This commit is contained in:
Oliver Walters 2019-08-14 13:19:13 +10:00
commit 2c1b20b5d5
9 changed files with 116 additions and 74 deletions

3
.gitignore vendored
View File

@ -35,6 +35,9 @@ docs/_build
InvenTree/media InvenTree/media
InvenTree/static InvenTree/static
# Local config file
config.yaml
# Key file # Key file
secret_key.txt secret_key.txt

View File

@ -11,7 +11,7 @@ addons:
before_install: before_install:
- make requirements - make requirements
- make secret - make setup
- make migrate - make migrate
script: script:

View File

@ -11,11 +11,18 @@ database setup in this file.
""" """
import sys
import os import os
import logging import logging
import tempfile import tempfile
import yaml import yaml
def eprint(*args, **kwargs):
""" Print a warning message to stderr """
print(*args, file=sys.stderr, **kwargs)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -23,7 +30,7 @@ cfg_filename = os.path.join(BASE_DIR, 'config.yaml')
if not os.path.exists(cfg_filename): if not os.path.exists(cfg_filename):
CONFIG = {} CONFIG = {}
print("Warning: config.yaml not found - using default settings") eprint("Warning: config.yaml not found - using default settings")
else: else:
with open(cfg_filename, 'r') as cfg: with open(cfg_filename, 'r') as cfg:
CONFIG = yaml.safe_load(cfg) CONFIG = yaml.safe_load(cfg)
@ -52,7 +59,7 @@ if cors_opt:
CORS_ORIGIN_ALLOW_ALL = cors_opt.get('allow_all', False) CORS_ORIGIN_ALLOW_ALL = cors_opt.get('allow_all', False)
if CORS_ORIGIN_ALLOW_ALL: if CORS_ORIGIN_ALLOW_ALL:
print("Warning: CORS requests are allowed for any domain!") eprint("Warning: CORS requests are allowed for any domain!")
else: else:
CORS_ORIGIN_WHITELIST = cors_opt.get('whitelist', []) CORS_ORIGIN_WHITELIST = cors_opt.get('whitelist', [])
@ -156,7 +163,7 @@ DATABASES = {}
if 'database' in CONFIG: if 'database' in CONFIG:
DATABASES['default'] = CONFIG['database'] DATABASES['default'] = CONFIG['database']
else: else:
print("Warning: Database backend not specified - using default (sqlite)") eprint("Warning: Database backend not specified - using default (sqlite)")
DATABASES['default'] = { DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'inventree_db.sqlite3'), 'NAME': os.path.join(BASE_DIR, 'inventree_db.sqlite3'),

View File

@ -3,15 +3,20 @@
# Ref: https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-DATABASES # Ref: https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-DATABASES
# Specify database parameters below as they appear in the Django docs # Specify database parameters below as they appear in the Django docs
database: database:
# Example configuration - sqlite (default)
ENGINE: django.db.backends.sqlite3 ENGINE: django.db.backends.sqlite3
NAME: inventree_db.sqlite3 NAME: inventree_db.sqlite3
# For more complex database installations, further parameters are required # For more complex database installations, further parameters are required
# Refer to the django documentation for full list of options # Refer to the django documentation for full list of options
# USER: db_username
# PASSWORD: db_password # Example Configuration - MySQL
# HOST: db_hostname #ENGINE: django.db.backends.mysql
# PORT: db_port #NAME: inventree
#USER: inventree
#PASSWORD: password
#HOST: ''
#PORT: ''
# Set debug to False to run in production mode # Set debug to False to run in production mode
debug: True debug: True
@ -36,7 +41,7 @@ cors:
# MEDIA_ROOT is the local filesystem location for storing uploaded files # MEDIA_ROOT is the local filesystem location for storing uploaded files
# By default, it is stored in a directory named 'media' local to the InvenTree directory # By default, it is stored in a directory named 'media' local to the InvenTree directory
# This should be changed for a production installation # This should be changed for a production installation
media_root: './media' media_root: 'media'
# STATIC_ROOT is the local filesystem location for storing static files # STATIC_ROOT is the local filesystem location for storing static files
# By default it is stored in a directory named 'static' local to the InvenTree directory # By default it is stored in a directory named 'static' local to the InvenTree directory
@ -47,4 +52,4 @@ log_queries: False
# Backup options # Backup options
# Set the backup_dir parameter to store backup files in a specific location # Set the backup_dir parameter to store backup files in a specific location
# backup_dir = "/home/me/inventree-backup/" backup_dir: '/mnt/c/Users/Oliver/inventree-backup/'

View File

@ -1,56 +0,0 @@
"""
Generates a Django SECRET_KEY file to be used by manage.py
"""
import random
import string
import os
import sys
import argparse
KEY_FN = 'secret_key.txt'
KEY_DIR = os.path.dirname(os.path.realpath(__file__))
def generate_key(length=50):
""" Generate a random string
Args:
length: Number of characters in returned string (default = 50)
Returns:
Randomized secret key string
"""
options = string.digits + string.ascii_letters + string.punctuation
key = ''.join([random.choice(options) for i in range(length)])
return key
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Generate Django SECRET_KEY file')
parser.add_argument('--output', help='Specify key file path', default=None)
parser.add_argument('--force', '-f', help='Override key file (if it exists)', action='store_true')
parser.add_argument('--dummy', '-d', help='Dummy run (display key only', action='store_true')
args = parser.parse_args()
if args.output:
key_filename = args.output
else:
key_filename = os.path.join(KEY_DIR, KEY_FN)
key_data = generate_key()
if args.dummy:
print('SECRET_KEY: {k}'.format(k=key_data))
sys.exit(0)
if not args.force and os.path.exists(key_filename):
print("Key file already exists - '{f}'".format(f=key_filename))
sys.exit(0)
with open(key_filename, 'w') as key_file:
print("Generating SECRET_KEY file - '{f}'".format(f=key_filename))
key_file.write(key_data)

68
InvenTree/setup.py Normal file
View File

@ -0,0 +1,68 @@
"""
Performs initial setup functions.
- Generates a Django SECRET_KEY file to be used by manage.py
- Copies config template file (if a config file does not already exist)
"""
import random
import string
import os
import sys
import argparse
from shutil import copyfile
OUTPUT_DIR = os.path.dirname(os.path.realpath(__file__))
KEY_FN = 'secret_key.txt'
CONFIG_FN = 'config.yaml'
CONFIG_TEMPLATE_FN = 'config_template.yaml'
def generate_key(length=50):
""" Generate a random string
Args:
length: Number of characters in returned string (default = 50)
Returns:
Randomized secret key string
"""
options = string.digits + string.ascii_letters + string.punctuation
key = ''.join([random.choice(options) for i in range(length)])
return key
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Generate Django SECRET_KEY file')
parser.add_argument('--force', '-f', help='Override existing files', action='store_true')
parser.add_argument('--dummy', '-d', help='Dummy run (do not create any files)', action='store_true')
args = parser.parse_args()
# Places to store files
key_filename = os.path.join(OUTPUT_DIR, KEY_FN)
conf_template = os.path.join(OUTPUT_DIR, CONFIG_TEMPLATE_FN)
conf_filename = os.path.join(OUTPUT_DIR, CONFIG_FN)
# Generate secret key data
key_data = generate_key()
if args.dummy:
print('SECRET_KEY: {k}'.format(k=key_data))
sys.exit(0)
if not args.force and os.path.exists(key_filename):
print("Key file already exists - '{f}'".format(f=key_filename))
else:
with open(key_filename, 'w') as key_file:
print("Generating SECRET_KEY file - '{f}'".format(f=key_filename))
key_file.write(key_data)
if not args.force and os.path.exists(conf_filename):
print("Config file already exists (skipping)")
else:
print("Copying config template to 'config.yaml'")
copyfile(conf_template, conf_filename)

View File

@ -19,13 +19,18 @@ migrate:
requirements: requirements:
pip3 install -U -r requirements.txt pip3 install -U -r requirements.txt
secret: setup:
python3 InvenTree/keygen.py python3 InvenTree/setup.py
superuser: superuser:
python3 InvenTree/manage.py createsuperuser python3 InvenTree/manage.py createsuperuser
install: requirements secret migrate superuser install: requirements setup migrate superuser
mysql:
apt-get install mysql-server
apt-get install libmysqlclient-dev
pip3 install mysqlclient
style: style:
flake8 InvenTree flake8 InvenTree
@ -47,4 +52,4 @@ backup:
python3 InvenTree/manage.py dbbackup python3 InvenTree/manage.py dbbackup
python3 InvenTree/manage.py mediabackup python3 InvenTree/manage.py mediabackup
.PHONY: clean migrate requirements secret superuser install style test coverage documentation backup .PHONY: clean migrate requirements setup superuser install mysql style test coverage documentation backup

View File

@ -15,7 +15,7 @@ To support install specific settings, a simple configuration file ``config.yaml`
The default configuration file launches a *DEBUG* configuration with a simple SQLITE database backend. This default configuration file is shown below: The default configuration file launches a *DEBUG* configuration with a simple SQLITE database backend. This default configuration file is shown below:
.. literalinclude :: ../InvenTree/config.yaml .. literalinclude :: ../InvenTree/config_template.yaml
:language: yaml :language: yaml
:linenos: :linenos:
@ -30,7 +30,17 @@ Database options are specified under the *database* heading in the configuration
By default, InvenTree uses an sqlite database file : ``inventree_db.sqlite3``. This provides a simple, portable database file that is easy to use for debug and testing purposes. By default, InvenTree uses an sqlite database file : ``inventree_db.sqlite3``. This provides a simple, portable database file that is easy to use for debug and testing purposes.
**MYSQL:** MySQL database backend is supported with the native Django implemetation. **MYSQL:** MySQL database backend is supported with the native Django implemetation. To run InvenTree with the MySQL backend, a number of extra packages need to be installed:
* mysql-server - *MySQL backend server*
* libmysqlclient-dev - *Required for connecting to the MySQL database in Python*
* (pip) mysqlclient - *Python package for communication with MySQL database*
These requirements can be installed from the base directory with the command ``make mysql``.
It is up to the database adminstrator to create a new database to store inventree data, in addition to a username/password to access the data.
The database options then need to be adjusted to communicate the MySQL backend. Refer to the `Django docs <https://docs.djangoproject.com/en/dev/ref/databases/>`_ for further information.
**POSTGRESQL:** PostgreSQL database backend is supported with the native Django implementation. Note that to use this backend, the ``psycopg2`` Python library must first be installed. **POSTGRESQL:** PostgreSQL database backend is supported with the native Django implementation. Note that to use this backend, the ``psycopg2`` Python library must first be installed.

View File

@ -52,7 +52,7 @@ Development and Testing
Other shorthand functions are provided for the development and testing process: Other shorthand functions are provided for the development and testing process:
* ``make requirements`` - Install all required underlying packages using PIP * ``make requirements`` - Install all required underlying packages using PIP
* ``make secret`` - Generate the SECRET_KEY file for session validation * ``make setup`` - Perform one-time setup functions
* ``make superuser`` - Create a superuser account * ``make superuser`` - Create a superuser account
* ``make backup`` - Backup database tables and media files * ``make backup`` - Backup database tables and media files
* ``make test`` - Run all unit tests * ``make test`` - Run all unit tests