blob: 141216b708b3915deac0cb2fa36eb48f51177fc2 [file] [log] [blame]
James E. Blairf09c2382018-02-08 16:50:31 -08001Zuul From Scratch
2=================
3
4.. note:: This is a work in progress that attempts to walk through all
5 of the steps needed to run Zuul on a cloud server against
6 GitHub projects.
7
8Environment Setup
9-----------------
10
11We're going to be using Fedora 27 on a cloud server for this
12installation.
13
14Login to your environment
15~~~~~~~~~~~~~~~~~~~~~~~~~
16
17Since we'll be using a cloud image for Fedora 27, our login user will
18be ``fedora`` which will also be the staging user for installation of
19Zuul and Nodepool.
20
21To get started, ssh to your machine as the ``fedora`` user::
22
23 ssh fedora@<ip_address>
24
25Environment Setup
26~~~~~~~~~~~~~~~~~
27
28::
29
30 sudo dnf update -y
31 sudo systemctl reboot
32 sudo dnf install git redhat-lsb-core python3 python3-pip python3-devel make gcc openssl-devel python-openstackclient -y
33 pip3 install --user bindep
34
35Zuul and Nodepool Installation
36------------------------------
37
38Install Zookeeper
39~~~~~~~~~~~~~~~~~
40
41::
42
43 sudo dnf install zookeeper -y
44
45Install Nodepool
46~~~~~~~~~~~~~~~~
47
48::
49
50 sudo adduser --system nodepool --home-dir /var/lib/nodepool --create-home
51 git clone https://git.openstack.org/openstack-infra/nodepool
52 cd nodepool/
53 sudo dnf -y install $(bindep -b)
54 sudo pip3 install .
55
56Install Zuul
57~~~~~~~~~~~~
58
59::
60
61 sudo adduser --system zuul --home-dir /var/lib/zuul --create-home
62 git clone https://git.openstack.org/openstack-infra/zuul
63 cd zuul/
64 sudo dnf install $(bindep -b) -y
65 sudo pip3 install git+https://github.com/sigmavirus24/github3.py.git@develop#egg=Github3.py
66 sudo pip3 install .
67
68Setup
69-----
70
71Zookeeper Setup
72~~~~~~~~~~~~~~~
73
74.. TODO recommended reading for zk clustering setup
75
76::
77
78 sudo bash -c 'echo "1" > /etc/zookeeper/myid'
79 sudo bash -c 'echo "tickTime=2000
80 dataDir=/var/lib/zookeeper
81 clientPort=2181" > /etc/zookeeper/zoo.cfg'
82
83Nodepool Setup
84~~~~~~~~~~~~~~
85
86Before starting on this, you need to download your `openrc`
87configuration from your OpenStack cloud. Put it on your server in the
88fedora user's home directory. It should be called
89``<username>-openrc.sh``. Once that is done, create a new keypair
90that will be installed when instantiating the servers::
91
92 cd ~
93 source <username>-openrc.sh # this will prompt for password - enter it
94 umask 0066
95
96 ssh-keygen -t rsa -b 2048 -f nodepool_rsa # don't enter a passphrase
97 openstack keypair create --public-key nodepool_rsa.pub nodepool
98
99We'll use the private key later wheen configuring Zuul. In the same
100session, configure nodepool to talk to your cloud::
101
102 sudo mkdir -p ~nodepool/.config/openstack
103 cat > clouds.yaml <<EOF
104 clouds:
105 mycloud:
106 auth:
107 username: $OS_USERNAME
108 password: $OS_PASSWORD
109 project_name: ${OS_PROJECT_NAME:-$OS_TENANT_NAME}
110 auth_url: $OS_AUTH_URL
111 region_name: $OS_REGION_NAME
112 EOF
113 sudo mv clouds.yaml ~nodepool/.config/openstack/
114 sudo chown -R nodepool.nodepool ~nodepool/.config
115 umask 0002
116
117Once you've written out the file, double check all the required fields have been filled out.
118
119::
120
121 sudo mkdir /etc/nodepool/
122 sudo mkdir /var/log/nodepool
123 sudo chgrp -R nodepool /var/log/nodepool/
124 sudo chmod 775 /var/log/nodepool/
125
126Nodepool Configuration
127~~~~~~~~~~~~~~~~~~~~~~
128
129Inputs needed for this file:
130
131* cloud name / region name - from clouds.yaml
132* flavor-name
133* image-name - from your cloud
134
135::
136
137 sudo bash -c "cat >/etc/nodepool/nodepool.yaml <<EOF
138 zookeeper-servers:
139 - host: localhost
140 port: 2181
141
142 providers:
143 - name: myprovider # this is a nodepool identifier for this cloud provider (cloud+region combo)
144 region-name: regionOne # this needs to match the region name in clouds.yaml but is only needed if there is more than one region
145 cloud: mycloud # This needs to match the name in clouds.yaml
146 cloud-images:
147 - name: centos-7 # Defines a cloud-image for nodepool
148 image-name: CentOS-7-x86_64-GenericCloud-1706 # name of image from cloud
149 username: centos # The user Zuul should log in as
150 pools:
151 - name: main
152 max-servers: 4 # nodepool will never create more than this many servers
153 labels:
154 - name: centos-7-small # defines label that will be used to get one of these in a job
155 flavor-name: 'm1.small' # name of flavor from cloud
156 cloud-image: centos-7 # matches name from cloud-images
157 key-name: nodepool # name of the keypair to use for authentication
158
159 labels:
160 - name: centos-7-small # defines label that will be used in jobs
161 min-ready: 2 # nodepool will always keep this many booted and ready to go
162 EOF"
163
164.. warning::
165
166 `min-ready:2` may incur costs in your cloud provider
167
168
169Zuul Setup
170~~~~~~~~~~
171
172::
173
174 sudo mkdir /etc/zuul/
175 sudo mkdir /var/log/zuul/
176 sudo chown zuul.zuul /var/log/zuul/
177 sudo mkdir /var/lib/zuul/.ssh
178 sudo chmod 0700 /var/lib/zuul/.ssh
179 sudo mv nodepool_rsa /var/lib/zuul/.ssh
180 sudo chown -R zuul.zuul /var/lib/zuul/.ssh
181
182Zuul Configuration
183~~~~~~~~~~~~~~~~~~
184
185Write the Zuul config file. Note that this configures Zuul's web
186server to listen on all public addresses. This is so that Zuul may
187receive webhook events from GitHub. You may wish to proxy this or
188further restrict public access.
189
190::
191
192 sudo bash -c "cat > /etc/zuul/zuul.conf <<EOF
193 [gearman]
194 server=127.0.0.1
195
196 [gearman_server]
197 start=true
198
199 [executor]
200 private_key_file=/home/zuul/.ssh/nodepool_rsa
201
202 [web]
203 listen_address=0.0.0.0
204
205 [scheduler]
206 tenant_config=/etc/zuul/main.yaml
207 EOF"
208
209 sudo bash -c "cat > /etc/zuul/main.yaml <<EOF
210 - tenant:
211 name: quickstart
212 EOF"
213
214Service Management
215------------------
216
217Zookeeper Service Management
218~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219
220::
221
222 sudo systemctl start zookeeper.service
223
224::
225
226 sudo systemctl status zookeeper.service
227 ● zookeeper.service - Apache ZooKeeper
228 Loaded: loaded (/usr/lib/systemd/system/zookeeper.service; disabled; vendor preset: disabled)
229 Active: active (running) since Wed 2018-01-03 14:53:47 UTC; 5s ago
230 Process: 4153 ExecStart=/usr/bin/zkServer.sh start zoo.cfg (code=exited, status=0/SUCCESS)
231 Main PID: 4160 (java)
232 Tasks: 17 (limit: 4915)
233 CGroup: /system.slice/zookeeper.service
234 └─4160 java -Dzookeeper.log.dir=/var/log/zookeeper -Dzookeeper.root.logger=INFO,CONSOLE -cp /usr/share/java/
235
236::
237
238 sudo systemctl enable zookeeper.service
239
240
241Nodepool Service Management
242~~~~~~~~~~~~~~~~~~~~~~~~~~~
243
244::
245
246 sudo bash -c "cat > /etc/systemd/system/nodepool-launcher.service <<EOF
247 [Unit]
248 Description=Nodepool Launcher Service
249 After=syslog.target network.target
250
251 [Service]
252 Type=simple
253 # Options to pass to nodepool-launcher.
254 Group=nodepool
255 User=nodepool
256 RuntimeDirectory=nodepool
257 ExecStart=/usr/local/bin/nodepool-launcher
258
259 [Install]
260 WantedBy=multi-user.target
261 EOF"
262
263 sudo chmod 0644 /etc/systemd/system/nodepool-launcher.service
264 sudo systemctl daemon-reload
265 sudo systemctl start nodepool-launcher.service
266 sudo systemctl status nodepool-launcher.service
267 sudo systemctl enable nodepool-launcher.service
268
269Zuul Service Management
270~~~~~~~~~~~~~~~~~~~~~~~
271::
272
273 sudo bash -c "cat > /etc/systemd/system/zuul-scheduler.service <<EOF
274 [Unit]
275 Description=Zuul Scheduler Service
276 After=syslog.target network.target
277
278 [Service]
279 Type=simple
280 Group=zuul
281 User=zuul
282 RuntimeDirectory=zuul
283 ExecStart=/usr/local/bin/zuul-scheduler
284 ExecStop=/usr/local/bin/zuul-scheduler stop
285
286 [Install]
287 WantedBy=multi-user.target
288 EOF"
289
290 sudo bash -c "cat > /etc/systemd/system/zuul-executor.service <<EOF
291 [Unit]
292 Description=Zuul Executor Service
293 After=syslog.target network.target
294
295 [Service]
296 Type=simple
297 Group=zuul
298 User=zuul
299 RuntimeDirectory=zuul
300 ExecStart=/usr/local/bin/zuul-executor
301 ExecStop=/usr/local/bin/zuul-executor stop
302
303 [Install]
304 WantedBy=multi-user.target
305 EOF"
306
307 sudo bash -c "cat > /etc/systemd/system/zuul-web.service <<EOF
308 [Unit]
309 Description=Zuul Web Service
310 After=syslog.target network.target
311
312 [Service]
313 Type=simple
314 Group=zuul
315 User=zuul
316 RuntimeDirectory=zuul
317 ExecStart=/usr/local/bin/zuul-web
318 ExecStop=/usr/local/bin/zuul-web stop
319
320 [Install]
321 WantedBy=multi-user.target
322 EOF"
323
324 sudo systemctl daemon-reload
325 sudo systemctl start zuul-scheduler.service
326 sudo systemctl status zuul-scheduler.service
327 sudo systemctl enable zuul-scheduler.service
328 sudo systemctl start zuul-executor.service
329 sudo systemctl status zuul-executor.service
330 sudo systemctl enable zuul-executor.service
331 sudo systemctl start zuul-web.service
332 sudo systemctl status zuul-web.service
333 sudo systemctl enable zuul-web.service
334
335Use Zuul Jobs
336-------------
337
338Add to ``/etc/zuul/zuul.conf``::
339
340 sudo bash -c "cat >> /etc/zuul/zuul.conf <<EOF
341
342 [connection zuul-git]
343 driver=git
344 baseurl=https://git.openstack.org/
345 EOF"
346
347Restart executor and scheduler::
348
349 sudo systemctl restart zuul-executor.service
350 sudo systemctl restart zuul-scheduler.service
351
352Configure GitHub
353----------------
354
355You'll need an organization in Github for this, so create one if you
356haven't already. In this example we will use `my-org`.
357
358.. NOTE Duplicate content here and in drivers/github.rst. Keep them
359 in sync.
360
361Create a `GitHub application
362<https://developer.github.com/apps/building-integrations/setting-up-and-registering-github-apps/registering-github-apps/>`_:
363
364* Go to your organization settings page to create the application, e.g.:
365 https://github.com/organizations/my-org/settings/apps/new
366* Set GitHub App name to "my-org-zuul"
367* Set Setup URL to your setup documentation, when users install the application
368 they are redirected to this url
369* Set Webhook URL to
370 ``http://<IP ADDRESS>/connection/github/payload``.
371* Create a Webhook secret, and record it for later use
372* Set permissions:
373
374 * Commit statuses: Read & Write
375 * Issues: Read & Write
376 * Pull requests: Read & Write
377 * Repository contents: Read & Write (write to let zuul merge change)
378 * Repository administration: Read
379
380* Set events subscription:
381
382 * Label
383 * Status
384 * Issue comment
385 * Issues
386 * Pull request
387 * Pull request review
388 * Pull request review comment
389 * Commit comment
390 * Create
391 * Push
392 * Release
393
394* Set Where can this GitHub App be installed to "Any account"
395* Create the App
396* Generate a Private key in the app settings page and save the file for later
397
398.. TODO See if we can script this using GitHub API
399
400Go back to the `General` settings page for the app,
401https://github.com/organizations/my-org/settings/apps/my-org-zuul
402and look for the app `ID` number, under the `About` section.
403
404Edit ``/etc/zuul/zuul.conf`` to add the following::
405
406 [connection github]
407 driver=github
408 app_id=<APP ID NUMBER>
409 app_key=/etc/zuul/github.pem
410 webhook_token=<WEBHOOK TOKEN>
411
412Upload the private key which was generated earlier, and save it in
413``/etc/zuul/github.pem``.
414
415Restart all of Zuul::
416
417 sudo systemctl restart zuul-executor.service
418 sudo systemctl restart zuul-web.service
419 sudo systemctl restart zuul-scheduler.service
420
421Go to the `Advanced` tab for the app in GitHub,
422https://github.com/organizations/my-org/settings/apps/my-org-zuul/advanced,
423and look for the initial ping from the app. It probably wasn't
424delivered since Zuul wasn't configured at the time, so click
425``Resend`` and verify that it is delivered now that Zuul is
426configured.
427
428Visit the public app page on GitHub,
429https://github.com/apps/my-org-zuul, and install the app into your org.
430
431Create two new repositories in your org. One will hold the
432configuration for this tenant in Zuul, the other should be a normal
433project repo to use for testing. We'll call them `zuul-test-config`
434and `zuul-test`, respectively.
435
436Edit ``/etc/zuul/main.yaml`` so that it looks like this::
437
438 - tenant:
439 name: quickstart
440 source:
441 zuul-git:
442 config-projects:
443 - openstack-infra/zuul-base-jobs
444 untrusted-projects:
445 - openstack-infra/zuul-jobs
446 github:
447 config-projects:
448 - my-org/zuul-test-config
449 untrusted-projects:
450 - my-org/zuul-test
451
452The first section, under 'zuul-git' imports the "standard library" of
453Zuul jobs, a collection of jobs that can be used by any Zuul
454installation.
455
456The second section is your GitHub configuration.
457
458After updating the file, restart the Zuul scheduler::
459
460 sudo systemctl restart zuul-scheduler.service
461
462Add an initial pipeline configuration to the `zuul-test-config`
463repository. Inside that project, create a ``zuul.yaml`` file with the
464following contents::
465
466 - pipeline:
467 name: check
468 description: |
469 Newly opened pull requests enter this pipeline to receive an
470 initial verification
471 manager: independent
472 trigger:
473 github:
474 - event: pull_request
475 action:
476 - opened
477 - changed
478 - reopened
479 - event: pull_request
480 action: comment
481 comment: (?i)^\s*recheck\s*$
482 start:
483 github:
484 status: pending
485 comment: false
486 success:
487 github:
488 status: 'success'
489 failure:
490 github:
491 status: 'failure'
492
493Merge that commit into the repository.
494
495In the `zuul-test` project, create a `.zuul.yaml` file with the
496following contents::
497
498 - project:
499 check:
500 jobs:
501 - noop
502
503Open a new pull request with that commit against the `zuul-test`
504project and verify that Zuul reports a successful run of the `noop`
505job.