From 857572288216387c2288f50531ed927b06207943 Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Thu, 11 Dec 2014 17:57:23 +0000 Subject: Make mason.configure install the new Mason config --- mason.configure | 139 ++++++++++++++++++++++------------- zuul/10-dhcp.network | 5 ++ zuul/ansible/hosts | 1 + zuul/ansible/mason-setup.yml | 117 +++++++++++++++++++++++++++++ zuul/lighttpd.service | 10 +++ zuul/mason-setup.service | 16 ++++ zuul/os-init-script | 6 ++ zuul/share/lighttpd.conf | 24 ++++++ zuul/share/os.conf | 30 ++++++++ zuul/share/turbo-hipster-config.yaml | 47 ++++++++++++ zuul/share/zuul-layout.yaml | 23 ++++++ zuul/share/zuul-logging.conf | 44 +++++++++++ zuul/share/zuul.conf | 26 +++++++ zuul/turbo-hipster.service | 10 +++ zuul/zuul-merger.service | 10 +++ zuul/zuul-server.service | 10 +++ 16 files changed, 467 insertions(+), 51 deletions(-) create mode 100644 zuul/10-dhcp.network create mode 100644 zuul/ansible/hosts create mode 100644 zuul/ansible/mason-setup.yml create mode 100644 zuul/lighttpd.service create mode 100644 zuul/mason-setup.service create mode 100644 zuul/os-init-script create mode 100644 zuul/share/lighttpd.conf create mode 100755 zuul/share/os.conf create mode 100644 zuul/share/turbo-hipster-config.yaml create mode 100644 zuul/share/zuul-layout.yaml create mode 100644 zuul/share/zuul-logging.conf create mode 100644 zuul/share/zuul.conf create mode 100644 zuul/turbo-hipster.service create mode 100644 zuul/zuul-merger.service create mode 100644 zuul/zuul-server.service diff --git a/mason.configure b/mason.configure index 1198ebd0..78212d2d 100644 --- a/mason.configure +++ b/mason.configure @@ -19,16 +19,34 @@ # a Mason instance at deployment time. It uses the following variables # from the environment: # +# * TROVE_ID +# * TROVE_HOST # * ARTIFACT_CACHE_SERVER +# +# * GERRIT_USER +# * GERRIT_HOSTNAME +# * GERRIT_HTTP_PORT +# * GERRIT_GIT_PORT +# * GERRIT_SSH_KEY +# * GERRIT_SSH_KEY_PATH +# +# * GEARMAN_HOST +# * GEARMAN_PORT +# * START_GEARMAN +# # * MASON_CLUSTER_MORPHOLOGY -# * MASON_DEFINITIONS_REF -# * MASON_DISTBUILD_ARCH -# * MASON_TEST_HOST +# * MASON_ARCHITECTURE +# * MASON_TEST_HOSTS +# * MASON_DISTBUILD_CONTROLLERS +# * MASON_TEST_INFRASTRUCTURE_TYPE +# * MASON_UPSTREAM_TROVE +# # * OPENSTACK_NETWORK_ID -# * TEST_INFRASTRUCTURE_TYPE -# * TROVE_HOST -# * TROVE_ID -# * CONTROLLERHOST +# * OPENSTACK_USER +# * OPENSTACK_PASSWORD +# * OPENSTACK_TENANT_ID +# * OPENSTACK_TENANT_NAME +# * OPENSTACK_AUTH_URL set -e @@ -39,27 +57,26 @@ set -e ROOT="$1" mkdir -p "$ROOT"/usr/lib/mason -cp mason/mason.sh "$ROOT"/usr/lib/mason/mason.sh -cp mason/mason-report.sh "$ROOT"/usr/lib/mason/mason-report.sh -cp mason/os-init-script "$ROOT"/usr/lib/mason/os-init-script +cp zuul/os-init-script "$ROOT"/usr/lib/mason/os-init-script -cp mason/mason.timer "$ROOT"/etc/systemd/system/mason.timer +cp zuul/mason-setup.service "$ROOT"/etc/systemd/system/mason-setup.service +cp zuul/zuul-server.service "$ROOT"/etc/systemd/system/zuul-server.service +cp zuul/zuul-merger.service "$ROOT"/etc/systemd/system/zuul-merger.service +cp zuul/turbo-hipster.service "$ROOT"/etc/systemd/system/turbo-hipster.service +cp zuul/lighttpd.service "$ROOT"/etc/systemd/system/lighttpd.service -cp mason/mason.service "$ROOT"/etc/systemd/system/mason.service + +# HACK AROUND BAD SYSTEMD +cp zuul/10-dhcp.network "$ROOT"/etc/systemd/network/10-dhcp.network + ########################################################################## -# Set up httpd web server +# Create required directories ########################################################################## -cp mason/httpd.service "$ROOT"/etc/systemd/system/httpd.service - -mkdir -p "$ROOT"/srv/mason - -cat >>"$ROOT"/etc/httpd.conf <"$MASON_DATA/mason.conf" import os, sys, yaml mason_configuration={ - 'ARTIFACT_CACHE_SERVER': os.environ['ARTIFACT_CACHE_SERVER'], - 'MASON_CLUSTER_MORPHOLOGY': os.environ['MASON_CLUSTER_MORPHOLOGY'], - 'MASON_DEFINITIONS_REF': os.environ['MASON_DEFINITIONS_REF'], - 'MASON_DISTBUILD_ARCH': os.environ['MASON_DISTBUILD_ARCH'], - 'MASON_TEST_HOST': os.environ['MASON_TEST_HOST'], - 'OPENSTACK_NETWORK_ID': os.environ['OPENSTACK_NETWORK_ID'], - 'TEST_INFRASTRUCTURE_TYPE': os.environ['TEST_INFRASTRUCTURE_TYPE'], 'TROVE_ID': os.environ['TROVE_ID'], 'TROVE_HOST': os.environ['TROVE_HOST'], - 'CONTROLLERHOST': os.environ['CONTROLLERHOST'], + 'ARTIFACT_CACHE_SERVER': os.environ['ARTIFACT_CACHE_SERVER'], + 'GERRIT_USER': os.environ['GERRIT_USER'], + 'GERRIT_HOSTNAME': os.environ['GERRIT_HOSTNAME'], + 'GERRIT_HTTP_PORT': os.environ['GERRIT_HTTP_PORT'], + 'GERRIT_GIT_PORT': os.environ['GERRIT_GIT_PORT'], + 'GERRIT_SSH_KEY_PATH': os.environ['GERRIT_SSH_KEY_PATH'], + 'GEARMAN_HOST': os.environ['GEARMAN_HOST'], + 'GEARMAN_PORT': os.environ['GEARMAN_PORT'], + 'START_GEARMAN': os.environ['START_GEARMAN'], + 'MASON_CLUSTER_MORPHOLOGY': os.environ['MASON_CLUSTER_MORPHOLOGY'], + 'MASON_ARCHITECTURE': os.environ['MASON_ARCHITECTURE'], + 'MASON_TEST_HOSTS': os.environ['MASON_TEST_HOSTS'], + 'MASON_DISTBUILD_CONTROLLERS': os.environ['MASON_DISTBUILD_CONTROLLERS'], + 'MASON_TEST_INFRASTRUCTURE_TYPE': os.environ['MASON_TEST_INFRASTRUCTURE_TYPE'], + 'MASON_UPSTREAM_TROVE': os.environ['MASON_UPSTREAM_TROVE'], } yaml.dump(mason_configuration, sys.stdout, default_flow_style=False) EOF -if [ "$TEST_INFRASTRUCTURE_TYPE" = "openstack" ]; then +if [ "$MASON_TEST_INFRASTRUCTURE_TYPE" = "openstack" ]; then python <<'EOF' >>"$MASON_DATA/mason.conf" import os, sys, yaml openstack_credentials={ + 'OPENSTACK_NETWORK_ID': os.environ['OPENSTACK_NETWORK_ID'], 'OS_USERNAME': os.environ['OPENSTACK_USER'], 'OS_TENANT_NAME': os.environ['OPENSTACK_TENANT'], 'OS_TENANT_ID': os.environ['OPENSTACK_TENANT_ID'], @@ -144,10 +188,3 @@ openstack_credentials={ yaml.dump(openstack_credentials, sys.stdout, default_flow_style=False) EOF fi - -########################################################################## -# Enable services -########################################################################## - -ln -s ../mason.timer "$ROOT"/etc/systemd/system/multi-user.target.wants/mason.timer -ln -s ../httpd.service "$ROOT"/etc/systemd/system/multi-user.target.wants/httpd.service diff --git a/zuul/10-dhcp.network b/zuul/10-dhcp.network new file mode 100644 index 00000000..93dc1c5d --- /dev/null +++ b/zuul/10-dhcp.network @@ -0,0 +1,5 @@ +[Match] +Name=eth* + +[Network] +DHCP=yes diff --git a/zuul/ansible/hosts b/zuul/ansible/hosts new file mode 100644 index 00000000..5b97818d --- /dev/null +++ b/zuul/ansible/hosts @@ -0,0 +1 @@ +localhost ansible_connection=local diff --git a/zuul/ansible/mason-setup.yml b/zuul/ansible/mason-setup.yml new file mode 100644 index 00000000..1f9babc6 --- /dev/null +++ b/zuul/ansible/mason-setup.yml @@ -0,0 +1,117 @@ +--- +- hosts: localhost + vars_files: + - "/etc/mason/mason.conf" + tasks: + + - fail: msg='TROVE_ID is mandatory' + when: TROVE_ID is not defined + + - fail: msg='TROVE_HOST is mandatory' + when: TROVE_HOST is not defined + + - fail: msg='ARTIFACT_CACHE_SERVER is mandatory' + when: ARTIFACT_CACHE_SERVER is not defined + + - fail: msg='GERRIT_USER is mandatory' + when: GERRIT_USER is not defined + + - fail: msg='GERRIT_HOSTNAME is mandatory' + when: GERRIT_HOSTNAME is not defined + + - fail: msg='GERRIT_HTTP_PORT is mandatory' + when: GERRIT_HTTP_PORT is not defined + + - fail: msg='GERRIT_GIT_PORT is mandatory' + when: GERRIT_GIT_PORT is not defined + + - fail: msg='GERRIT_SSH_KEY_PATH is mandatory' + when: GERRIT_SSH_KEY_PATH is not defined + + - fail: msg='GEARMAN_HOST is mandatory' + when: GEARMAN_HOST is not defined + + - fail: msg='GEARMAN_PORT is mandatory' + when: GEARMAN_PORT is not defined + + - fail: msg='START_GEARMAN is mandatory' + when: START_GEARMAN is not defined + + - fail: msg='MASON_CLUSTER_MORPHOLOGY is mandatory' + when: MASON_CLUSTER_MORPHOLOGY is not defined + + - fail: msg='MASON_ARCHITECTURE is mandatory' + when: MASON_ARCHITECTURE is not defined + + - fail: msg='MASON_TEST_HOSTS is mandatory' + when: MASON_TEST_HOSTS is not defined + + - fail: msg='MASON_DISTBUILD_CONTROLLERS is mandatory' + when: MASON_DISTBUILD_CONTROLLERS is not defined + + - fail: msg='MASON_TEST_INFRASTRUCTURE_TYPE is mandatory' + when: MASON_TEST_INFRASTRUCTURE_TYPE is not defined + + - fail: msg='MASON_UPSTREAM_TROVE is mandatory' + when: MASON_UPSTREAM_TROVE is not defined + + - fail: msg='OPENSTACK_NETWORK_ID is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OPENSTACK_NETWORK_ID is not defined + + - fail: msg='OS_USERNAME is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OS_USERNAME is not defined + + - fail: msg='OS_PASSWORD is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OS_PASSWORD is not defined + + - fail: msg='OS_TENANT_ID is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OS_TENANT_ID is not defined + + - fail: msg='OS_TENANT_NAME is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OS_TENANT_NAME is not defined + + - fail: msg='OS_AUTH_URL is mandatory when MASON_TEST_INFRASTRUCTURE_TYPE=openstack' + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" and OS_AUTH_URL is not defined + + - name: Create required configuration files + template: src=/usr/share/mason-setup/{{ item }} dest=/etc/{{ item }} + with_items: + - zuul.conf + - turbo-hipster-config.yaml + - lighttpd.conf + - zuul-layout.yaml + - zuul-logging.conf + + - name: Create the OpenStack credentials file + template: src=/usr/share/mason-setup/{{ item }} dest=/etc/{{ item }} + with_items: + - os.conf + when: MASON_TEST_INFRASTRUCTURE_TYPE == "openstack" + + - name: Enable the zuul-server service + service: name=zuul-server.service enabled=yes + register: zuul_server_service + - name: Restart the zuul-server service + service: name=zuul-server.service state=restarted + when: zuul_server_service|changed + + - name: Enable the zuul-merger service + service: name=zuul-merger.service enabled=yes + register: zuul_merger_service + - name: Restart the zuul-merger service + service: name=zuul-merger.service state=restarted + when: zuul_merger_service|changed + + - name: Enable the turbo-hipster service + service: name=turbo-hipster.service enabled=yes + register: turbo_hipster_service + - name: Restart the turbo-hipster service + service: name=turbo-hipster.service state=restarted + when: turbo_hipster_service|changed + + - name: Enable the lighttpd service + service: name=lighttpd.service enabled=yes + register: lighttpd_service + - name: Restart the lighttpd service + service: name=lighttpd.service state=restarted + when: lighttpd_service|changed diff --git a/zuul/lighttpd.service b/zuul/lighttpd.service new file mode 100644 index 00000000..2c9d2a19 --- /dev/null +++ b/zuul/lighttpd.service @@ -0,0 +1,10 @@ +[Unit] +Description=HTTP server for Mason +After=network.target + +[Service] +User=root +ExecStart=/usr/sbin/lighttpd -f /etc/lighttpd.conf + +[Install] +WantedBy=multi-user.target diff --git a/zuul/mason-setup.service b/zuul/mason-setup.service new file mode 100644 index 00000000..60403bde --- /dev/null +++ b/zuul/mason-setup.service @@ -0,0 +1,16 @@ +[Unit] +Description=Run mason-setup Ansible scripts +Requires=network.target +After=network.target +Requires=opensshd.service +After=opensshd.service + +# If there's a shared /var subvolume, it must be mounted before this +# unit runs. +Requires=local-fs.target +After=local-fs.target + +ConditionPathExists=/etc/mason/mason.conf + +[Service] +ExecStart=/usr/bin/ansible-playbook -v -i /usr/lib/mason-setup/ansible/hosts /usr/lib/mason-setup/ansible/mason-setup.yml diff --git a/zuul/os-init-script b/zuul/os-init-script new file mode 100644 index 00000000..77afb926 --- /dev/null +++ b/zuul/os-init-script @@ -0,0 +1,6 @@ +#!/bin/bash + +# This allows the test runner to know that cloud-init has completed the +# disc resizing, and there is enough free space to continue. +touch /root/cloud-init-finished + diff --git a/zuul/share/lighttpd.conf b/zuul/share/lighttpd.conf new file mode 100644 index 00000000..3d2ce72a --- /dev/null +++ b/zuul/share/lighttpd.conf @@ -0,0 +1,24 @@ +server.document-root = "/var/www/" + +server.port = 80 + +server.username = "www" +server.groupname = "www" + +mimetype.assign = ( + ".html" => "text/html", + ".txt" => "text/plain", + ".log" => "text/plain", + ".jpg" => "image/jpeg", + ".png" => "image/png" +) + +static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" ) +index-file.names = ( "index.html" ) + +$HTTP["host"] == "127.0.0.1" { + server.document-root = "/var/www/" + $HTTP["url"] =~ "^/logs/" { + dir-listing.activate = "enable" + } +} diff --git a/zuul/share/os.conf b/zuul/share/os.conf new file mode 100755 index 00000000..21ef398c --- /dev/null +++ b/zuul/share/os.conf @@ -0,0 +1,30 @@ +#!/bin/bash + +# A version of this file with the relevant information included can be +# obtained by navigating to 'Access & Security' -> 'API Access' -> +# 'Download OpenStack RC file' in The Horizon web interface of your +# OpenStack. However, the file obtained from there sets OS_PASSWORD +# such that it will ask the user for a password, so you will need to +# change that for Mason to work automatically. +# +# With the addition of Keystone, to use an openstack cloud you should +# authenticate against keystone, which returns a **Token** and **Service +# Catalog**. The catalog contains the endpoint for all services the +# user/tenant has access to - including nova, glance, keystone, swift. +# +# *NOTE*: Using the 2.0 *auth api* does not mean that compute api is 2.0. We +# will use the 1.1 *compute api* +export OS_AUTH_URL={{ OS_AUTH_URL|quote }} + +# With the addition of Keystone we have standardized on the term **tenant** +# as the entity that owns the resources. +export OS_TENANT_ID={{ OS_TENANT_ID|quote }} +export OS_TENANT_NAME={{ OS_TENANT_NAME|quote }} + +# In addition to the owning entity (tenant), openstack stores the entity +# performing the action as the **user**. +export OS_USERNAME={{ OS_USERNAME|quote }} + +# With Keystone you pass the keystone password. +export OS_PASSWORD={{ OS_PASSWORD|quote }} + diff --git a/zuul/share/turbo-hipster-config.yaml b/zuul/share/turbo-hipster-config.yaml new file mode 100644 index 00000000..5402e365 --- /dev/null +++ b/zuul/share/turbo-hipster-config.yaml @@ -0,0 +1,47 @@ +zuul_server: + gerrit_site: "http://{{ GERRIT_HOSTNAME }}:{{ GERRIT_HTTP_PORT }}" + git_origin: "git://{{ GERRIT_HOSTNAME }}:{{ GERRIT_GIT_PORT }}" + gearman_host: "{{ GEARMAN_HOST }}" + gearman_port: "{{ GEARMAN_PORT }}" + +debug_log: /var/log/turbo-hipster/debug.log +jobs_working_dir: /var/lib/turbo-hipster/jobs +git_working_dir: /var/lib/turbo-hipster/git +pip_download_cache: /var/cache/pip + +plugins: + - name: build + function: build:build + import-path: mason.tests.build + location: /usr/share/system-tests/ + config: + trove-host: "{{ TROVE_HOST }}" + artifact-cache-server: "{{ ARTIFACT_CACHE_SERVER }}" + controllers: [ "{{ MASON_DISTBUILD_CONTROLLERS }}" ] + cluster-morphology: "{{ MASON_CLUSTER_MORPHOLOGY }}" + - name: build-test + function: build:build_test + import-path: mason.tests.build_test + location: /usr/share/system-tests/ + config: + trove-host: "{{ TROVE_HOST }}" + cluster-morphology: "{{ MASON_CLUSTER_MORPHOLOGY }}" + test-infrastructure-type: "{{ MASON_TEST_INFRASTRUCTURE_TYPE }}" + deployment-host: [ "{{ MASON_TEST_HOSTS }}" ] + trove-id: "{{ TROVE_ID }}" + openstack-network-id: "{{ OPENSTACK_NETWORK_ID }}" + - name: artifact-upload + function: build:artifact-upload + import-path: mason.tests.artifact_upload + location: /usr/share/system-tests/ + config: + artifact-cache-server: "{{ ARTIFACT_CACHE_SERVER }}" + cluster-morphology: "{{ MASON_CLUSTER_MORPHOLOGY }}" + architecture: "{{ MASON_ARCHITECTURE }}" + upstream-trove: "{{ MASON_UPSTREAM_TROVE }}" + upload-release-artifacts: False + +publish_logs: + type: local + path: /var/log/ + prepend_url: http://localhost/logs diff --git a/zuul/share/zuul-layout.yaml b/zuul/share/zuul-layout.yaml new file mode 100644 index 00000000..689c8219 --- /dev/null +++ b/zuul/share/zuul-layout.yaml @@ -0,0 +1,23 @@ +pipelines: + - name: check + manager: IndependentPipelineManager + trigger: + gerrit: + - event: patchset-created + success: + gerrit: + verified: 1 + failure: + gerrit: + verified: -1 + +jobs: + - name: ^.*-merge$ + failure-message: Unable to merge change, please rebase and try again. + +projects: + - name: definitions + check: + - build: + - build_test: + - artifact_upload diff --git a/zuul/share/zuul-logging.conf b/zuul/share/zuul-logging.conf new file mode 100644 index 00000000..8b76da26 --- /dev/null +++ b/zuul/share/zuul-logging.conf @@ -0,0 +1,44 @@ +[loggers] +keys=root,zuul,gerrit + +[handlers] +keys=console,debug,normal + +[formatters] +keys=simple + +[logger_root] +level=WARNING +handlers=console + +[logger_zuul] +level=DEBUG +handlers=debug,normal +qualname=zuul + +[logger_gerrit] +level=DEBUG +handlers=debug,normal +qualname=gerrit + +[handler_console] +level=WARNING +class=StreamHandler +formatter=simple +args=(sys.stdout,) + +[handler_debug] +level=DEBUG +class=logging.handlers.TimedRotatingFileHandler +formatter=simple +args=('/var/log/zuul/debug.log', 'midnight', 1, 30,) + +[handler_normal] +level=INFO +class=logging.handlers.TimedRotatingFileHandler +formatter=simple +args=('/var/log/zuul/zuul.log', 'midnight', 1, 30,) + +[formatter_simple] +format=%(asctime)s %(levelname)s %(name)s: %(message)s +datefmt= diff --git a/zuul/share/zuul.conf b/zuul/share/zuul.conf new file mode 100644 index 00000000..cf7c3793 --- /dev/null +++ b/zuul/share/zuul.conf @@ -0,0 +1,26 @@ +[gearman] +server={{ GEARMAN_HOST }} +port={{ GEARMAN_PORT }} + +[gearman_server] +start={{ START_GEARMAN }} + +[gerrit] +server={{ GERRIT_HOSTNAME }} +port={{ GERRIT_GIT_PORT }} +baseurl=http://{{ GERRIT_HOSTNAME }}:{{ GERRIT_HTTP_PORT }} +user={{ GERRIT_USER }} +sshkey={{ GERRIT_SSH_KEY_PATH }}.pub + +[zuul] +log_config=/etc/zuul-logging.conf +pidfile=/var/run/zuul/zuul.pid +state_dir=/var/lib/zuul +git_dir=/var/lib/zuul/git +status_url=http://127.0.0.1/logs + +[merger] +git_dir=/var/lib/zuul/git +git_user_email={{ GERRIT_USER }}@mason +git_user_name={{ GERRIT_USER }} +zuul_url=ssh://{{ GERRIT_USER }}@{{ GERRIT_HOSTNAME }}:{{ GERRIT_GIT_PORT }} diff --git a/zuul/turbo-hipster.service b/zuul/turbo-hipster.service new file mode 100644 index 00000000..20cde2ad --- /dev/null +++ b/zuul/turbo-hipster.service @@ -0,0 +1,10 @@ +[Unit] +Description=turbo-hipster: Test runner for Zuul +After=zuul-server.service + +[Service] +User=root +ExecStart=/bin/sh -c ". /etc/os.conf && /usr/bin/turbo-hipster -c /etc/turbo-hipster-config.yaml" + +[Install] +WantedBy=multi-user.target diff --git a/zuul/zuul-merger.service b/zuul/zuul-merger.service new file mode 100644 index 00000000..bc3eca21 --- /dev/null +++ b/zuul/zuul-merger.service @@ -0,0 +1,10 @@ +[Unit] +Description=Zuul Merger: Handles automated merging of changes +After=zuul-merger.service + +[Service] +User=root +ExecStart=/usr/bin/zuul-merger -d -c /etc/zuul.conf + +[Install] +WantedBy=multi-user.target diff --git a/zuul/zuul-server.service b/zuul/zuul-server.service new file mode 100644 index 00000000..dfc6436f --- /dev/null +++ b/zuul/zuul-server.service @@ -0,0 +1,10 @@ +[Unit] +Description=Zuul: CI orchestration and Gatekeeper +After=mason-setup.service + +[Service] +User=root +ExecStart=/usr/bin/zuul-server -d -c /etc/zuul.conf -l /etc/zuul-layout.yaml + +[Install] +WantedBy=multi-user.target -- cgit v1.2.1