From e29646a94714d516d52272fc83d9a15bbc21e488 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 27 Dec 2014 13:52:45 +0100 Subject: [PATCH 01/13] initial version --- .gitignore | 2 ++ __init__.py | 0 celeryrouters.py | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 .gitignore create mode 100644 __init__.py create mode 100644 celeryrouters.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3bb2efd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.*.swp +*.pyc diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/celeryrouters.py b/celeryrouters.py new file mode 100644 index 0000000..e468813 --- /dev/null +++ b/celeryrouters.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + + +class LdapRouter(object): + + def route_for_task(self, task, args=None, kwargs=None): + if 'ldap' in task: + return {'exchange': 'ldap', + 'exchange_type': 'direct', + 'queue': 'ldap'} + return None + + +class FileRouter(object): + + def route_for_task(self, task, args=None, kwargs=None): + if 'file' in task: + return {'exchange': 'file', + 'exchange_type': 'direct', + 'queue': 'file'} + return None + + From 546441d49920caf43eb7d33976c2d71ae85f16d5 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 1 Jan 2015 22:32:37 +0100 Subject: [PATCH 02/13] unify routers, add support for mysql and pgsql tasks - add new celeryrouters.GvaRouter - remove LdapRouter and FileRouter --- .gitignore | 1 + celeryrouters.py | 23 +++++++---------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 3bb2efd..5f1ace6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .*.swp *.pyc +.ropeproject/ diff --git a/celeryrouters.py b/celeryrouters.py index e468813..ec7b122 100644 --- a/celeryrouters.py +++ b/celeryrouters.py @@ -2,23 +2,14 @@ from __future__ import unicode_literals -class LdapRouter(object): +class GvaRouter(object): def route_for_task(self, task, args=None, kwargs=None): - if 'ldap' in task: - return {'exchange': 'ldap', + for route in ['ldap', 'file', 'mysql', 'pgsql']: + if route in task: + return { + 'exchange': route, 'exchange_type': 'direct', - 'queue': 'ldap'} + 'queue': route, + } return None - - -class FileRouter(object): - - def route_for_task(self, task, args=None, kwargs=None): - if 'file' in task: - return {'exchange': 'file', - 'exchange_type': 'direct', - 'queue': 'file'} - return None - - From e9c1a218d6782fcd5fdbbd15b455ee448a52165b Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 8 Jan 2015 20:30:57 +0100 Subject: [PATCH 03/13] initial documentation and requirements --- .gitignore | 43 +++++++ CONTRIBUTORS.txt | 1 + LICENSE.txt | 22 ++++ README.rst | 13 ++ docs/Makefile | 153 ++++++++++++++++++++++ docs/__init__.py | 0 docs/changelog.rst | 4 + docs/code.rst | 39 ++++++ docs/conf.py | 248 ++++++++++++++++++++++++++++++++++++ docs/deploy.rst | 10 ++ docs/index.rst | 27 ++++ docs/install.rst | 83 ++++++++++++ docs/make.bat | 190 +++++++++++++++++++++++++++ requirements.txt | 3 + requirements/base.txt | 8 ++ requirements/local.txt | 6 + requirements/production.txt | 3 + requirements/test.txt | 3 + 18 files changed, 856 insertions(+) create mode 100644 .gitignore create mode 100644 CONTRIBUTORS.txt create mode 100644 LICENSE.txt create mode 100644 README.rst create mode 100644 docs/Makefile create mode 100644 docs/__init__.py create mode 100644 docs/changelog.rst create mode 100644 docs/code.rst create mode 100644 docs/conf.py create mode 100644 docs/deploy.rst create mode 100644 docs/index.rst create mode 100644 docs/install.rst create mode 100644 docs/make.bat create mode 100644 requirements.txt create mode 100644 requirements/base.txt create mode 100644 requirements/local.txt create mode 100644 requirements/production.txt create mode 100644 requirements/test.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79f6256 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Python bytecode: +*.py[co] + +# Packaging files: +*.egg* + +# Sphinx docs: +build + +# SQLite3 database files: +*.db + +# Logs: +*.log + +# Eclipse +.project +.pydevproject +.settings + +# Linux Editors +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +.elc +auto-save-list +tramp +.\#* +*.swp +*.swo + +# Mac +.DS_Store +._* + +# Windows +Thumbs.db +Desktop.ini + +.ropeproject +_build/ +*.sqlite3 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 0000000..dc72595 --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1 @@ +Jan Dittberner diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..53c8c14 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2015 Jan Dittberner + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..e23cd88 --- /dev/null +++ b/README.rst @@ -0,0 +1,13 @@ +======== +gvamysql +======== + +This is the GNUViech Admin PostgreSQL server administration tool project. + +GNUViech Admin is a suite of tools for server management used for hosting +customer management at `Jan Dittberner IT-Consulting & -Solutions +`_. + +Read the :doc:`Installation instructions ` to get started locally. + +The project page for gvafile is at http://dev.gnuviech-server.de/gvapgsql. diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..9842cf5 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/{{ project_name }}.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/{{ project_name }}.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/{{ project_name }}" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/{{ project_name }}" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/__init__.py b/docs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..15a0c50 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,4 @@ +Changelog +========= + +* :feature:`-` initial project setup diff --git a/docs/code.rst b/docs/code.rst new file mode 100644 index 0000000..0aac8f9 --- /dev/null +++ b/docs/code.rst @@ -0,0 +1,39 @@ +================== +Code documentation +================== + +gvapgsql is implemented as `Celery`_ app. + +.. _Celery: http://www.celeryproject.org/ + + +The project module :py:mod:`gvapgsql` +===================================== + +.. automodule:: gvapgsql + + +:py:mod:`gvapgsql.celery` +------------------------- + +.. automodule:: gvapgsql.celery + :members: + + +:py:mod:`gvapgsql.settings` +--------------------------- + +.. automodule:: gvapgsql.settings + + +:py:mod:`pgsqltasks` app +======================== + +.. automodule:: pgsqltasks + +:py:mod:`pgsqltasks.tasks` +-------------------------- + +.. automodule:: pgsqltasks.tasks + :members: + :undoc-members: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..bd9cefb --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# pymode:lint_ignore=E501 +# +# gvamysql documentation build configuration file, created by +# sphinx-quickstart on Sun Feb 17 11:46:20 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath(os.path.join('..', 'gvapgsql'))) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['releases', 'sphinx.ext.autodoc', 'celery.contrib.sphinx'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +releases_issue_uri = 'https://dev.gnuviech-server.de/gvapgsql/ticket/%s' + +releases_release_uri = 'https://dev.gnuviech-server.de/gvapgsql/milestone/%s' + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'gvapgsql' +copyright = u'2015 Jan Dittberner' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.0' +# The full version, including alpha/beta/rc tags. +release = '0.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'gvapgsqldoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + #'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'gvapgsql.tex', u'gvapgsql Documentation', + u'Jan Dittberner', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'gvapgsql', u'gvapgsql Documentation', + [u'Jan Dittberner'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'gvapgsql', u'gvapgsql Documentation', + u'Jan Dittberner', 'gvapgsql', 'GNUViech admin PostgreSQL server tools.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' diff --git a/docs/deploy.rst b/docs/deploy.rst new file mode 100644 index 0000000..e71b99a --- /dev/null +++ b/docs/deploy.rst @@ -0,0 +1,10 @@ +Deploy +====== + +The production deployment for gvapgsql is performed using saltstack and consists +of the following steps: + +* installation of native dependencies +* setup of a virtualenv +* installation of gvapgsql production dependencies inside the virtualenv +* setup of celery worker under control of supervisord diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..422340e --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,27 @@ +.. gvapgsql documentation master file, created for gvaldap by + sphinx-quickstart on Sun Feb 17 11:46:20 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. include:: ../README.rst + +Welcome to gvapgsql's documentation! +==================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + install + deploy + code + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..e7e3633 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,83 @@ +.. index:: installation + +======= +Install +======= + +Working Environment +=================== + +You have several options in setting up your working environment. We recommend +using virtualenv to separate the dependencies of your project from your +system's python environment. If on Linux or Mac OS X, you can also use +virtualenvwrapper to help manage multiple virtualenvs across different +projects. + +.. index:: virtualenv + +Virtualenv Only +--------------- + +First, make sure you are using `virtualenv`_. Once that's installed, create +your virtualenv: + +.. code-block:: sh + + $ virtualenv --distribute gvapgsql + +.. _virtualenv: https://virtualenv.pypa.io/en/latest/ + +You will also need to ensure that the virtualenv has the project directory +added to the path. + +.. index:: virtualenvwrapper + +Virtualenv with virtualenvwrapper +------------------------------------ + +In Linux and Mac OSX, you can install `virtualenvwrapper +`_, which will take care +of managing your virtual environments and adding the project path to the +`site-directory` for you: + +.. code-block:: sh + + $ mkdir gvapgsql + $ mkvirtualenv -a gvapgsql gvapgsql-dev + $ cd gvapgsql && add2virtualenv `pwd` + + +.. index:: pip, requirements, dependencies + +Installation of Dependencies +============================= + +Depending on where you are installing dependencies: + +In development: + +.. code-block:: sh + + $ pip install -r requirements/local.txt + +For production: + +.. code-block:: sh + + $ pip install -r requirements.txt + +.. index:: celery, worker, file queue + +Running the Celery worker +========================= + +gvapgsql uses the `Celery`_ distributed task queue system. The gvapgsql logic is +executed by a celery worker. After all dependencies are installed you can go +into the gvapgsql directory and run the celery worker with: + +.. code-block:: sh + + $ cd gvapgsql + $ celery -A gvapgsql worker -Q pgsql -l info + +.. _Celery: http://www.celeryproject.org/ diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..c8212a0 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\{{ project_name }}.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\{{ project_name }}.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0b95660 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# This file is here because many Platforms as a Service look for +# requirements.txt in the root directory of a project. +-r requirements/production.txt diff --git a/requirements/base.txt b/requirements/base.txt new file mode 100644 index 0000000..178da47 --- /dev/null +++ b/requirements/base.txt @@ -0,0 +1,8 @@ +amqp==1.4.6 +bpython==0.13.1 +anyjson==0.3.3 +billiard==3.3.0.19 +celery==3.1.17 +kombu==3.0.24 +pytz==2014.10 +psycopg2==2.5.4 diff --git a/requirements/local.txt b/requirements/local.txt new file mode 100644 index 0000000..d0cecd4 --- /dev/null +++ b/requirements/local.txt @@ -0,0 +1,6 @@ +# Local development dependencies go here +-r base.txt +coverage==3.7.1 +Sphinx==1.2.3 +sqlparse==0.1.14 +releases==0.7.0 diff --git a/requirements/production.txt b/requirements/production.txt new file mode 100644 index 0000000..696dc7c --- /dev/null +++ b/requirements/production.txt @@ -0,0 +1,3 @@ +# Pro-tip: Try not to put anything here. There should be no dependency in +# production that isn't in development. +-r base.txt diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 0000000..bb78fde --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,3 @@ +# Test dependencies go here. +-r base.txt +coverage==3.7.1 From a513331ebce53c6c20a3e415806f4ce27b2b3683 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 8 Jan 2015 20:32:32 +0100 Subject: [PATCH 04/13] add unimplemented pgsqltasks --- gvapgsql/pgsqltasks/__init__.py | 4 ++ gvapgsql/pgsqltasks/models.py | 4 ++ gvapgsql/pgsqltasks/tasks.py | 72 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 gvapgsql/pgsqltasks/__init__.py create mode 100644 gvapgsql/pgsqltasks/models.py create mode 100644 gvapgsql/pgsqltasks/tasks.py diff --git a/gvapgsql/pgsqltasks/__init__.py b/gvapgsql/pgsqltasks/__init__.py new file mode 100644 index 0000000..c49a650 --- /dev/null +++ b/gvapgsql/pgsqltasks/__init__.py @@ -0,0 +1,4 @@ +""" +This module contains :py:mod:`pgsqltasks.tasks`. + +""" diff --git a/gvapgsql/pgsqltasks/models.py b/gvapgsql/pgsqltasks/models.py new file mode 100644 index 0000000..3a43087 --- /dev/null +++ b/gvapgsql/pgsqltasks/models.py @@ -0,0 +1,4 @@ +""" +Empty models to make Django accept pgsqltasks as an app. + +""" diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py new file mode 100644 index 0000000..039b74a --- /dev/null +++ b/gvapgsql/pgsqltasks/tasks.py @@ -0,0 +1,72 @@ +""" +This module defines Celery_ tasks to manage PostgreSQL users and databases. + +""" +from __future__ import absolute_import + +from celery import shared_task + + +@shared_task +def create_pgsql_user(username, password): + """ + This task creates a new PostgreSQL user. + + :param str username: the user name + :param str password: the password + :return: the created user's name + :rtype: str + + """ + + +@shared_task +def set_pgsql_userpassword(username, password): + """ + Set a new password for an existing PostgreSQL user. + + :param str username: the user name + :param str password: the password + :return: True if the password could be set, False otherwise + :rtype: boolean + + """ + + +@shared_task +def delete_pgsql_user(username): + """ + This task deletes an existing PostgreSQL user. + + :param str username: the user name + :return: True if the user has been deleted, False otherwise + :rtype: boolean + + """ + + +@shared_task +def create_pgsql_database(dbname, username): + """ + This task creates a new PostgreSQL database for the given PostgreSQL user. + + :param str dbname: database name + :param str username: the user name of an existing PostgreSQL user + :return: the database name + :rtype: str + + """ + + +@shared_task +def delete_pgsql_database(dbname, username): + """ + This task deletes an existing PostgreSQL database and revokes privileges of + the given user on that database. + + :param str dbname: database name + :param str username: the user name of an existing PostgreSQL user + :return: True if the database has been deleted, False otherwise + :rtype: boolean + + """ From 85253a2cdaa6cb006f8650a58280c42f1859f28b Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 8 Jan 2015 20:34:18 +0100 Subject: [PATCH 05/13] add Celery application and settings --- gvapgsql/gvapgsql/__init__.py | 0 gvapgsql/gvapgsql/celery.py | 15 +++++++++++ gvapgsql/gvapgsql/settings.py | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 gvapgsql/gvapgsql/__init__.py create mode 100644 gvapgsql/gvapgsql/celery.py create mode 100644 gvapgsql/gvapgsql/settings.py diff --git a/gvapgsql/gvapgsql/__init__.py b/gvapgsql/gvapgsql/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gvapgsql/gvapgsql/celery.py b/gvapgsql/gvapgsql/celery.py new file mode 100644 index 0000000..a99dd76 --- /dev/null +++ b/gvapgsql/gvapgsql/celery.py @@ -0,0 +1,15 @@ +""" +This module defines the Celery_ app for gvapgsql. + +.. _Celery: http://www.celeryproject.org/ + +""" +from __future__ import absolute_import + +from celery import Celery + +#: The Celery application +app = Celery('gvapgsql') + +app.config_from_object('gvapgsql.settings') +app.autodiscover_tasks(['pgsqltasks'], force=True) diff --git a/gvapgsql/gvapgsql/settings.py b/gvapgsql/gvapgsql/settings.py new file mode 100644 index 0000000..5de01b4 --- /dev/null +++ b/gvapgsql/gvapgsql/settings.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# pymode:lint_ignore=E501 +""" +Common settings and globals. + +""" + +from os import environ + + +def get_env_setting(setting): + """ + Get the environment setting or return exception. + + :param str setting: name of an environment setting + :raises ImproperlyConfigured: if the environment setting is not defined + :return: environment setting value + :rtype: str + """ + try: + return environ[setting] + except KeyError: + error_msg = "Set the %s env variable" % setting + raise AssertionError(error_msg) + + +########## CELERY CONFIGURATION +CELERY_TIMEZONE = 'Europe/Berlin' +CELERY_ENABLE_UTC = True +CELERY_RESULT_BACKEND = 'amqp' +CELERY_RESULT_PERSISTENT = True +CELERY_TASK_RESULT_EXPIRES = None +CELERY_ROUTES = ( + 'gvacommon.celeryrouters.GvaRouter', +) +CELERY_ACCEPT_CONTENT = ['json'] +CELERY_TASK_SERIALIZER = 'json' +CELERY_RESULT_SERIALIZER = 'json' +BROKER_URL = get_env_setting('GVAPGSQL_BROKER_URL') +########## END CELERY CONFIGURATION + +########## GVAPGSQL CONFIGURATION +GVAPGSQL_DBADMIN_HOST = get_env_setting('GVAPGSQL_DBADMIN_HOST') +GVAPGSQL_DBADMIN_PORT = int(get_env_setting('GVAPGSQL_DBADMIN_PORT')) +GVAPGSQL_DBADMIN_USER = get_env_setting('GVAPGSQL_DBADMIN_USER') +GVAPGSQL_DBADMIN_PASSWORD = get_env_setting('GVAPGSQL_DBADMIN_PASSWORD') +########## END GVAPGSQL CONFIGURATION From 3fbf64566540450e4cf6cbbd67af5b114987ca64 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 9 Jan 2015 19:35:37 +0100 Subject: [PATCH 06/13] implement pgsqltasks --- gvapgsql/pgsqltasks/tasks.py | 64 +++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index 039b74a..e28c228 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -5,6 +5,23 @@ This module defines Celery_ tasks to manage PostgreSQL users and databases. from __future__ import absolute_import from celery import shared_task +from celery.utils.log import get_task_logger + +from gvapgsql import settings +from psycopg2 import connect + + +_LOGGER = get_task_logger(__name__) + + +def _get_connection(): + return connect( + host=settings.GVAPGSQL_DBADMIN_HOST, + port=settings.GVAPGSQL_DBADMIN_PORT, + user=settings.GVAPGSQL_DBADMIN_USER, + password=settings.GVAPGSQL_DBADMIN_PASSWORD, + database='postgres', + ) @shared_task @@ -18,6 +35,15 @@ def create_pgsql_user(username, password): :rtype: str """ + with _get_connection() as conn: + with conn.cursor() as curs: + curs.execute( + """ + CREATE USER %(username)s WITH PASSWORD %(password)s + """, + {'username': username, 'password': password} + ) + @shared_task @@ -31,6 +57,14 @@ def set_pgsql_userpassword(username, password): :rtype: boolean """ + with _get_connection() as conn: + with conn.cursor() as curs: + curs.execute( + """ + ALTER ROLE %(username)s WITH PASSWORD %(password)s + """, + {'username': username, 'password': password} + ) @shared_task @@ -43,6 +77,14 @@ def delete_pgsql_user(username): :rtype: boolean """ + with _get_connection() as conn: + with conn.cursor() as curs: + curs.execute( + """ + DROP ROLE %(username)s + """, + {'username': username} + ) @shared_task @@ -56,17 +98,31 @@ def create_pgsql_database(dbname, username): :rtype: str """ + with _get_connection() as conn: + with conn.cursor() as curs: + curs.execute( + """ + CREATE DATABASE %(dbname)s OWNER %(username)s + """, + {'dbname': dbname, 'username': username} + ) @shared_task -def delete_pgsql_database(dbname, username): +def delete_pgsql_database(dbname): """ - This task deletes an existing PostgreSQL database and revokes privileges of - the given user on that database. + This task deletes an existing PostgreSQL database. :param str dbname: database name - :param str username: the user name of an existing PostgreSQL user :return: True if the database has been deleted, False otherwise :rtype: boolean """ + with _get_connection() as conn: + with conn.cursor() as curs: + curs.execute( + """ + DROP DATABASE %(dbname)s + """, + {'dbname': dbname} + ) From 61221649905bc1579ad7050c2691284ae88429f7 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 9 Jan 2015 22:01:56 +0100 Subject: [PATCH 07/13] add identifier quoting --- gvapgsql/pgsqltasks/tasks.py | 45 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index e28c228..a089245 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -9,11 +9,46 @@ from celery.utils.log import get_task_logger from gvapgsql import settings from psycopg2 import connect +from psycopg2.extensions import ISQLQuote _LOGGER = get_task_logger(__name__) +class Ident(object): + """ + Wrap a PostgreSQL identifier. + + Inspired by + http://osdir.com/ml/python-db-psycopg-devel/2009-03/msg00019.html. + + Note that this adapter needs to make an SQL SELECT to correctly quote the + identifier (that is then cached) so it can be a good idea to pre-allocate + identifiers by calling getquoted() on the, before entering critical + sections of code. + """ + + def __init__(self, ident): + self.ident = ident + self.ident_quoted = None + + def prepare(self, conn): + self._conn = conn + + def getquoted(self): + if not self.ident_quoted: + with self._conn.cursor() as curs: + curs.execute("SELECT quote_ident(%s)", (self.ident,)) + return self.ident_quoted + + def __str__(self): + return str(self.ident_quoted) + + def __conform__(self, proto): + if proto == ISQLQuote: + return self + + def _get_connection(): return connect( host=settings.GVAPGSQL_DBADMIN_HOST, @@ -41,7 +76,7 @@ def create_pgsql_user(username, password): """ CREATE USER %(username)s WITH PASSWORD %(password)s """, - {'username': username, 'password': password} + {'username': Ident(username), 'password': password} ) @@ -63,7 +98,7 @@ def set_pgsql_userpassword(username, password): """ ALTER ROLE %(username)s WITH PASSWORD %(password)s """, - {'username': username, 'password': password} + {'username': Ident(username), 'password': password} ) @@ -83,7 +118,7 @@ def delete_pgsql_user(username): """ DROP ROLE %(username)s """, - {'username': username} + {'username': Ident(username)} ) @@ -104,7 +139,7 @@ def create_pgsql_database(dbname, username): """ CREATE DATABASE %(dbname)s OWNER %(username)s """, - {'dbname': dbname, 'username': username} + {'dbname': Ident(dbname), 'username': Ident(username)} ) @@ -124,5 +159,5 @@ def delete_pgsql_database(dbname): """ DROP DATABASE %(dbname)s """, - {'dbname': dbname} + {'dbname': Ident(dbname)} ) From 0b1249ed5d3f9ef791ef95a3f58b683b31068344 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 9 Jan 2015 22:12:51 +0100 Subject: [PATCH 08/13] add missing assignment --- gvapgsql/pgsqltasks/tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index a089245..8c11cde 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -39,6 +39,7 @@ class Ident(object): if not self.ident_quoted: with self._conn.cursor() as curs: curs.execute("SELECT quote_ident(%s)", (self.ident,)) + self.ident_quoted = curs.fetchone()[0] return self.ident_quoted def __str__(self): From 0ddf72b323466ef4bfe84136c7a38d020254d41f Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 10 Jan 2015 17:58:00 +0100 Subject: [PATCH 09/13] avoid transaction for CREATE and DROP database --- gvapgsql/pgsqltasks/tasks.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index 8c11cde..1683ff5 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -135,13 +135,14 @@ def create_pgsql_database(dbname, username): """ with _get_connection() as conn: - with conn.cursor() as curs: - curs.execute( - """ - CREATE DATABASE %(dbname)s OWNER %(username)s - """, - {'dbname': Ident(dbname), 'username': Ident(username)} - ) + conn.autocommit = True + curs = conn.cursor() + curs.execute( + """ + CREATE DATABASE %(dbname)s OWNER %(username)s + """, + {'dbname': Ident(dbname), 'username': Ident(username)} + ) @shared_task @@ -155,10 +156,11 @@ def delete_pgsql_database(dbname): """ with _get_connection() as conn: - with conn.cursor() as curs: - curs.execute( - """ - DROP DATABASE %(dbname)s - """, - {'dbname': Ident(dbname)} - ) + conn.autocommit = True + curs = conn.cursor() + curs.execute( + """ + DROP DATABASE %(dbname)s + """, + {'dbname': Ident(dbname)} + ) From 7ee5b7fc5f768dfa1a11a1bbc5c234bb01ae3833 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 10 Jan 2015 18:25:30 +0100 Subject: [PATCH 10/13] create databases with UTF8 encoding --- gvapgsql/pgsqltasks/tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index 1683ff5..7e70157 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -140,6 +140,7 @@ def create_pgsql_database(dbname, username): curs.execute( """ CREATE DATABASE %(dbname)s OWNER %(username)s + TEMPLATE template0 ENCODING UTF8 """, {'dbname': Ident(dbname), 'username': Ident(username)} ) From 1cf370f4aee85c27f638686b49b0304265548b94 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 10 Jan 2015 18:27:49 +0100 Subject: [PATCH 11/13] add missing quotes to encoding --- gvapgsql/pgsqltasks/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gvapgsql/pgsqltasks/tasks.py b/gvapgsql/pgsqltasks/tasks.py index 7e70157..5fcf861 100644 --- a/gvapgsql/pgsqltasks/tasks.py +++ b/gvapgsql/pgsqltasks/tasks.py @@ -140,7 +140,7 @@ def create_pgsql_database(dbname, username): curs.execute( """ CREATE DATABASE %(dbname)s OWNER %(username)s - TEMPLATE template0 ENCODING UTF8 + TEMPLATE template0 ENCODING 'UTF8' """, {'dbname': Ident(dbname), 'username': Ident(username)} ) From 6ce322cecc859559ce8db271f8bdddd861dd7560 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 10 Jan 2015 18:33:00 +0100 Subject: [PATCH 12/13] set version number, add changelog entry --- docs/changelog.rst | 2 ++ docs/conf.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 15a0c50..89d5688 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,4 +1,6 @@ Changelog ========= +* :release:`0.1.0 <2015-01-10>` +* :feature:`-` provide functionality to create and delete PostgreSQL users and databases * :feature:`-` initial project setup diff --git a/docs/conf.py b/docs/conf.py index bd9cefb..d860ade 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,9 +54,9 @@ copyright = u'2015 Jan Dittberner' # built documents. # # The short X.Y version. -version = '0.0' +version = '0.1' # The full version, including alpha/beta/rc tags. -release = '0.0.0' +release = '0.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From be38e74ffbe74a61a5883f849bae32c8516b84b9 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 10 Jan 2015 18:36:49 +0100 Subject: [PATCH 13/13] define required environment variables for docs build --- docs/conf.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index d860ade..887623f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,6 +20,12 @@ import os # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath(os.path.join('..', 'gvapgsql'))) +os.environ['GVAPGSQL_BROKER_URL'] = 'amqp://localhost' +os.environ['GVAPGSQL_DBADMIN_HOST'] = 'localhost' +os.environ['GVAPGSQL_DBADMIN_PORT'] = '5432' +os.environ['GVAPGSQL_DBADMIN_USER'] = 'gvapgsql' +os.environ['GVAPGSQL_DBADMIN_PASSWORD'] = 'gvapgsql' + # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here.