aboutsummaryrefslogtreecommitdiff
path: root/INSTALL
blob: 8c25e99660c151e9285d36f9aada7d6dccb4fd4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
This guide shows how to install and configure brep on a "deployment" machine as
opposed to a "development" one (see INSTALL-DEV for the latter). Here we assume
you are using a systemd-based distribution. If not, then you will need to
replace systemctl commands with the equivalent init.d ones.

The below instructions include steps for setting up brep as the build2 build
bot controller, package submission, and CI request services. All these
functionalities are optional and, if not needed, then the corresponding steps
can be omitted.

1. Create 'brep' User

This user will be used to run the brep package database loader, build database
cleaner, and the database schemes migration utility. We will also use its home
directory to build and install the brep module, store its configuration, etc.

Note: if the deployment machine employs SELinux, then this approach may
require additional configuration steps (not shown) in order to allow Apache2
access to the module, configuration, and content (or, alternatively, a
different deployment approach).

We create this user with a disabled password so only root will be able to
operate as brep. Because of this restriction we will allow brep to run sudo
without a password:

# adduser --disabled-password brep
# echo "brep ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/brep
# chmod 0440 /etc/sudoers.d/brep

In the rest of this guide commands that start with the $ shell prompt are
expected to be executed as the brep user and in its home directory (those
that start with # as above are run as root). To change to the brep user
from root, do:

# su -l brep


2. Install Prerequisites

a) Install a C++ compiler using your distribution's package.

b) Install PostgreSQL 9.3 or above (including the contrib package containing
   the postgres_fdw extension) as well as Apache2 using your distribution's
   packages. Below are the names of these packages for some distributions:

   Debian/Ubuntu: postgresql-server    postgresql-contrib    apache2
   Fedora/RHEL:   postgresql-server    postgresql-contrib    httpd
   FreeBSD:       postgresqlXY-server  postgresqlXY-contrib  apache24

   Also check that the files in /home/brep are readable by "others". If they
   are not, then run the following command to grant Apache2 read access:

   $ setfacl -m g:www-data:rx /home/brep
   $ setfacl -dm g:www-data:rx /home/brep

   In the above command and in the rest of this guide replace www-data with
   the user name under which Apache2 is running (See the "User" directive in
   the Apache2 .conf file).

   [Note that strictly speaking www-data in the above command is the Apache2
   group, not user. However, most installations use the same name for both.]

c) Install PostgreSQL and Apache2 development files. Specifically, we need
   PostgreSQL's libpq and Apache's libapr, libapreq, and web server development
   files. Below are the names of their packages for some distributions:

   Debian/Ubuntu: libpq-dev           libapr1-dev libapreq2-dev   apache2-dev
   Fedora/RHEL:   posqtgresql-devel   apr-devel   libapreq2-devel httpd-devel
   FreeBSD:       postgresqlXY-client apr         libapreq2       apache24

d) Unless you already have the build2 toolchain, install it by following
   instructions on https://build2.org/install.xhtml.

   Note that brep loader (discussed below) runs bpkg so it makes sense to have
   both from the same release.

3. Build and Install brep

Normally the only extra information that you need to provide on this step is
the location of the Apache2 headers (httpd.h, etc). Below are their locations
for some distributions:

Debian/Ubuntu: /usr/include/apache2
Fedora/RHEL:   /usr/include/httpd
FreeBSD:       /usr/local/include/apache24

You can also use the Apache2 apxs utility to obtain this information as shown
below.

$ mkdir brep
$ cd brep

$ bpkg create                                   \
   cc                                           \
   config.cc.poptions="-I$(apxs -q includedir)" \
   config.bin.rpath=$HOME/install/lib           \
   config.install.root=$HOME/install

$ bpkg add https://pkg.cppget.org/1/alpha
$ bpkg fetch
$ bpkg build brep ?sys:libapr1 ?sys:libapreq2 ?sys:libpq
$ bpkg install brep

$ cd .. # Back to brep home.


4. Create PostgreSQL User and Databases

Note that the brep_package and brep_build databases can reside in different
database instances, potentially on different hosts. If this is the case then
the following commands must be adjusted accordingly.

Note also that below unless you set a custom password for the brep-build
database user, any locally logged-in user will be able to login as brep-build
and gain full access to the brep_package database.

$ sudo sudo -u postgres psql # Note: double sudo is not a mistake.

