From beb19b9277bece30cafbb67aa9b347f0288fab3f Mon Sep 17 00:00:00 2001 From: James Molet Date: May 22 2018 15:07:43 +0000 Subject: adding docker compose --- diff --git a/docker/client_secrets.json b/docker/client_secrets.json new file mode 100644 index 0000000..1b0dd62 --- /dev/null +++ b/docker/client_secrets.json @@ -0,0 +1,11 @@ +{ + "web": { + "redirect_uris": ["http://localhost:5004/"], + "token_uri": "https://iddev.fedorainfracloud.org/openidc/Token", + "auth_uri": "https://iddev.fedorainfracloud.org/openidc/Authorization", + "client_id": "D-e69a1ac7-30fa-4d18-9001-7468c4f34c3c", + "client_secret": "qgz8Bzjg6nO7JWCXoB0o8L49KfI5atLF", + "userinfo_uri": "https://iddev.fedorainfracloud.org/openidc/UserInfo", + "token_introspection_uri": "https://iddev.fedorainfracloud.org/openidc/TokenInfo" + } +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..080333e --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,69 @@ +version: '2.1' +services: + rdb: + image: postgres:9.5.2 + restart: always + environment: + POSTGRES_USER: resultsdb + POSTGRES_PASSWORD: resultsdb + POSTGRES_DB: resultsdb + POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 30s + retries: 3 + + resultsdb: + image: "docker-registry.engineering.redhat.com/factory2/resultsdb:latest" + volumes: + - ./resultsdb-settings.py:/etc/resultsdb/settings.py:ro,Z + - ./resultsdb.conf:/etc/httpd/conf.d/resultsdb.conf:ro,Z + ports: + - 5001:5001 + depends_on: + rdb: + condition: service_healthy + + wdb: + image: postgres:9.5.2 + restart: always + environment: + POSTGRES_USER: waiverdb + POSTGRES_PASSWORD: waiverdb + POSTGRES_DB: waiverdb + POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + + waiverdb: + image: "docker-registry.engineering.redhat.com/factory2/waiverdb:latest" + environment: + DATABASE_PASSWORD: waiverdb + SECRET_KEY: waiverdb + entrypoint: /bin/sh -i -c "waiverdb wait-for-db && waiverdb db upgrade && python3-gunicorn --bind 0.0.0.0:5004 --access-logfile=- waiverdb.wsgi:app" + volumes: + - ./waiverdb-settings.py:/etc/waiverdb/settings.py:ro,Z + - ./client_secrets.json:/etc/secret/client_secrets.json:ro,Z + ports: + - 5004:5004 + user: '0' + depends_on: + - wdb + + gmemcached: + image: "docker.io/modularitycontainers/memcached" + + greenwave: + image: "quay.io/factory2/greenwave:latest" + volumes: + - ./greenwave-settings.py:/etc/greenwave/settings.py:ro,Z + - ../conf/policies/:/etc/greenwave/policies/:ro,Z + depends_on: + - gmemcached + - resultsdb + - waiverdb + ports: + - 8080:8080 + +networks: + default: + driver: bridge diff --git a/docker/greenwave-settings.py b/docker/greenwave-settings.py new file mode 100644 index 0000000..dcd489d --- /dev/null +++ b/docker/greenwave-settings.py @@ -0,0 +1,17 @@ +SECRET_KEY = 'greenwave' +HOST = '0.0.0.0' +PORT = 8080 +DEBUG = False +POLICIES_DIR = '/etc/greenwave/policies/' +WAIVERDB_API_URL = 'http://waiverdb:5004/api/v1.0' +RESULTSDB_API_URL = 'http://resultsdb:5001/api/v2.0' +CACHE = { + # 'backend': "dogpile.cache.null", + 'backend': "dogpile.cache.memcached", + 'expiration_time': 1, # 1 is 1 second, keep to see that memcached + # service is working + 'arguments': { + 'url': 'gmemcached:11211', + 'distributed_lock': True + } +} diff --git a/docker/resultsdb-settings.py b/docker/resultsdb-settings.py new file mode 100644 index 0000000..85471e1 --- /dev/null +++ b/docker/resultsdb-settings.py @@ -0,0 +1,11 @@ +SECRET_KEY = 'resultsdb' +SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://resultsdb:resultsdb@rdb:5432/resultsdb' +FILE_LOGGING = False +LOGFILE = '/var/log/resultsdb/resultsdb.log' +SYSLOG_LOGGING = False +STREAM_LOGGING = True +RUN_HOST= '0.0.0.0' +RUN_PORT = 5001 +MESSAGE_BUS_PUBLISH = False +MESSAGE_BUS_PLUGIN = 'fedmsg' +MESSAGE_BUS_KWARGS = {'modname': 'resultsdb'} diff --git a/docker/waiverdb-settings.py b/docker/waiverdb-settings.py new file mode 100644 index 0000000..3d4d568 --- /dev/null +++ b/docker/waiverdb-settings.py @@ -0,0 +1,9 @@ +DATABASE_URI = 'postgresql+psycopg2://waiverdb:waiverdb@wdb/waiverdb' +HOST = '0.0.0.0' +PORT = 5004 +#AUTH_METHOD = 'OIDC' +AUTH_METHOD = 'dummy' +MESSAGE_BUS_PUBLISH = False +SUPERUSERS = ['dummy'] +#OIDC_CLIENT_SECRETS = '/etc/secret/client_secrets.json' +RESULTSDB_API_URL = 'http://resultsdb:5001/api/v2.0' diff --git a/docs/dev-guide.rst b/docs/dev-guide.rst index d3ea10f..f60c478 100644 --- a/docs/dev-guide.rst +++ b/docs/dev-guide.rst @@ -55,6 +55,16 @@ The functional tests assume you have ResultsDB and WaiverDB git checkouts in find them in a different location by passing ``RESULTSDB`` or ``WAIVERDB`` environment variables. +Docker Compose +============== + +For development you may want to bring up quick instances of Greenwave / +WaiverDB / ResultsDB / all of the above. For more information on that see: + +.. toctree:: + :maxdepth: 2 + + docker-compose Building the documentation ========================== diff --git a/docs/docker-compose.rst b/docs/docker-compose.rst new file mode 100644 index 0000000..b65a4f9 --- /dev/null +++ b/docs/docker-compose.rst @@ -0,0 +1,207 @@ +Docker-compose for greenwave +=========================================== + +Rationale +--------- + +I was tasked with getting the functional greenwave tests working with +remote deployed servers in openshift.  During this task I ran into many +bugs and it was hard to determine where the errors were happening.  I +had to tackle errors simultaneously in openshift, my greenwave patches, +the other services greenwave depends on, their dependencies, and the +general issues with stuffing things into containers.  In its current +state I see two extremes of developing:  1) running everything manually +on your bare metal machines, 2) running a full deployment in openshift +using the existing templates.  I needed a nice middle ground that let me +iterate my changes quickly and isolate complexities to zero in on these +bugs.  I found that docker-compose is a great solution to this. + +What is docker-compose +---------------------- + +There are many online resources explaining how to use this tool but I +like to explain its purpose through its history.  Before kubernetes or +indeed any docker's management tools were invented, you only had +docker's cli.  As the complexity of a microservice topology +increased, you started to have these increasingly longer docker commands +that had to be run in a certain order.  They were usually stuffed in a +bash script somewhere.  Version 0 of docker-compose was a simple python +program that parsed a developer friendly yaml describing a toplogy into +these commands.  With version 1, docker upstream picked up the project +and bought it to feature parity with docker cli.  With version 2 they +made use of the [then] new docker api, and added useful features such as +health checks on containers.  Finally with version 3, they redesigned +everything to be consistent with the docker-verse, and added docker +swarm functionality which lets you deploy these compositions to a remote +server. + +Where it fits into our current container usage +---------------------------------------------- + +With version 3 of docker-compose its use case overlaps with the things +openshift currently does.  However I think its greatest utility lies +along its original intention of being a great developer tool. It allows +you to bring up many containers quickly and easily on your local +machine.  I think it can co-exist with openshift as openshift gives you +everything you need to run containers in a self contained environment +and  it handles production concerns such as user and access management.  +Docker-compose, on the other hand, provides bare-bone containers, and is +potentially much easier to use. + +To illuminate this fact consider our openshift templates, as of this +writing, require over 819 lines of code to deploy six containers; to +launch them today you need to run a series of commands such as:  + +**maximum openshift** + +.. code-block:: console + + oc process -f resultsdb/openshift/resultsdb-test-template.yaml -p TEST_ID=123 -p RESULTSDB_IMAGE=docker-registry.engineering.redhat.com/csomh/resultsdb:latest | oc apply -f - && + oc process -f waiverdb/openshift/waiverdb-test-template.yaml -p TEST_ID=123 -p WAIVERDB_APP_VERSION=latest | oc apply -f - && + oc process -f greenwave/openshift/greenwave-test-template.yaml -p TEST_ID=123 -p GREENWAVE_IMAGE=quay.io/factory2/greenwave:latest | oc apply -f + +In comparison, this same thing is accomplished with a single +docker-compose.yml in about 70 lines with the command +``docker-compose up``.  This is because openshift templates are based +off of kubernetes manifests.  These manifests are a direct dump of the +state of a current running kubernetes and it contains mappings to all +the objects needed in order to migrate between instances.  Due to that +fact I don't think manifests were designed with ease of use in mind. +Kubernetes itself has another project that aims to solve this developer +usage called Charts.  + +Quick How To +------------ + +Installation +~~~~~~~~~~~~ + +To run docker-compose you need to be able to run the regular docker +command line.  Once you have that working you can install compose with: + +``{yum|dnf|brew} install docker-compose`` + +You now can write a docker-compose.yml.  See the `docker-compose reference`_ +for a full description, but for the purposes of greenwave I will +use the example files in \ ``greenwave/docker/``. + +The first thing you will notice is that each of the +resultsdb/waiverdb/greenwave configs are in separate files and not +in-lined into the template.  This means you can edit them quickly in +your favorite editor with the correct syntax highlighting, and not have +to worry about conflicting yaml indentation or any weird jinja snafus as +you would in an openshift template. + +docker-compose.yml format +~~~~~~~~~~~~~~~~~~~~~~~~~ + +First section of the file is the version. + +**docker-compose.yml** + +.. code-block:: yaml + + version: '2.1' + +I selected this version because it gives me a little more control +over local running containers (health checks) and I don't need the docker +swarm functionality of version 3. + +**docker-compose-yml** + +.. code-block:: yaml + + services: + rdb: + image: postgres:9.5.2 + restart: always + environment: + POSTGRES_USER: resultsdb + POSTGRES_PASSWORD: resultsdb + POSTGRES_DB: resultsdb + POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 30s + retries: 3 + +This defines what containers are run.  The first container, \ ``rdb``, is +an off the shelf postgres from the docker hub.  It is set to restart +itself on failures, and it has some basic settings which are set through +environment variables as is docker best practice.  It also has a simple +health check which is shell command that checks if a postgres server is +running.  Note that the this container is "pingable" from any other +container simply by running: ``ping rdb``.  + +**docker-compose.yml** + +.. code-block:: yaml + + resultsdb: + image: "docker-registry.engineering.redhat.com/factory2/resultsdb:latest" + volumes: + - ./resultsdb-settings.py:/etc/resultsdb/settings.py:ro,Z + - ./resultsdb.conf:/etc/httpd/conf.d/resultsdb.conf:ro,Z + ports: + - 5001:5001 + depends_on: + rdb: + condition: service_healthy + +  + +The second service is ``resultsdb``.  Its running our own built +resultsdb image.  Note here that we don't have to actually push an image +anywhere, we can reuse a local image simply by supplying the appropriate +name.  We are mounting resultsdb's config files in as volumes.  The +config files are at the same level as there docker-compose.yml, and they +are being mounted to the proper locations on the resultsdb server.  The +ports section here simply exposes port 5001 to my development box's +5001.  This means resultsdb is reachable from my own terminal +at \ ``localhost:5001``.   Finally this service depends on its database, +and the \ ``depends_on`` directive tells docker-compose to always start +the rdb container first, and in this case, wait for it to boot properly +before starting resultsdb. + +This continues on for the waiverdb and greenwave services, and I will +omit their walk through for brevity, unless someone asks. + +Using docker-compose +~~~~~~~~~~~~~~~~~~~~ + +Here is my selection of useful docker-compose commands.  There are many +more and you can do most the things regular docker gives you. + +**docker-compose cli** + +.. code-block:: console + + # start in the right directory + cd wherever/greenwave/docker/ + + # give me all services + docker-compose up + + # run the services as a daemon in the background + docker-compose up -d + + # kill everything + docker-compose down + + # give me just a resultsdb and a waiverdb and their dependent services + docker-compose up resultsdb waiverdb + + # screw it, give me a bash shell on the waiverdb so I can poke things + docker-compose exec waiverdb /bin/bash + + # give me the a log of all the greenwave events + docker-compose logs greenwave + +If you were for example developing greenwave and running it on your own +(invoking it manually) you might try setting +``WAIVERDB_API_URL = 'http://localhost:5004/api/v1.0'`` and +``RESULTSDB_API_URL = 'http://localhost:5001/api/v2.0'`` and then +running: ``docker-compose up -d resultsdb waiverdb`` + +.. _docker-compose reference: https://docs.docker.com/compose/compose-file/compose-file-v2/ \ No newline at end of file diff --git a/functional-tests/conftest.py b/functional-tests/conftest.py index 5774b49..504ffe2 100644 --- a/functional-tests/conftest.py +++ b/functional-tests/conftest.py @@ -162,7 +162,9 @@ def greenwave_server(tmpdir_factory, resultsdb_server, waiverdb_server): 'expiration_time': 300, 'arguments': {'filename': %r}, } - """ % cache_file.strpath)) + RESULTSDB_API_URL = '%sapi/v2.0' + WAIVERDB_API_URL = '%sapi/v1.0' + """ % (cache_file.strpath, resultsdb_server, waiverdb_server))) # We also update the config file for *this* process, as well as the server subprocess, # because the fedmsg consumer tests actually invoke the handler code in-process.