]> granicus.if.org Git - icinga2/blob - doc/21-development.md
Merge pull request #7096 from Icinga/feature/derivative-states
[icinga2] / doc / 21-development.md
1 # Development <a id="development"></a>
2
3 This chapter provides hints on Icinga 2 debugging,
4 development, package builds and tests.
5
6 * [Debug Icinga 2](21-development.md#development-debug)
7   * [GDB Backtrace](21-development.md#development-debug-gdb-backtrace)
8   * [Core Dump](21-development.md#development-debug-core-dump)
9 * [Test Icinga 2](21-development.md#development-tests)
10   * [Snapshot Packages (Nightly Builds)](21-development.md#development-tests-snapshot-packages)
11 * [Develop Icinga 2](21-development.md#development-develop)
12   * [Linux Dev Environment](21-development.md#development-linux-dev-env)
13   * [macOS Dev Environment](21-development.md#development-macos-dev-env)
14   * [Windows Dev Environment](21-development.md#development-windows-dev-env)
15 * [Package Builds](21-development.md#development-package-builds)
16   * [RPM](21-development.md#development-package-builds-rpms)
17   * [DEB](21-development.md#development-package-builds-deb)
18   * [Windows](21-development.md#development-package-builds-windows)
19 * [Advanced Tips](21-development.md#development-advanced)
20
21
22 ## Debug Icinga 2 <a id="development-debug"></a>
23
24 This chapter targets all users who have been asked by developers to provide
25 a stack trace or coredump if the application crashed. It is also useful
26 for developers working with different debuggers.
27
28 > **Note:**
29 >
30 > This is intentionally mentioned before any development insights
31 > as debugging is a more frequent and commonly asked question.
32
33 ### Debug Requirements <a id="debug-requirements"></a>
34
35 Make sure that the debug symbols are available for Icinga 2.
36 The Icinga 2 packages provide a debug package which must be
37 installed separately for all involved binaries, like `icinga2-bin`
38 or `icinga2-ido-mysql`.
39
40 Distribution       | Command
41 -------------------|------------------------------------------
42 Debian/Ubuntu      | `apt-get install icinga2-dbg`
43 RHEL/CentOS        | `yum install icinga2-debuginfo`
44 Fedora             | `dnf install icinga2-debuginfo icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo`
45 SLES/openSUSE      | `zypper install icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo`
46
47 Furthermore, you may also have to install debug symbols for Boost and your C++ library.
48
49 If you're building your own binaries, you should use the `-DCMAKE_BUILD_TYPE=Debug` cmake
50 build flag for debug builds.
51
52
53 ### GDB as Debugger <a id="development-debug-gdb"></a>
54
55 Install GDB in your development environment.
56
57 Distribution       | Command
58 -------------------|------------------------------------------
59 Debian/Ubuntu      | `apt-get install gdb`
60 RHEL/CentOS        | `yum install gdb`
61 Fedora             | `dnf install gdb`
62 SLES/openSUSE      | `zypper install gdb`
63
64 #### GDB Run <a id="development-debug-gdb-run"></a>
65
66 Call GDB with the binary (`/usr/sbin/icinga2` is a wrapper script calling
67 `/usr/lib64/icinga2/sbin/icinga2` since 2.4) and all arguments and run it in foreground.
68
69 ```
70 gdb --args /usr/lib64/icinga2/sbin/icinga2 daemon -x debug
71 ```
72
73 The exact path to the Icinga 2 binary differs on each distribution. On Ubuntu
74 it is installed into `/usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2` on 64-bit systems
75 for example.
76
77 > **Note**
78 >
79 > If gdb tells you it's missing debug symbols, quit gdb and install
80 > them: `Missing separate debuginfos, use: debuginfo-install ...`
81
82 Run/restart the application.
83
84 ```
85 (gdb) r
86 ```
87
88 Kill the running application.
89
90 ```
91 (gdb) k
92 ```
93
94 Continue after breakpoint.
95
96 ```
97 (gdb) c
98 ```
99
100 #### GDB Core Dump <a id="development-debug-gdb-coredump"></a>
101
102 Either attach to the running process using `gdb -p PID` or start
103 a new gdb run.
104
105 ```
106 (gdb) r
107 (gdb) generate-core-file
108 ```
109
110 #### GDB Backtrace <a id="development-debug-gdb-backtrace"></a>
111
112 If Icinga 2 aborted its operation abnormally, generate a backtrace.
113
114 > **Note**
115 >
116 > Please install the [required debug symbols](21-development.md#debug-requirements)
117 > prior to generating a backtrace.
118
119 `thread apply all` is important here since this includes all running threads.
120 We need this information when e.g. debugging dead locks and hanging features.
121
122 ```
123 (gdb) bt
124 (gdb) thread apply all bt full
125 ```
126
127 If gdb stops at a SIGPIPE signal please disable the signal before
128 running Icinga 2. This isn't an error, but we need to workaround it.
129
130 ```
131 (gdb) handle SIGPIPE nostop noprint pass
132 (gdb) r
133 ```
134
135 If you create a [new issue](https://github.com/Icinga/icinga2/issues),
136 make sure to attach as much detail as possible.
137
138 #### GDB Backtrace from Running Process <a id="development-debug-gdb-backtrace-running"></a>
139
140 If Icinga 2 is still running, generate a full backtrace from the running
141 process and store it into a new file (e.g. for debugging dead locks).
142
143 > **Note**
144 >
145 > Please install the [required debug symbols](21-development.md#debug-requirements)
146 > prior to generating a backtrace.
147
148 Icinga 2 runs with 2 processes: main and command executor, therefore generate two backtrace logs
149 and add them to the GitHub issue.
150
151 ```
152 for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "thread apply all bt full" -ex "detach" -ex "q" > gdb_bt_${pid}_`date +%s`.log; done
153 ```
154
155 #### GDB Thread List from Running Process <a id="development-debug-gdb-thread-list-running"></a>
156
157 Instead of a full backtrace, you sometimes just need a list of running threads.
158
159 ```
160 for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "info threads" -ex "detach" -ex "q" > gdb_threads_${pid}_`date +%s`.log; done
161 ```
162
163 #### GDB Backtrace Stepping <a id="development-debug-gdb-backtrace-stepping"></a>
164
165 Identifying the problem may require stepping into the backtrace, analysing
166 the current scope, attributes, and possible unmet requirements. `p` prints
167 the value of the selected variable or function call result.
168
169 ```
170 (gdb) up
171 (gdb) down
172 (gdb) p checkable
173 (gdb) p checkable.px->m_Name
174 ```
175
176 #### GDB Breakpoints <a id="development-debug-gdb-breakpoint"></a>
177
178 To set a breakpoint to a specific function call, or file specific line.
179
180 ```
181 (gdb) b checkable.cpp:125
182 (gdb) b icinga::Checkable::SetEnablePerfdata
183 ```
184
185 GDB will ask about loading the required symbols later, select `yes` instead
186 of `no`.
187
188 Then run Icinga 2 until it reaches the first breakpoint. Continue with `c`
189 afterwards.
190
191 ```
192 (gdb) run
193 (gdb) c
194 ```
195
196 In case you want to step into the next line of code, use `n`. If there is a
197 function call where you want to step into, use `s`.
198
199 ```
200 (gdb) n
201
202 (gdb) s
203 ```
204
205 If you want to delete all breakpoints, use `d` and select `yes`.
206
207 ```
208 (gdb) d
209 ```
210
211 > **Tip**
212 >
213 > When debugging exceptions, set your breakpoint like this: `b __cxa_throw`.
214
215 Breakpoint Example:
216
217 ```
218 (gdb) b __cxa_throw
219 (gdb) r
220 (gdb) up
221 ....
222 (gdb) up
223 #11 0x00007ffff7cbf9ff in icinga::Utility::GlobRecursive(icinga::String const&, icinga::String const&, boost::function<void (icinga::String const&)> const&, int) (path=..., pattern=..., callback=..., type=1)
224     at /home/michi/coding/icinga/icinga2/lib/base/utility.cpp:609
225 609                     callback(cpath);
226 (gdb) l
227 604
228 605     #endif /* _WIN32 */
229 606
230 607             std::sort(files.begin(), files.end());
231 608             BOOST_FOREACH(const String& cpath, files) {
232 609                     callback(cpath);
233 610             }
234 611
235 612             std::sort(dirs.begin(), dirs.end());
236 613             BOOST_FOREACH(const String& cpath, dirs) {
237 (gdb) p files
238 $3 = std::vector of length 11, capacity 16 = {{static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/agent.conf"}, {static NPos = 18446744073709551615,
239     m_Data = "/etc/icinga2/conf.d/commands.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/downtimes.conf"}, {static NPos = 18446744073709551615,
240     m_Data = "/etc/icinga2/conf.d/groups.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/notifications.conf"}, {static NPos = 18446744073709551615,
241     m_Data = "/etc/icinga2/conf.d/satellite.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/services.conf"}, {static NPos = 18446744073709551615,
242     m_Data = "/etc/icinga2/conf.d/templates.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/test.conf"}, {static NPos = 18446744073709551615,
243     m_Data = "/etc/icinga2/conf.d/timeperiods.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/users.conf"}}
244 ```
245
246
247 ### Core Dump <a id="development-debug-core-dump"></a>
248
249 When the Icinga 2 daemon crashes with a `SIGSEGV` signal
250 a core dump file should be written. This will help
251 developers to analyze and fix the problem.
252
253 #### Core Dump File Size Limit <a id="development-debug-core-dump-limit"></a>
254
255 This requires setting the core dump file size to `unlimited`.
256
257
258 ##### Systemd
259
260 ```
261 systemctl edit icinga2.service
262
263 [Service]
264 ...
265 LimitCORE=infinity
266
267 systemctl daemon-reload
268
269 systemctl restart icinga2
270 ```
271
272 ##### Init Script
273
274 ```
275 vim /etc/init.d/icinga2
276 ...
277 ulimit -c unlimited
278
279 service icinga2 restart
280 ```
281
282 ##### Verify
283
284 Verify that the Icinga 2 process core file size limit is set to `unlimited`.
285
286 ```
287 for pid in $(pidof icinga2); do cat /proc/$pid/limits; done
288
289 ...
290 Max core file size        unlimited            unlimited            bytes
291 ```
292
293
294 #### Core Dump Kernel Format <a id="development-debug-core-dump-format"></a>
295
296 The Icinga 2 daemon runs with the SUID bit set. Therefore you need
297 to explicitly enable core dumps for SUID on Linux.
298
299 ```
300 sysctl -w fs.suid_dumpable=2
301 ```
302
303 Adjust the coredump kernel format and file location on Linux:
304
305 ```
306 sysctl -w kernel.core_pattern=/var/lib/cores/core.%e.%p
307
308 install -m 1777 -d /var/lib/cores
309 ```
310
311 MacOS:
312
313 ```
314 sysctl -w kern.corefile=/cores/core.%P
315
316 chmod 777 /cores
317 ```
318
319 #### Core Dump Analysis <a id="development-debug-core-dump-analysis"></a>
320
321 Once Icinga 2 crashes again a new coredump file will be written. Please
322 attach this file to your bug report in addition to the general details.
323
324 Simple test case for a `SIGSEGV` simulation with `sleep`:
325
326 ```
327 ulimit -c unlimited
328 sleep 1800&
329 [1] <PID>
330 kill -SEGV <PID>
331 gdb `which sleep` /var/lib/cores/core.sleep.<PID>
332 (gdb) bt
333 rm /var/lib/cores/core.sleep.*
334 ```
335
336 Analyzing Icinga 2:
337
338 ```
339 gdb /usr/lib64/icinga2/sbin/icinga2 core.icinga2.<PID>
340 (gdb) bt
341 ```
342
343 ### LLDB as Debugger <a id="development-debug-lldb"></a>
344
345 LLDB is available on macOS with the Xcode command line tools.
346
347 ```
348 $ xcode-select --install
349 ```
350
351 In order to run Icinga 2 with LLDB you need to pass the binary as argument.
352
353 ```
354 lldb -- /usr/local/icinga2/lib/icinga2/sbin/icinga2 daemon
355 ```
356
357 Breakpoint:
358
359 ```
360 > b checkable.cpp:57
361 > b icinga::Checkable::ProcessCheckResult
362 ```
363
364 Full backtrace:
365
366 ```
367 > bt all
368 ```
369
370 Select thread:
371
372 ```
373 > thr sel 5
374 ```
375
376 Step into:
377
378 ```
379 > s
380 ```
381
382 Next step:
383
384 ```
385 > n
386 ```
387
388 Continue:
389
390 ```
391 > c
392 ```
393
394 Up/down in stacktrace:
395
396 ```
397 > up
398 > down
399 ```
400
401 ## Test Icinga 2 <a id="development-tests"></a>
402
403 ### Snapshot Packages (Nightly Builds) <a id="development-tests-snapshot-packages"></a>
404
405 Icinga provides snapshot packages as nightly builds from [Git master](https://github.com/icinga/icinga2).
406
407 These packages contain development code which should be considered "work in progress".
408 While developers ensure that tests are running fine with CI actions on PRs,
409 things might break, or changes are not yet documented in the changelog.
410
411 You can help the developers and test the snapshot packages, e.g. when larger
412 changes or rewrites are taking place for a new major version. Your feedback
413 is very much appreciated.
414
415 Snapshot packages are available for all supported platforms including
416 Linux and Windows and can be obtained from [https://packages.icinga.com](https://packages.icinga.com).
417
418 The [Vagrant boxes](https://github.com/Icinga/icinga-vagrant) also use
419 the Icinga snapshot packages to allow easier integration tests. It is also
420 possible to use Docker with base OS images and installing the snapshot
421 packages.
422
423 If you encounter a problem, please [open a new issue](https://github.com/Icinga/icinga2/issues/new/choose)
424 on GitHub and mention that you're testing the snapshot packages.
425
426 #### RHEL/CentOS <a id="development-tests-snapshot-packages-rhel"></a>
427
428 2.11+ requires the [EPEL repository](02-getting-started.md#package-repositories-rhel-epel) for Boost 1.66+.
429
430 In addition to that, the `icinga-rpm-release` package already provides the `icinga-snapshot-build`
431 repository but it is disabled by default.
432
433 ```
434 yum -y install https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm
435 yum -y install epel-release
436 yum makecache
437
438 yum install --enablerepo=icinga-snapshot-build icinga2
439 ```
440
441 #### Debian <a id="development-tests-snapshot-packages-debian"></a>
442
443 2.11+ requires Boost 1.66+ which either is provided by the OS, backports or Icinga stable repositories.
444 It is advised to configure both Icinga repositories, stable and snapshot and selectively
445 choose the repository with the `-t` flag on `apt-get install`.
446
447 ```
448 apt-get update
449 apt-get -y install apt-transport-https wget gnupg
450
451 wget -O - https://packages.icinga.com/icinga.key | apt-key add -
452
453 DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \
454  echo "deb https://packages.icinga.com/debian icinga-${DIST} main" > \
455  /etc/apt/sources.list.d/${DIST}-icinga.list
456  echo "deb-src https://packages.icinga.com/debian icinga-${DIST} main" >> \
457  /etc/apt/sources.list.d/${DIST}-icinga.list
458
459 DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \
460  echo "deb http://packages.icinga.com/debian icinga-${DIST}-snapshots main" > \
461  /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list
462  echo "deb-src http://packages.icinga.com/debian icinga-${DIST}-snapshots main" >> \
463  /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list
464
465 apt-get update
466 ```
467
468 On Debian Stretch, you'll also need to add Debian Backports.
469
470 ```
471 DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \
472  echo "deb https://deb.debian.org/debian ${DIST}-backports main" > \
473  /etc/apt/sources.list.d/${DIST}-backports.list
474
475 apt-get update
476 ```
477
478 Then install the snapshot packages.
479
480 ```
481 DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \
482 apt-get install -t icinga-${DIST}-snapshots icinga2
483 ```
484
485 #### Ubuntu <a id="development-tests-snapshot-packages-ubuntu"></a>
486
487 ```
488 apt-get update
489 apt-get -y install apt-transport-https wget gnupg
490
491 wget -O - https://packages.icinga.com/icinga.key | apt-key add -
492
493 . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \
494  echo "deb https://packages.icinga.com/ubuntu icinga-${DIST} main" > \
495  /etc/apt/sources.list.d/${DIST}-icinga.list
496  echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST} main" >> \
497  /etc/apt/sources.list.d/${DIST}-icinga.list
498
499 . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \
500  echo "deb https://packages.icinga.com/ubuntu icinga-${DIST}-snapshots main" > \
501  /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list
502  echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST}-snapshots main" >> \
503  /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list
504
505 apt-get update
506 ```
507
508 Then install the snapshot packages.
509
510 ```
511 . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \
512 apt-get install -t icinga-${DIST}-snapshots icinga2
513 ```
514
515 #### SLES <a id="development-tests-snapshot-packages-sles"></a>
516
517 The required Boost packages are provided with the stable release repository.
518
519 ```
520 rpm --import https://packages.icinga.com/icinga.key
521
522 zypper ar https://packages.icinga.com/SUSE/ICINGA-release.repo
523 zypper ref
524
525 zypper ar https://packages.icinga.com/SUSE/ICINGA-snapshot.repo
526 zypper ref
527 ```
528
529 Selectively install the snapshot packages using the `-r` parameter.
530
531 ```
532 zypper in -r icinga-snapshot-builds icinga2
533 ```
534
535
536 ### Unit Tests <a id="development-tests-unit"></a>
537
538 Build the binaries and run the tests.
539
540
541 ```
542 make -j4 -C debug
543 make test -C debug
544 ```
545
546 Run a specific boost test:
547
548 ```
549 debug/Bin/Debug/boosttest-test-base --run_test=remote_url
550 ```
551
552
553
554 ## Develop Icinga 2 <a id="development-develop"></a>
555
556 Icinga 2 can be built on many platforms such as Linux, Unix and Windows.
557 There are limitations in terms of support, e.g. Windows is only supported for agents,
558 not a full-featured master or satellite.
559
560 Before you start with actual development, there is a couple of pre-requisites.
561
562 ### Choose your Editor <a id="development-develop-choose-editor"></a>
563
564 Icinga 2 can be developed with your favorite editor. Icinga developers prefer
565 these tools:
566
567 - vim
568 - CLion (macOS, Linux)
569 - MS Visual Studio (Windows)
570 - Atom
571
572 Editors differ on the functionality. The more helpers you get for C++ development,
573 the faster your development workflow will be.
574
575
576 #### Whitespace Cleanup <a id="development-develop-choose-editor-whitespaces"></a>
577
578 Patches must be cleaned up and follow the indent style (tabs instead of spaces).
579 You should also remove any training whitespaces.
580
581 `git diff` allows to highlight such.
582
583 ```
584 vim $HOME/.gitconfig
585
586 [color "diff"]
587         whitespace = red reverse
588 [core]
589         whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol
590 ```
591
592 `vim` also can match these and visually alert you to remove them.
593
594 ```
595 vim $HOME/.vimrc
596
597 highlight ExtraWhitespace ctermbg=red guibg=red
598 match ExtraWhitespace /\s\+$/
599 autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
600 autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
601 autocmd InsertLeave * match ExtraWhitespace /\s\+$/
602 autocmd BufWinLeave * call clearmatches()
603 ```
604
605 ### Get to know the architecture <a id="development-develop-get-to-know-the-architecture"></a>
606
607 Icinga 2 can run standalone or in distributed environments. It contains a whole lot
608 more than a simple check execution engine.
609
610 Read more about it in the [Technical Concepts](19-technical-concepts.md#technical-concepts) chapter.
611
612 ### Get to know the code <a id="development-develop-get-to-know-the-code"></a>
613
614 First off, you really need to know C++ and portions of C++11 and the boost libraries.
615 Best is to start with a book or online tutorial to get into the basics.
616 Icinga developers gained their knowledge through studies, training and self-teaching
617 code by trying it out and asking senior developers for guidance.
618
619 Here's a few books we can recommend:
620
621 * [Accelerated C++: Practical Programming by Example](https://www.amazon.com/Accelerated-C-Practical-Programming-Example/dp/020170353X) (Andrew Koenig, Barbara E. Moo)
622 * [Effective C++](https://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876) (Scott Meyers)
623 * [Boost C++ Application Development Cookbook - Second Edition: Recipes to simplify your application development](https://www.amazon.com/dp/1787282244/ref=cm_sw_em_r_mt_dp_U_dN1OCbERS00EQ) (Antony Polukhin)
624 * [Der C++ Programmierer](https://www.amazon.de/Programmierer-lernen-Professionell-anwenden-L%C3%B6sungen/dp/3446416447), German (Ulrich Breymann)
625 * [C++11 programmieren](https://www.amazon.de/gp/product/3836217325/), German (Torsten T. Will)
626
627 In addition, it is a good bet to also know SQL when diving into backend development.
628
629 * [SQL Performance Explained](https://www.amazon.de/gp/product/3950307826/) (Markus Winand)
630
631 Last but not least, if you are developing on Windows, get to know the internals about services and the Win32 API.
632
633
634 ### Design Patterns <a id="development-develop-design-patterns"></a>
635
636 Icinga 2 heavily relies on object-oriented programming and encapsulates common
637 functionality into classes and objects. It also uses modern programming techniques
638 to e.g. work with shared pointer memory management.
639
640 Icinga 2 consists of libraries bundled into the main binary. Therefore you'll
641 find many code parts in the `lib/` directory wheras the actual application is
642 built from `icinga-app/`. Accompanied with Icinga 2, there's the Windows plugins
643 which are standalone and compiled from `plugins/`.
644
645 Library        | Description
646 ---------------|------------------------------------
647 base           | Objects, values, types, streams, tockets, TLS, utilities, etc.
648 config         | Configuration compiler, expressions, etc.
649 cli            | CLI (sub) commands and helpers.
650 icinga         | Icinga specific objects and event handling.
651 remote         | Cluster and HTTP client/server and REST API related code.
652 checker        | Checker feature, check scheduler.
653 notification   | Notification feature, notification scheduler.
654 methods        | Command execution methods, plugins and built-in checks.
655 perfdata       | Performance data related, including Graphite, Elastic, etc.
656 db\_ido        | IDO database abstraction layer.
657 db\_ido\_mysql | IDO database driver for MySQL.
658 db\_ido\_pgsql | IDO database driver for PgSQL.
659 mysql\_shin    | Library stub for linking against the MySQL client libraries.
660 pgsql\_shim    | Library stub for linking against the PgSQL client libraries.
661
662 #### Class Compiler <a id="development-develop-design-patterns-class-compiler"></a>
663
664 Another thing you will recognize are the `.ti` files which are compiled
665 by our own class compiler into actual source code. The meta language allows
666 developers to easily add object attributes and specify their behaviour.
667
668 Some object attributes need to be stored over restarts in the state file
669 and therefore have the `state` attribute set. Others are treated as `config`
670 attribute and automatically get configuration validation functions created.
671 Hidden or read-only REST API attributes are marked with `no_user_view` and
672 `no_user_modify`.
673
674 The most beneficial thing are getters and setters being generated. The actual object
675 inherits from `ObjectImpl<TYPE>` and therefore gets them "for free".
676
677 Example:
678
679 ```
680 vim lib/perfdata/gelfwriter.ti
681
682   [config] enable_tls;
683
684 vim lib/perfdata/gelfwriter.cpp
685
686     if (GetEnableTls()) {
687 ```
688
689 The logic is hidden in `tools/mkclass/` in case you want to learn more about it.
690 The first steps during CMake & make also tell you about code generation.
691
692
693 ### Builds: CMake <a id="development-develop-builds-cmake"></a>
694
695 In its early development stages in 2012, Icinga 2 was built with autoconf/automake
696 and separate Windows project files. We've found this very fragile, and have changed
697 this into CMake as our build tool.
698
699 The most common benefits:
700
701 * Everything is described in CMakeLists.txt in each directory
702 * CMake only needs to know that a sub directory needs to be included.
703 * The global CMakeLists.txt acts as main entry point for requirement checks and library/header includes.
704 * Separate binary build directories, the actual source tree stays clean.
705 * CMake automatically generates a Visual Studio project file `icinga2.sln` on Windows.
706
707 ### Builds: Unity Builds <a id="development-develop-builds-unity-builds"></a>
708
709 Another thing you should be aware of: Unity builds on and off.
710
711 Typically, we already use caching mechanisms to reduce recompile time with ccache.
712 For release builds, there's always a new build needed as the difference is huge compared
713 to a previous (major) release.
714
715 Therefore we've invented the Unity builds, which basically concatenates all source files
716 into one big library source code file. The compiler then doesn't need to load the many small
717 files but compiles and links this huge one.
718
719 Unity builds require more memory which is why you should disable them for development
720 builds in small sized VMs (Linux, Windows) and also Docker containers.
721
722 There's a couple of header files which are included everywhere. If you touch/edit them,
723 the cache is invalidated and you need to recompile a lot more files then. `base/utility.hpp`
724 and `remote/zone.hpp` are good candidates for this.
725
726
727 ### Linux Dev Environment <a id="development-linux-dev-env"></a>
728
729 Based on CentOS 7, we have an early draft available inside the Icinga Vagrant boxes:
730 [centos7-dev](https://github.com/Icinga/icinga-vagrant/tree/master/centos7-dev).
731
732 If you're compiling Icinga 2 natively without any virtualization layer in between,
733 this usually is faster. This is also the reason why developers on macOS prefer native builds
734 over Linux or Windows VMs. Don't forget to test the actual code on Linux later! Socket specific
735 stuff like `epoll` is not available on Unix kernels.
736
737 Depending on your workstation and environment, you may either develop and run locally,
738 use a container deployment pipeline or put everything in a high end resource remote VM.
739
740 Fork https://github.com/Icinga/icinga2 into your own repository, e.g. `https://github.com/dnsmichi/icinga2`.
741
742 Create two build directories for different binary builds.
743
744 * `debug` contains the debug build binaries. They contain more debug information and run tremendously slower than release builds from packages. Don't use them for benchmarks.
745 * `release` contains the release build binaries, as you would install them on a live system. This helps comparing specific scenarios for race conditions and more.
746
747 ```
748 mkdir -p release debug
749 ```
750
751 Proceed with the specific distribution examples below.
752
753 * [CentOS 7](21-development.md#development-linux-dev-env-centos)
754 * [Debian 9](21-development.md#development-linux-dev-env-debian)
755
756
757 #### CentOS 7 <a id="development-linux-dev-env-centos"></a>
758
759 ```
760 yum -y install gdb git bash-completion htop rpmdevtools \
761  ccache cmake make gcc-c++ flex bison \
762  openssl-devel boost-devel systemd-devel mysql-devel \
763  postgresql-devel libedit-devel libstdc++-devel
764
765 groupadd icinga
766 groupadd icingacmd
767 useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga
768
769 ln -s /bin/ccache /usr/local/bin/gcc
770 ln -s /bin/ccache /usr/local/bin/g++
771
772 git clone https://github.com/icinga/icinga2.git && cd icinga2
773
774 mkdir debug release
775 cd debug
776 cmake .. -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DICINGA2_PLUGINDIR=/usr/local/sbin
777 cd ..
778 make -j2 install -C debug
779 ```
780
781
782 ```
783 chown -R icinga:icinga /usr/local/icinga2/var/
784
785 /usr/local/icinga2/lib/icinga2/prepare-dirs /usr/local/icinga2/etc/sysconfig/icinga2
786 /usr/local/icinga2/sbin/icinga2 api setup
787 vim /usr/local/icinga2/etc/icinga2/conf.d/api-users.conf
788
789 gdb --args /usr/local/icinga2/lib/icinga2/sbin/icinga2 daemon
790 ```
791
792 #### Debian 9 <a id="development-linux-dev-env-debian"></a>
793
794 ```
795 apt-get -y install gdb vim git cmake make ccache build-essential libssl-dev libboost-all-dev bison flex default-libmysqlclient-dev libpq-dev libedit-dev monitoring-plugins
796
797 ln -s /usr/bin/ccache /usr/local/bin/gcc
798 ln -s /usr/bin/ccache /usr/local/bin/g++
799
800 groupadd icinga
801 groupadd icingacmd
802 useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga
803
804 git clone https://github.com/icinga/icinga2.git && cd icinga2
805
806 mkdir debug release
807 cd debug
808 cmake .. -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DICINGA2_PLUGINDIR=/usr/local/sbin
809 cd ..
810 make -j2 install -C debug
811 ```
812
813
814 ```
815 chown -R icinga:icinga /usr/local/icinga2/var/
816
817 /usr/local/icinga2/lib/icinga2/prepare-dirs /usr/local/icinga2/etc/sysconfig/icinga2
818 /usr/local/icinga2/sbin/icinga2 api setup
819 vim /usr/local/icinga2/etc/icinga2/conf.d/api-users.conf
820
821 gdb --args /usr/local/icinga2/lib/icinga2/sbin/icinga2 daemon
822 ```
823
824
825
826 ### macOS Dev Environment <a id="development-macos-dev-env"></a>
827
828 It is advised to use Homebrew to install required build dependencies.
829 Macports have been reported to work as well, typically you'll get more help
830 with Homebrew from Icinga developers.
831
832 The idea is to run Icinga with the current user, avoiding root permissions.
833
834 #### Requirements
835
836 OpenSSL 1.0.x doesn't build anymore, so we're explicitly using 1.1.x here.
837
838 ```
839 brew install ccache boost cmake bison flex openssl@1.1 mysql-connector-c++ postgresql libpq
840 ```
841
842 ##### ccache
843
844 ```
845 sudo mkdir /opt/ccache
846
847 sudo ln -s `which ccache` /opt/ccache/clang
848 sudo ln -s `which ccache` /opt/ccache/clang++
849
850 vim $HOME/.bash_profile
851
852 # ccache is managed with symlinks to avoid collision with cgo
853 export PATH="/opt/ccache:$PATH"
854
855 source $HOME/.bash_profile
856 ```
857
858 #### Builds
859
860 Icinga is built as release (optimized build for packages) and debug (more symbols and details for debugging). Debug builds
861 typically run slower than release builds and must not be used for performance benchmarks.
862
863 ```
864 mkdir -p release debug
865
866 cd debug
867 cmake -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin ..
868 cd ..
869
870 make -j4 -C debug
871 make -j4 install -C debug
872 ```
873
874 ##### Build Aliases
875
876 This is derived from [dnsmichi's flavour](https://github.com/dnsmichi/dotfiles) and not generally best practice.
877
878 ```
879 vim $HOME/.bash_profile
880
881 export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga/icinga2 -DICINGA2_USER=`id -u -n` -DICINGA2_GROUP=`id -g -n` -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin -DICINGA2_WITH_PGSQL=OFF"
882
883 export I2_DEBUG="-DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF $I2_GENERIC"
884 export I2_RELEASE="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DICINGA2_WITH_TESTS=ON -DICINGA2_UNITY_BUILD=ON $I2_GENERIC"
885
886 alias i2_debug="mkdir -p debug; cd debug; cmake $I2_DEBUG ..; make -j4; make -j4 install; cd .."
887 alias i2_release="mkdir -p release; cd release; cmake $I2_RELEASE ..; make -j4; make -j4 install; cd .."
888
889 export PATH=/usr/local/icinga/icinga2/sbin/:$PATH
890 test -f /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 && source /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2
891
892
893 source $HOME/.bash_profile
894 ```
895
896 #### Run
897
898 ```
899 chown -R icinga:icinga /usr/local/icinga2
900 chown -R icinga:_www /usr/local/icinga2/var/run/icinga2/cmd
901
902 icinga2 daemon
903 ```
904
905 #### Plugins
906
907 ```
908 brew install monitoring-plugins
909
910 sudo vim /usr/local/icinga2/etc/icinga2/constants.conf
911 const PluginDir = "/usr/local/sbin"
912 ```
913
914 #### Backends: Redis
915
916 ```
917 brew install redis
918 brew services start redis
919 ```
920
921 #### Databases: MariaDB
922
923 ```
924 brew install mariadb
925 mkdir -p /usr/local/etc/my.cnf.d
926 brew services start mariadb
927
928 mysql_secure_installation
929 ```
930
931 ```
932 vim $HOME/.my.cnf
933
934 [client]
935 user = root
936 password = supersecurerootpassword
937
938 sudo -i
939 ln -s /Users/michi/.my.cnf $HOME/.my.cnf
940 exit
941 ```
942
943 ```
944 mysql -e 'create database icinga;'
945 mysql -e "grant all on icinga.* to 'icinga'@'localhost' identified by 'icinga';"
946 mysql icinga < $HOME/dev/icinga/icinga2/lib/db_ido_mysql/schema/mysql.sql
947 ```
948
949 #### API
950
951 ```
952 icinga2 api setup
953 cd /usr/local/icinga/icinga2/var/lib/icinga2/certs
954 HOST_NAME=mbpmif.int.netways.de
955 icinga2 pki new-cert --cn ${HOST_NAME} --csr ${HOST_NAME}.csr --key ${HOST_NAME}.key
956 icinga2 pki sign-csr --csr ${HOST_NAME}.csr --cert ${HOST_NAME}.crt
957 echo "const NodeName = \"${HOST_NAME}\"" >> /usr/local/icinga/icinga2/etc/icinga2/constants.conf
958 ```
959
960
961
962
963 ### Windows Dev Environment <a id="development-windows-dev-env"></a>
964
965 The following sections explain how to setup the required build tools
966 and how to run and debug the code.
967
968 #### Chocolatey
969
970 Open an administrative command prompt (Win key, type “cmd”, right-click and “run as administrator”) and paste the following instructions:
971
972 ```
973 @powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
974 ```
975
976 #### Visual Studio
977
978 Thanks to Microsoft they’ll now provide their Professional Edition of Visual Studio 2017
979 as community version, free for use for open source projects such as Icinga.
980 The installation requires ~9GB disk space. [Download](https://www.visualstudio.com/downloads/)
981 the web installer and start the installation.
982
983 You need a free Microsoft account to download and also store your preferences.
984
985 Choose these individual components on Visual Studio 2017:
986
987 * .NET
988   * .NET Framework 3.5 development tools
989   * .NET Framework 4.6.1 SDK
990   * .NET Framework 4.6.1 targeting pack
991 * Code tools
992   * Git for Windows
993   * Static analysis tools
994 * Compilers, build tools and runtimes
995   * C# and Visual Basic Roslyn compilers
996   * C++/CU Support
997   * VC++ 2017 v141 toolset (x86_64)
998 * Debugging and testing
999   * C++ profiling tools
1000   * Just-in-Time debugger
1001 * Development activities
1002   * Visual Studio C++ core features
1003 * Games and Graphics
1004   * Graphics debugger and GPU profiler for DirectX (required by C++ profiling tools)
1005 * SDKs, libraries and frameworks
1006   * Graphics Tools Windows 8.1 SDK (required by C++ profiling tools)
1007   * Windows 10 SDK **10.0.10240.0 - exactly this version**
1008   * Windows 8.1 SDK
1009   * Windows Universal C Runtime
1010 * Uncategorized
1011   * GitHub Extension for Visual Studio
1012
1013
1014 After a while, Visual Studio will be ready.
1015
1016 #### .NET Framework 3.5
1017
1018 Windows 10 has .NET Framework >= 4.6 installed by default. The Icinga Agent Wizard
1019 is built on .NET Framework 2.0 which is not included in .NET Framework 4.6.
1020
1021 Windows 10 provides .NET Framework 3.5 which includes .NET Framework 2.0.
1022
1023 Navigate into `Control Panel` -> `Programs` -> `Turn Windows features on or off`.
1024 Select `.NET Framework 3.5 (includes .NET 2.0 and 3.0)` and wait until the installation process
1025 is finished.
1026
1027 #### Flex and Bison
1028
1029 Install it using [chocolatey](https://www.wireshark.org/docs/wsdg_html_chunked/ChSetupWin32.html):
1030
1031 ```
1032 choco install -y winflexbison
1033 ```
1034
1035 Chocolatey installs these tools into the hidden directory `C:\ProgramData\chocolatey\lib\winflexbison\tools`.
1036
1037 #### OpenSSL
1038
1039 Icinga 2 requires the OpenSSL library. [Download](http://slproweb.com/products/Win32OpenSSL.html)
1040 and install it into the default path.
1041
1042 Once asked for `Copy OpenSSLs DLLs to` select `The Windows system directory`. That way CMake/Visual Studio
1043 will automatically detect them for builds and packaging.
1044
1045 > **Note**
1046 >
1047 > We cannot use the chocolatey package as this one does not provide any development headers.
1048 >
1049 > Choose 1.1.1 LTS from manual downloads for best compatibility.
1050
1051 #### Boost
1052
1053 In order to use the boost development header and library files you need to [download](http://www.boost.org/users/download/)
1054 Boost and then extract it to e.g. `C:\boost_1_69_0`.
1055
1056 > **Note**
1057 >
1058 > Just use `C:`, the zip file already contains the sub folder. Extraction takes a while,
1059 > the archive contains more than 70k files.
1060
1061 In order to integrate Boost into Visual Studio 2017, open the `Developer Command Prompt` from the start menu,
1062 and navigate to `C:\boost_1_69_0`.
1063
1064 Execute `bootstrap.bat` first.
1065
1066 ```
1067 cd C:\boost_1_69_0
1068 bootstrap.bat
1069 ```
1070
1071 Once finished, specify the required `toolset` to compile boost against Visual Studio.
1072 This takes quite some time in a Windows VM. Boost Context uses Assembler code,
1073 which isn't treated as exception safe by the VS compiler. Therefore set the
1074 additional compilation flag according to [this entry](https://lists.boost.org/Archives/boost/2015/08/224570.php).
1075
1076 ```
1077 b2 --toolset=msvc-14.1 asmflags=\safeseh
1078 ```
1079
1080 ![Windows Boost Build in VS2017 Development Console](images/development/windows_boost_build_dev_cmd.png)
1081
1082 #### TortoiseGit
1083
1084 TortoiseGit provides a graphical integration into the Windows explorer. This makes it easier to checkout, commit
1085 and whatnot.
1086
1087 [Download](https://tortoisegit.org/download/) TortoiseGit on your system.
1088
1089 In order to clone via Git SSH you also need to create a new directory called `.ssh`
1090 inside your user's home directory.
1091 Therefore open a command prompt (win key, type `cmd`, enter) and run `mkdir .ssh`.
1092 Add your `id_rsa` private key and `id_rsa.pub` public key files into that directory.
1093
1094 Start the setup routine and choose `OpenSSH` as default secure transport when asked.
1095
1096 Open a Windows Explorer window and navigate into
1097
1098 ```
1099 cd %HOMEPATH%\source\repos
1100 ```
1101
1102 Right click and select `Git Clone` from the context menu.
1103
1104 Use `ssh://git@github.com/icinga/icinga2.git` for SSH clones, `https://github.com/icinga/icinga2.git` otherwise.
1105
1106 #### CMake
1107
1108 Icinga 2 uses CMake to manage the build environment. You can generate the Visual Studio project files
1109 using CMake. [Download](https://cmake.org/download/) and install CMake. Select to add it to PATH for all users
1110 when asked.
1111
1112 > **Note**
1113 >
1114 > In order to properly detect the Boost libraries, install the CMake 3.14+.
1115
1116 Once setup is completed, open a command prompt and navigate to
1117
1118 ```
1119 cd %HOMEPATH%\source\repos
1120 ```
1121
1122 Run CMake with the following command. This generates a new Visual Studio project file called `icinga2.sln`.
1123
1124 You need to specify the previously installed component paths:
1125
1126 Variable              | Value                                                                | Description
1127 ----------------------|----------------------------------------------------------------------|-------------------------------------------------------
1128 `BOOST_ROOT`          | `C:\boost_1_69_0`                                                    | Root path where you've extracted and compiled Boost.
1129 `BOOST_LIBRARYDIR`    | `C:\boost_1_69_0\stage`                                              | Path to the static compiled Boost libraries, directory must contain `lib`.
1130 `BISON_EXECUTABLE`    | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe`     | Path to the Bison executable.
1131 `FLEX_EXECUTABLE`     | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe`      | Path to the Flex executable.
1132 `ICINGA2_WITH_MYSQL`  | OFF                                                                  | Requires extra setup for MySQL if set to `ON`. Not supported for client setups.
1133 `ICINGA2_WITH_PGSQL`  | OFF                                                                  | Requires extra setup for PgSQL if set to `ON`. Not supported for client setups.
1134 `ICINGA2_UNITY_BUILD` | OFF                                                                  | Disable unity builds for development environments.
1135
1136 Tip: If you have previously opened a terminal, run `refreshenv` to re-read updated PATH variables.
1137
1138 ```
1139 cmake . -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Debug -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF
1140 ```
1141
1142 Best is write a small batch/Powershell script which just executes these lines.
1143
1144 ```
1145 @echo off
1146
1147 cd icinga2
1148 mkdir debug
1149 cd debug
1150 del CMakeCache.txt
1151
1152 cmake . -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Debug -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF
1153
1154 cmake --build . --target PACKAGE --config Debug
1155
1156 cd ..
1157 ```
1158
1159
1160 #### Icinga 2 in Visual Studio
1161
1162 Navigate to
1163
1164 ```
1165 cd %HOMEPATH%\source\repos\icinga2
1166 ```
1167
1168 Open `icinga2.sln`. Log into Visual Studio when asked.
1169
1170 On the right panel, select to build the `Bin/icinga-app` solution.
1171
1172 The executable binaries are located in `Bin\Release\Debug` in your `icinga2`
1173 project directory.
1174
1175 Navigate there and run `icinga2.exe --version`.
1176
1177 ```
1178 cd %HOMEPATH%\source\repos\icinga2\Bin\Release\Debug
1179 icinga2.exe --version
1180 ```
1181
1182
1183 #### Release Package
1184
1185 CMake uses CPack and NSIS to create the setup executable including all binaries and libraries
1186 in addition to setup dialogues and configuration. Therefore we’ll need to install [NSIS](http://nsis.sourceforge.net/Download)
1187 first.
1188
1189 We also need to install the Windows Installer XML (WIX) toolset.
1190
1191 ```
1192 choco install -y wixtoolset
1193 ```
1194
1195 Once completed open an administrative shell and navigate to your Visual Studio project.
1196
1197 Let CMake to build a release package.
1198
1199 ```
1200 cd %HOMEPATH%\source\repos\icinga2
1201 cmake --build debug --target PACKAGE --config Release
1202 ```
1203
1204 Note: This will still use the debug builds. A yet more clean approach
1205 is to run CMake with changed release parameters beforehand and then
1206 re-run the release package builder.
1207
1208 ```
1209 cd %HOMEPATH%\source\repos\icinga2
1210 mkdir release
1211 cd release
1212
1213 cmake .. -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=Release -DBOOST_ROOT=C:\boost_1_69_0 -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=OFF
1214 cd ..
1215
1216 cmake --build release --target PACKAGE --config Release
1217 ```
1218
1219 Again, put these lines into a batch/Powershell script and execute that.
1220
1221 ```
1222 @echo off
1223 cd icinga2
1224
1225 mkdir release
1226 cd release
1227
1228 del CMakeCache.txt
1229
1230 ; set gen=Visual Studio 15 2017 Win64
1231 set gen=Visual Studio 15 2017
1232
1233 cmake .. -G "%gen%" -DCPACK_GENERATOR=WIX -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBOOST_ROOT=C:\boost_1_69_0 -DBOOST_LIBRARYDIR=C:\boost_1_69_0\stage -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DICINGA2_WITH_MYSQL=OFF -DICINGA2_WITH_PGSQL=OFF -DICINGA2_UNITY_BUILD=ON
1234 cd ..
1235
1236 cmake --build release --target PACKAGE --config Release
1237
1238 cd ..
1239 ```
1240
1241
1242 ### Embedded Dev Env: Pi <a id="development-embedded-dev-env"></a>
1243
1244 > **Note**
1245 >
1246 > This isn't officially supported yet, just a few hints how you can do it yourself.
1247
1248 The following examples source from armhf on Raspberry Pi.
1249
1250 #### ccache
1251
1252 ```
1253 apt install -y ccache
1254
1255 /usr/sbin/update-ccache-symlinks
1256
1257 echo 'export PATH="/usr/lib/ccache:$PATH"' | tee -a ~/.bashrc
1258
1259 source ~/.bashrc && echo $PATH
1260 ```
1261
1262 #### Build
1263
1264 Copy the icinga2 source code into `$HOME/icinga2`. Clone the `deb-icinga2` repository into `debian/`.
1265
1266 ```
1267 git clone https://github.com/Icinga/icinga2 $HOME/icinga2
1268 git clone https://github.com/Icinga/deb-icinga2 $HOME/icinga2/debian
1269 ```
1270
1271 Then build a Debian package and install it like normal.
1272 ```
1273 dpkg-buildpackage -uc -us
1274 ```
1275
1276 ## Package Builds <a id="development-package-builds"></a>
1277
1278 This documentation is explicitly meant for packagers and the Icinga
1279 build infrastructure.
1280
1281 The following requirements need to be fulfilled in order to build the
1282 Icinga application using a dist tarball (including notes for distributions):
1283
1284 * cmake >= 2.6
1285 * GNU make (make) or ninja-build
1286 * C++ compiler which supports C++11
1287   * RHEL/Fedora/SUSE: gcc-c++ >= 4.7 (extra Developer Tools on RHEL5/6 see below)
1288   * Debian/Ubuntu: build-essential
1289   * Alpine: build-base
1290   * you can also use clang++
1291 * pkg-config
1292 * OpenSSL library and header files >= 1.0.1
1293   * RHEL/Fedora: openssl-devel
1294   * SUSE: libopenssl-devel
1295   * Debian/Ubuntu: libssl-dev
1296   * Alpine: libressl-dev
1297 * Boost library and header files >= 1.66.0
1298   * RHEL/Fedora: boost166-devel
1299   * Debian/Ubuntu: libboost-all-dev
1300   * Alpine: boost-dev
1301 * GNU bison (bison)
1302 * GNU flex (flex) >= 2.5.35
1303 * systemd headers
1304   * Only required when using systemd
1305   * Debian/Ubuntu: libsystemd-dev
1306   * RHEL/Fedora: systemd-devel
1307
1308 ### Optional features <a id="development-package-builds-optional-features"></a>
1309
1310 * MySQL (disable with CMake variable `ICINGA2_WITH_MYSQL` to `OFF`)
1311   * RHEL/Fedora: mysql-devel
1312   * SUSE: libmysqlclient-devel
1313   * Debian/Ubuntu: default-libmysqlclient-dev | libmysqlclient-dev
1314   * Alpine: mariadb-dev
1315 * PostgreSQL (disable with CMake variable `ICINGA2_WITH_PGSQL` to `OFF`)
1316   * RHEL/Fedora: postgresql-devel
1317   * Debian/Ubuntu: libpq-dev
1318   * postgresql-dev on Alpine
1319 * libedit (CLI console)
1320   * RHEL/Fedora: libedit-devel on CentOS (RHEL requires rhel-7-server-optional-rpms)
1321   * Debian/Ubuntu/Alpine: libedit-dev
1322 * Termcap (only required if libedit doesn't already link against termcap/ncurses)
1323   * RHEL/Fedora: libtermcap-devel
1324   * Debian/Ubuntu: (not necessary)
1325
1326 ### Special requirements <a id="development-package-builds-special-requirements"></a>
1327
1328 **FreeBSD**: libexecinfo (automatically used when Icinga 2 is installed via port or package)
1329
1330 **RHEL6**: Requires a newer boost version which is available on packages.icinga.com
1331 with a version suffixed name.
1332
1333 ### Runtime user environment <a id="development-package-builds-runtime-user-env"></a>
1334
1335 By default Icinga will run as user `icinga` and group `icinga`. Additionally the
1336 external command pipe and livestatus features require a dedicated command group
1337 `icingacmd`. You can choose your own user/group names and pass them to CMake
1338 using the `ICINGA2_USER`, `ICINGA2_GROUP` and `ICINGA2_COMMAND_GROUP` variables.
1339
1340 ```
1341 # groupadd icinga
1342 # groupadd icingacmd
1343 # useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga
1344 ```
1345
1346 On Alpine (which uses ash busybox) you can run:
1347
1348 ```
1349 # addgroup -S icinga
1350 # addgroup -S icingacmd
1351 # adduser -S -D -H -h /var/spool/icinga2 -s /sbin/nologin -G icinga -g icinga icinga
1352 # adduser icinga icingacmd
1353 ```
1354
1355 Add the web server user to the icingacmd group in order to grant it write
1356 permissions to the external command pipe and livestatus socket:
1357
1358 ```
1359 # usermod -a -G icingacmd www-data
1360 ```
1361
1362 Make sure to replace "www-data" with the name of the user your web server
1363 is running as.
1364
1365 ### Building Icinga 2: Example <a id="development-package-builds-example"></a>
1366
1367 Once you have installed all the necessary build requirements you can build
1368 Icinga 2 using the following commands:
1369
1370 ```
1371 $ mkdir release && cd release
1372 $ cmake ..
1373 $ cd ..
1374 $ make -C release
1375 $ make install -C release
1376 ```
1377
1378 You can specify an alternative installation prefix using `-DCMAKE_INSTALL_PREFIX`:
1379
1380 ```
1381 $ cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/icinga2
1382 ```
1383
1384 ### CMake Variables <a id="development-package-builds-cmake-variables"></a>
1385
1386 In addition to `CMAKE_INSTALL_PREFIX` here are most of the supported Icinga-specific cmake variables.
1387
1388 For all variables regarding defaults paths on in CMake, see
1389 [GNUInstallDirs](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html).
1390
1391 Also see `CMakeLists.txt` for details.
1392
1393 #### System Environment
1394
1395 * `CMAKE_INSTALL_SYSCONFDIR`: The configuration directory; defaults to `CMAKE_INSTALL_PREFIX/etc`
1396 * `CMAKE_INSTALL_LOCALSTATEDIR`: The state directory; defaults to `CMAKE_INSTALL_PREFIX/var`
1397 * `ICINGA2_CONFIGDIR`: Main config directory; defaults to `CMAKE_INSTALL_SYSCONFDIR/icinga2` usually `/etc/icinga2`
1398 * `ICINGA2_CACHEDIR`: Directory for cache files; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/cache/icinga2` usually `/var/cache/icinga2`
1399 * `ICINGA2_DATADIR`: Data directory  for the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/lib/icinga2` usually `/var/lib/icinga2`
1400 * `ICINGA2_LOGDIR`: Logfiles of the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/log/icinga2 usually `/var/log/icinga2`
1401 * `ICINGA2_SPOOLDIR`: Spooling directory ; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/spool/icinga2` usually `/var/spool/icinga2`
1402 * `ICINGA2_INITRUNDIR`: Runtime data for the init system; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/run/icinga2` usually `/run/icinga2`
1403 * `ICINGA2_GIT_VERSION_INFO`: Whether to use Git to determine the version number; defaults to `ON`
1404 * `ICINGA2_USER`: The user Icinga 2 should run as; defaults to `icinga`
1405 * `ICINGA2_GROUP`: The group Icinga 2 should run as; defaults to `icinga`
1406 * `ICINGA2_COMMAND_GROUP`: The command group Icinga 2 should use; defaults to `icingacmd`
1407 * `ICINGA2_SYSCONFIGFILE`: Where to put the config file the initscript/systemd pulls it's dirs from;
1408 * defaults to `CMAKE_INSTALL_PREFIX/etc/sysconfig/icinga2`
1409 * `ICINGA2_PLUGINDIR`: The path for the Monitoring Plugins project binaries; defaults to `/usr/lib/nagios/plugins`
1410
1411 #### Build Optimization
1412
1413 * `ICINGA2_UNITY_BUILD`: Whether to perform a unity build; defaults to `ON`. Note: This requires additional memory and is not advised for building VMs, Docker for Mac and embedded hardware.
1414 * `ICINGA2_LTO_BUILD`: Whether to use link time optimization (LTO); defaults to `OFF`
1415
1416 #### Init System
1417
1418 * `USE_SYSTEMD=ON|OFF`: Use systemd or a classic SysV initscript; defaults to `OFF`
1419 * `INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT=ON|OFF` Force install both the systemd service definition file
1420   and the SysV initscript in parallel, regardless of how `USE_SYSTEMD` is set.
1421   Only use this for special packaging purposes and if you know what you are doing.
1422   Defaults to `OFF`.
1423
1424 #### Features
1425
1426 * `ICINGA2_WITH_CHECKER`: Determines whether the checker module is built; defaults to `ON`
1427 * `ICINGA2_WITH_COMPAT`: Determines whether the compat module is built; defaults to `ON`
1428 * `ICINGA2_WITH_LIVESTATUS`: Determines whether the Livestatus module is built; defaults to `ON`
1429 * `ICINGA2_WITH_NOTIFICATION`: Determines whether the notification module is built; defaults to `ON`
1430 * `ICINGA2_WITH_PERFDATA`: Determines whether the perfdata module is built; defaults to `ON`
1431 * `ICINGA2_WITH_TESTS`: Determines whether the unit tests are built; defaults to `ON`
1432
1433 #### MySQL or MariaDB
1434
1435 The following settings can be tuned for the MySQL / MariaDB IDO feature.
1436
1437 * `ICINGA2_WITH_MYSQL`: Determines whether the MySQL IDO module is built; defaults to `ON`
1438 * `MYSQL_CLIENT_LIBS`: Client implementation used (mysqlclient / mariadbclient); defaults searches for `mysqlclient` and `mariadbclient`
1439 * `MYSQL_INCLUDE_DIR`: Directory containing include files for the mysqlclient; default empty -
1440   checking multiple paths like `/usr/include/mysql`
1441
1442 See [FindMySQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindMySQL.cmake)
1443 for implementation details.
1444
1445 #### PostgreSQL
1446
1447 The following settings can be tuned for the PostgreSQL IDO feature.
1448
1449 * `ICINGA2_WITH_PGSQL`: Determines whether the PostgreSQL IDO module is built; defaults to `ON`
1450 * `PostgreSQL_INCLUDE_DIR`: Top-level directory containing the PostgreSQL include directories
1451 * `PostgreSQL_LIBRARY`: File path to PostgreSQL library : libpq.so (or libpq.so.[ver] file)
1452
1453 See [FindPostgreSQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindPostgreSQL.cmake)
1454 for implementation details.
1455
1456 #### Version detection
1457
1458 CMake determines the Icinga 2 version number using `git describe` if the
1459 source directory is contained in a Git repository. Otherwise the version number
1460 is extracted from the [VERSION](VERSION) file. This behavior can be
1461 overridden by creating a file called `icinga-version.h.force` in the source
1462 directory. Alternatively the `-DICINGA2_GIT_VERSION_INFO=OFF` option for CMake
1463 can be used to disable the usage of `git describe`.
1464
1465
1466 ### Building RPMs <a id="development-package-builds-rpms"></a>
1467
1468 #### Build Environment on RHEL, CentOS, Fedora, Amazon Linux
1469
1470 Setup your build environment:
1471
1472 ```
1473 yum -y install rpmdevtools
1474 ```
1475
1476 #### Build Environment on SuSE/SLES
1477
1478 SLES:
1479
1480 ```
1481 zypper addrepo http://download.opensuse.org/repositories/devel:tools/SLE_12_SP4/devel:tools.repo
1482 zypper refresh
1483 zypper install rpmdevtools spectool
1484 ```
1485
1486 OpenSuSE:
1487
1488 ```
1489 zypper addrepo http://download.opensuse.org/repositories/devel:tools/openSUSE_Leap_15.0/devel:tools.repo
1490 zypper refresh
1491 zypper install rpmdevtools spectool
1492 ```
1493
1494 #### Package Builds <a id="development-package-builds-rpms-package-builds"></a>
1495
1496 Prepare the rpmbuild directory tree:
1497
1498 ```
1499 cd $HOME
1500 rpmdev-setuptree
1501 ```
1502
1503 Snapshot builds:
1504
1505 ```
1506 curl https://raw.githubusercontent.com/Icinga/rpm-icinga2/master/icinga2.spec -o $HOME/rpmbuild/SPECS/icinga2.spec
1507 ```
1508
1509 > **Note**
1510 >
1511 > The above command builds snapshot packages. Change to the `release` branch
1512 > for release package builds.
1513
1514 Copy the tarball to `rpmbuild/SOURCES` e.g. by using the `spectool` binary
1515 provided with `rpmdevtools`:
1516
1517 ```
1518 cd $HOME/rpmbuild/SOURCES
1519 spectool -g ../SPECS/icinga2.spec
1520
1521 cd $HOME/rpmbuild
1522 ```
1523
1524 Install the build dependencies. Example for CentOS 7:
1525
1526 ```
1527 yum -y install libedit-devel ncurses-devel gcc-c++ libstdc++-devel openssl-devel \
1528 cmake flex bison boost-devel systemd mysql-devel postgresql-devel httpd \
1529 selinux-policy-devel checkpolicy selinux-policy selinux-policy-doc
1530 ```
1531
1532 Note: If you are using Amazon Linux, systemd is not required.
1533
1534 A shorter way is available using the `yum-builddep` command on RHEL based systems:
1535
1536 ```
1537 yum-builddep SPECS/icinga2.spec
1538 ```
1539
1540 Build the RPM:
1541
1542 ```
1543 rpmbuild -ba SPECS/icinga2.spec
1544 ```
1545
1546 #### Additional Hints <a id="development-package-builds-rpms-additional-hints"></a>
1547
1548 ##### SELinux policy module
1549
1550 The following packages are required to build the SELinux policy module:
1551
1552 * checkpolicy
1553 * selinux-policy (selinux-policy on CentOS 6, selinux-policy-devel on CentOS 7)
1554 * selinux-policy-doc
1555
1556 ##### RHEL/CentOS 6
1557
1558 The RedHat Developer Toolset is required for building Icinga 2 beforehand.
1559 This contains a modern version of flex and a C++ compiler which supports
1560 C++11 features.
1561 ```
1562 cat >/etc/yum.repos.d/devtools-2.repo <<REPO
1563 [testing-devtools-2-centos-\$releasever]
1564 name=testing 2 devtools for CentOS $releasever
1565 baseurl=https://people.centos.org/tru/devtools-2/\$releasever/\$basearch/RPMS
1566 gpgcheck=0
1567 REPO
1568 ```
1569
1570 Dependencies to devtools-2 are used in the RPM SPEC, so the correct tools
1571 should be used for building.
1572
1573 As an alternative, you can use newer Boost packages provided on
1574 [packages.icinga.com](https://packages.icinga.com/epel).
1575 ```
1576 cat >$HOME/.rpmmacros <<MACROS
1577 %build_icinga_org 1
1578 MACROS
1579 ```
1580
1581 ##### Amazon Linux
1582
1583 If you prefer to build packages offline, a suitable Vagrant box is located
1584 [here](https://atlas.hashicorp.com/mvbcoding/boxes/awslinux/).
1585
1586 ### Build Debian/Ubuntu packages <a id="development-package-builds-deb"></a>
1587
1588 Setup your build environment on Debian/Ubuntu, copy the 'debian' directory from
1589 the Debian packaging Git repository (https://github.com/Icinga/deb-icinga2)
1590 into your source tree and run the following command:
1591
1592 ```
1593 dpkg-buildpackage -uc -us
1594 ```
1595
1596 ### Build Alpine Linux packages <a id="development-package-builds-alpine"></a>
1597
1598 A simple way to setup a build environment is installing Alpine in a chroot.
1599 In this way, you can set up an Alpine build environment in a chroot under a
1600 different Linux distro.
1601 There is a script that simplifies these steps with just two commands, and
1602 can be found [here](https://github.com/alpinelinux/alpine-chroot-install).
1603
1604 Once the build environment is installed, you can setup the system to build
1605 the packages by following [this document](https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package).
1606
1607 ### Build Post Install Tasks <a id="development-package-builds-post-install-tasks"></a>
1608
1609 After building Icinga 2 yourself, your package build system should at least run the following post
1610 install requirements:
1611
1612 * enable the `checker`, `notification` and `mainlog` feature by default
1613 * run 'icinga2 api setup' in order to enable the `api` feature and generate SSL certificates for the node
1614
1615 ### Run Icinga 2 <a id="development-package-builds-run-icinga"></a>
1616
1617 Icinga 2 comes with a binary that takes care of loading all the relevant
1618 components (e.g. for check execution, notifications, etc.):
1619
1620 ```
1621 icinga2 daemon
1622
1623 [2016-12-08 16:44:24 +0100] information/cli: Icinga application loader (version: v2.5.4-231-gb10a6b7; debug)
1624 [2016-12-08 16:44:24 +0100] information/cli: Loading configuration file(s).
1625 [2016-12-08 16:44:25 +0100] information/ConfigItem: Committing config item(s).
1626 ...
1627 ```
1628
1629 #### Init Script <a id="development-package-builds-init-script"></a>
1630
1631 Icinga 2 can be started as a daemon using the provided init script:
1632
1633 ```
1634 /etc/init.d/icinga2
1635 Usage: /etc/init.d/icinga2 {start|stop|restart|reload|checkconfig|status}
1636 ```
1637
1638 #### Systemd <a id="development-package-builds-systemd"></a>
1639
1640 If your distribution uses systemd:
1641
1642 ```
1643 systemctl {start|stop|reload|status|enable|disable} icinga2
1644 ```
1645
1646 In case the distribution is running systemd >227, you'll also
1647 need to package and install the `etc/initsystem/icinga2.service.limits.conf`
1648 file into `/etc/systemd/system/icinga2.service.d`.
1649
1650 #### openrc <a id="development-package-builds-openrc"></a>
1651
1652 Or if your distribution uses openrc (like Alpine):
1653
1654 ```
1655 rc-service icinga2
1656 Usage: /etc/init.d/icinga2 {start|stop|restart|reload|checkconfig|status}
1657 ```
1658
1659 Note: the openrc's init.d is not shipped by default.
1660 A working init.d with openrc can be found here: (https://git.alpinelinux.org/cgit/aports/plain/community/icinga2/icinga2.initd). If you have customized some path, edit the file and adjust it according with your setup.
1661 Those few steps can be followed:
1662
1663 ```
1664 wget https://git.alpinelinux.org/cgit/aports/plain/community/icinga2/icinga2.initd
1665 mv icinga2.initd /etc/init.d/icinga2
1666 chmod +x /etc/init.d/icinga2
1667 ```
1668
1669 Icinga 2 reads a single configuration file which is used to specify all
1670 configuration settings (global settings, hosts, services, etc.). The
1671 configuration format is explained in detail in the [doc/](doc/) directory.
1672
1673 By default `make install` installs example configuration files in
1674 `/usr/local/etc/icinga2` unless you have specified a different prefix or
1675 sysconfdir.
1676
1677
1678 ### Windows Builds <a id="development-package-builds-windows"></a>
1679
1680 The Windows MSI packages are located at https://packages.icinga.com/windows/
1681
1682 #### Requirements <a id="development-package-builds-windows-requirements"></a>
1683
1684 * 32 or 64-bit system
1685 * Visual Studio >= 14 2015
1686 * CMake >= 2.6
1687 * OpenSSL >= 1.0.1
1688 * Flex and Bison
1689
1690 ##### Visual Studio
1691
1692 Download the community edition from [visualstudio.com](https://www.visualstudio.com/en/downloads/)
1693
1694 Workloads to install:
1695 * C++ Desktop
1696 * .NET Desktop
1697
1698 ##### OpenSSL for Icinga
1699
1700 Download custom OpenSSL builds from [openssl-windows GitHub project](https://github.com/Icinga/openssl-windows/releases).
1701
1702 You need to install a binary dist version to 'C:\\Program Files\\OpenSSL'.
1703
1704 The Powershell script `.\tools\win32\download-openssl.ps1` can be used for automated downloads.
1705
1706 ##### Chocolatey
1707
1708 A simple package manager for Windows, please see [install instructions](https://chocolatey.org/install).
1709
1710 ##### Git
1711
1712 Use Chocolatey, see [package details](https://chocolatey.org/packages/git).
1713
1714 ```
1715 choco install git
1716 ```
1717
1718 ##### Flex / Bison
1719
1720 Use Chocolatey, see [package details](https://chocolatey.org/packages/winflexbison3).
1721
1722 ```
1723 choco install winflexbison3
1724 ```
1725
1726 ##### CMake
1727
1728 Use Chocolatey, see [package details](https://chocolatey.org/packages/cmake)
1729 or download from: [cmake.org](https://cmake.org/download/)
1730
1731 ```
1732 choco install cmake
1733 ```
1734
1735 ##### WIX
1736
1737 Use Chocolatey, see [package details](https://chocolatey.org/packages/wixtoolset).
1738
1739 ```
1740 choco install wixtoolset
1741 ```
1742
1743 ##### Boost
1744
1745 Download third party Windows binaries from: [boost.org](http://www.boost.org/users/download/)
1746
1747 For example: `https://dl.bintray.com/boostorg/release/1.65.1/binaries/boost_1_65_1-msvc-14.1-64.exe`
1748
1749 *Warning:*
1750 * Must match your Visual Studio version!
1751 * CMake might not support the latest Boost version (we used CMake 3.10 and Boost 1_65_1)
1752
1753 Run the installer exe.
1754
1755
1756 #### Build Icinga 2
1757
1758 Run with VC Native x64 Command Prompt:
1759
1760 ```
1761 powershell .\tools\win32\configure.ps1
1762 powershell .\tools\win32\build.ps1
1763 powershell .\tools\win32\test.ps1
1764 ```
1765
1766 See these scripts for details.
1767
1768 #### CI: AppVeyor
1769
1770 We are building [Icinga 2 with AppVeyor](https://ci.appveyor.com/project/icinga/icinga2) for testing and CI integration.
1771
1772 Please check `appveyor.yml` for instructions.
1773
1774
1775
1776 ## Advanced Development Tips <a id="development-advanced"></a>
1777
1778 ### GDB Pretty Printers <a id="development-advanced-gdb-pretty-printer"></a>
1779
1780 Install the `boost`, `python` and `icinga2` pretty printers. Absolute paths are required,
1781 so please make sure to update the installation paths accordingly (`pwd`).
1782
1783 ```
1784 $ mkdir -p ~/.gdb_printers && cd ~/.gdb_printers
1785 ```
1786
1787 Boost Pretty Printers compatible with Python 3:
1788
1789 ```
1790 $ git clone https://github.com/mateidavid/Boost-Pretty-Printer.git && cd Boost-Pretty-Printer
1791 $ git checkout python-3
1792 $ pwd
1793 /home/michi/.gdb_printers/Boost-Pretty-Printer
1794 ```
1795
1796 Python Pretty Printers:
1797
1798 ```
1799 $ cd ~/.gdb_printers
1800 $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
1801 ```
1802
1803 Icinga 2 Pretty Printers:
1804
1805 ```
1806 $ mkdir -p ~/.gdb_printers/icinga2 && cd ~/.gdb_printers/icinga2
1807 $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/icingadbg.py
1808 ```
1809
1810 Now you'll need to modify/setup your `~/.gdbinit` configuration file.
1811 You can download the one from Icinga 2 and modify all paths.
1812
1813 Example on Fedora 22:
1814
1815 ```
1816 $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/gdbinit -O ~/.gdbinit
1817 $ vim ~/.gdbinit
1818
1819 set print pretty on
1820
1821 python
1822 import sys
1823 sys.path.insert(0, '/home/michi/.gdb_printers/icinga2')
1824 from icingadbg import register_icinga_printers
1825 register_icinga_printers()
1826 end
1827
1828 python
1829 import sys
1830 sys.path.insert(0, '/home/michi/.gdb_printers/python')
1831 from libstdcxx.v6.printers import register_libstdcxx_printers
1832 try:
1833     register_libstdcxx_printers(None)
1834 except:
1835     pass
1836 end
1837
1838 python
1839 import sys
1840 sys.path.insert(0, '/home/michi/.gdb_printers/Boost-Pretty-Printer')
1841 import boost_print
1842 boost_print.register_printers()
1843 end
1844 ```
1845
1846 If you are getting the following error when running gdb, the `libstdcxx`
1847 printers are already preloaded in your environment and you can remove
1848 the duplicate import in your `~/.gdbinit` file.
1849
1850 ```
1851 RuntimeError: pretty-printer already registered: libstdc++-v6
1852 ```
1853