CREATE DATABASE brep_package
  TEMPLATE template0
  ENCODING 'UTF8'
  LC_COLLATE 'en_US.UTF8'
  LC_CTYPE 'en_US.UTF8';

CREATE DATABASE brep_build
  TEMPLATE template0
  ENCODING 'UTF8'
  LC_COLLATE 'en_US.UTF8'
  LC_CTYPE 'en_US.UTF8';

CREATE USER brep;

GRANT ALL PRIVILEGES ON DATABASE brep_package, brep_build TO brep;

CREATE USER "www-data" INHERIT IN ROLE brep;

CREATE USER "brep-build" INHERIT IN ROLE brep PASSWORD '-';

Exit psql (^D), then make sure the logins work:

$ psql -d brep_package
^D
$ psql -d brep_build
^D
$ sudo sudo -u www-data psql -d brep_package
^D
$ sudo sudo -u www-data psql -d brep_build
^D

To troubleshoot, see PostgreSQL logs.

Next setup the connection between databases:

$ sudo sudo -u postgres psql -d brep_build

CREATE EXTENSION postgres_fdw;

CREATE SERVER package_server
  FOREIGN DATA WRAPPER postgres_fdw
  OPTIONS (dbname 'brep_package', updatable 'false');

GRANT USAGE ON FOREIGN SERVER package_server to brep;

CREATE USER MAPPING FOR PUBLIC
  SERVER package_server
  OPTIONS (user 'brep-build', password '-');

Exit psql (^D)

The user brep-build is required (by the postgres_fdw extension) to login with
password. To accomplish this, add the following line to the PostgreSQL client
authentication configuration file (pg_hba.conf):

# TYPE  DATABASE      USER        ADDRESS  METHOD
local   brep_package  brep-build           md5

Restart PostgreSQL:

$ sudo systemctl restart postgresql

Enable creating database tables with columns of the case-insensitive character
string type:

$ sudo sudo -u postgres psql -d brep_package

CREATE EXTENSION citext;

Exit psql (^D)

$ sudo sudo -u postgres psql -d brep_build

CREATE EXTENSION citext;

Exit psql (^D)


5. Create Database Schemes and Load Repositories

$ mkdir config
$ edit config/loadtab # Loader configuration, see brep-load(1).

$ install/bin/brep-migrate package
$ install/bin/brep-load config/loadtab

$ install/bin/brep-migrate build

To verify:

$ psql -d brep_package -c 'SELECT canonical_name, summary FROM repository'
$ psql -d brep_build -c 'SELECT package_name FROM build' # Empty row set.
$ psql -d brep_build -c 'SELECT DISTINCT name FROM build_package'


6. Setup Apache2 Module

$ cp install/share/brep/etc/brep-module.conf config/
$ edit config/brep-module.conf # Adjust default values if required.

To enable the build2 build bot controller functionality you will need to set
the build-config option in brep-module.conf.

To enable the package submission functionality you will need to specify the
submit-data and submit-temp directories in brep-module.conf. Note that these
directories must exist and have read, write, and execute permissions granted
to the www-data user. This, for example, can be achieved with the following
commands:

$ mkdir /home/brep/submit-data
$ mkdir /home/brep/submit-temp
$ setfacl -m g:www-data:rwx /home/brep/submit-data
$ setfacl -m g:www-data:rwx /home/brep/submit-temp

To also enable the package submission web form set the submit-form option. You
can use the installed sample submission form fragment or create a custom one
if your submission handler requires additional information (besides the
package archive and its SHA256 checksum) to be supplied by the client. For
example:

$ cp install/share/brep/www/submit.xhtml config/
$ edit config/submit.xhtml # Add custom form fields, adjust CSS style, etc.

For sample submission handler implementations see brep/handler/submit/.

To enable the CI request functionality you will need to specify the ci-data
directory in brep-module.conf. Note that this directory must exist and have
read, write, and execute permissions granted to the www-data user. This, for
example, can be achieved with the following commands:

$ mkdir /home/brep/ci-data
$ setfacl -m g:www-data:rwx /home/brep/ci-data

To also enable the CI request submission web form set the ci-form option. You
can use the installed sample CI form fragment or create a custom one if your
CI request handler requires additional information (besides the repository URL
and optional package name[/version]) to be supplied by the client. For
example:

$ cp install/share/brep/www/ci.xhtml config/
$ edit config/ci.xhtml # Add custom form fields, adjust CSS style, etc.

For sample CI request handler implementations see brep/handler/ci/.

Here we assume you have setup an appropriate Apache2 virtual server. Open the
corresponding Apache2 .conf file and add the following inside VirtualHost (you
can also find this fragment in install/share/brep/etc/brep-apache2.conf):

        # Load the brep module.
        #
        <IfModule !brep_module>
          LoadModule brep_module /home/brep/install/libexec/brep/mod_brep.so
        </IfModule>

        # Repository email. This email is used for the From: header in emails
        # send by brep (for example, build failure notifications).
        #
        brep-email admin@example.org

        # Repository host. It specifies the scheme and the host address (but
        # not the root path; see brep-root below) that will be used whenever
        # brep needs to construct an absolute URL to one of its locations (for
        # example, a link to a build log that is being send via email).
        #
        brep-host https://example.org

        # Repository root. This is the part of the URL between the host name
        # and the start of the repository. For example, root value /pkg means
	# the repository URL is http://example.org/pkg/. Specify / to use the
        # web server root (e.g., http://example.org/). If using a different
        # repository root, don't forget to also change Location and Alias
	# directives below.
        #
        brep-root /pkg

        <Location "/pkg">
          SetHandler brep

          <IfModule dir_module>
            DirectoryIndex disabled
            DirectorySlash Off
          </IfModule>
        </Location>

        # Brep module configuration. If you prefer, you can paste the contents
        # of this file here. However, you will need to prefix every option with
        # 'brep-'.
        #
        brep-conf /home/brep/config/brep-module.conf

        # Static brep content (CSS files).
        #
        <IfModule !alias_module>
          Error "mod_alias is not enabled"
        </IfModule>

        # Note: trailing slashes are important!
        #
        Alias /pkg/@/ /home/brep/install/share/brep/www/

        <Directory "/home/brep/install/share/brep/www">
          Require all granted
        </Directory>

        # You can also serve the repository files from the repository root.
        # For example:
        #
        #   http://example.org/pkg/1/...  -> /path/to/repo/1/...
        #
        #AliasMatch ^/pkg/(\d+)/(.+) /path/to/repo/$1/$2
        #
        #<Directory "/path/to/repo">
        #  Require all granted
        #</Directory>

The output content types of the brep module are application/xhtml+xml,
text/manifest and text/plain. If you would like to make sure they get
compressed (along with linked CSS), also add the following lines:

        # Compress brep output (xhtml+xml) and CSS.
        #
      	AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE text/manifest
        AddOutputFilterByType DEFLATE text/plain
	AddOutputFilterByType DEFLATE text/css

Restart Apache2:

$ sudo systemctl restart apache2

To verify, visit the repository root. To troubleshoot, see Apache logs.

Now that Apache2 loads the brep module which requires PostgreSQL, it is a good
idea to make the Apache2 service depend on PostgreSQL so that they are started
in proper order. Here is how we can do it with systemd (with newer versions
you can use 'systemctl edit' instead of mkdir and cat):

# mkdir -p /etc/systemd/system/apache2.service.d/
# cat >/etc/systemd/system/apache2.service.d/postgresql.conf
[Unit]
Requires=postgresql.service
After=postgresql.service
^D

# mkdir -p /etc/systemd/system/postgresql.service.d/
# cat >/etc/systemd/system/postgresql.service.d/apache2.conf
[Unit]
Wants=apache2.service
^D

# systemctl daemon-reload
# systemctl cat apache2       # Verify override is listed.
# systemctl cat postgresql    # Verify override is listed.
# systemctl stop postgresql
# systemctl status apache2    # Verify stopped.
# systemctl start postgresql
# systemctl status apache2    # Verify started.


7. Optimize CSS

This step is optional and involves optimizing the CSS files used by brep. For
example, using the sassc(1) command line tool:

$ cd install/share/brep/www/
$ for i in *.scss; do sassc -s compressed $i `basename -s .scss $i`.css; done


8. Setup Periodic Loader and Cleaner Execution

Initially this guide suggested using systemd user session support to run the
loader and the cleaner. However, the current state of user sessions has one
major drawback: they are not started/attached-to when logging in with su -l
(see Debian bug #813789 for details). This limitation makes them unusable in
our setup. If you still would like to use systemd to run the loader and the
cleaner, then you can set it up as a system-wide service which runs the
utilities as the brep user/group. Otherwise, a cron job is a natural choice.

Note that the cleaner execution is optional and is only required if the build2
build bot functionality is enabled (see the build bot documentation for
details). If it is disabled in you setup, then skip the cleaner-related
parts in the subsequent subsections.

8.a Setup Periodic Loader and Cleaner Execution with cron

The following crontab entries will execute the loader every five minutes
and the cleaner once a day at midnight:

$ crontab -l
MAILTO=<brep-admin-email>
PATH=/usr/local/bin:/bin:/usr/bin
*/5 * * * * $HOME/install/bin/brep-load $HOME/config/loadtab
0 0 * * * $HOME/install/bin/brep-clean $HOME/config/buildtab
^D

Note that here we assume that bpkg (which is executed by brep-load) is in one
of the PATH's directories (usually /usr/local/bin).


8.b Setup Periodic Loader and Cleaner Execution with systemd

In this version we will use the systemd user session to periodically run the
loader and the cleaner as the brep user. If your installation doesn't use
systemd, then a cron job would be a natural alternative (see above).

As the first step, make sure systemd user sessions support is working for the
brep user:

$ systemctl --user status

If there are any errors, make sure the dbus and libpam-systemd packages are
installed, relogin as brep, and try again. If it still doesn't work, google
for the error message and your distribution name.

Next enable the brep's systemd session to remain running after logging off
since we want the utilities to run even when we are not logged in:

$ sudo loginctl enable-linger brep

$ mkdir -p .config/systemd/user
$ cp install/share/brep/etc/systemd/brep-load.* .config/systemd/user/
$ cp install/share/brep/etc/systemd/brep-clean.* .config/systemd/user/

Start the service to make sure there are no issues:

$ systemctl --user start brep-load.service
$ journalctl

$ systemctl --user start brep-clean.service
$ journalctl

Start the timers and monitor them to make sure they fire:

$ systemctl --user start brep-load.timer
$ systemctl --user start brep-clean.timer
$ journalctl -f

If everything looks good, enable the timer to be started at boot time:

$ systemctl --user enable brep-load.timer
$ systemctl --user enable brep-clean.timer


9. Upgrade Procedure

During upgrade we will stop apache for what should normally be a short period
of time. To ensure that there are no surprises, for production environments it
is generally recommended to first perform the upgrade on a staging machine, for
example, a VM with an identical setup.

Save the previous installation and configuration, for example, using the
brep version as a suffix:

$ cp -r config config-`cat install/share/doc/brep/version`
$ cp -r install install-`cat install/share/doc/brep/version`

Build new version of brep:

$ cd brep
$ bpkg fetch
$ bpkg build brep

If you are using a systemd-based setup, then stop and disable the loader and
the cleaner:

$ systemctl --user disable --now brep-load.timer
$ systemctl --user disable --now brep-clean.timer
$ systemctl --user stop brep-load.service
$ systemctl --user stop brep-clean.service

If you are using a cron-based setup, then it is not worth it commenting out the
job entries. If the new version of the loader or the cleaner gets executed
before or during the migration, then it will fail and you will get an email
with the diagnostics. Other than that, it should be harmless.

Stop apache:

$ sudo systemctl stop apache2

Install new brep:

$ rm -rf ../install/*
$ bpkg install brep
$ cd ..

Review brep-module.conf changes that may need to be merged:

$ diff -u install/share/brep/etc/brep-module.conf config/brep-module.conf

Migrate database schemes:

$ install/bin/brep-migrate package
$ install/bin/brep-migrate build

Note that if instead you need to recreate the whole databases (e.g., migration
is not possible), then one way to do it would be:

$ psql -d brep_package -c 'DROP OWNED BY brep'
$ psql -d brep_build -c 'DROP OWNED BY brep'

If using systemd, then start and enable the loader and the cleaner:

$ systemctl --user start brep-load.service
$ systemctl --user status brep-load.service
$ systemctl --user start brep-clean.service
$ systemctl --user status brep-clean.service

If everything looks good, enable periodic execution:

$ systemctl --user enable --now brep-load.timer
$ systemctl --user enable --now brep-clean.timer

If using cron, then simply wait for the next run.

You can also do a manual load:

$ install/bin/brep-load config/loadtab

Next, start apache:

$ sudo systemctl start apache2

To verify, visit the repository root. To troubleshoot, see Apache logs.

You will also need to repeat the CSS optimization step above.