From 403773d55a2a236943b9abd5269c522b75eb4bd6 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Mon, 31 May 2021 14:47:07 +1000 Subject: [PATCH] limnoria/meetbot setup on eavesdrop01.opendev.org This installs our Limnoira/meetbot container and configures it on eavesdrop01.opendev.org. I have ported the configuration from the old puppet as best I can (it is very verbose); my procedure was to use the Limnoira wizard to start a new config file then backport everything from the old file. I felt this was best to not miss any new options. This does channel logging (via built-in ChannelLogger plugin, along with a cron job for logs2html) and runs our fork of meetbot. It exports the channel logs via HTTP to /irclogs and meetings logs to /meetings. meetings.opendev.org will proxy to these two locations when the server is active. Note this has not ported the channel list; so the bot will not be listening in our channels. Change-Id: I9f9a466c271e1a706f9f98f816de0e84047519f1 --- inventory/service/groups.yaml | 1 + .../host_vars/eavesdrop01.opendev.org.yaml | 3 + .../handlers/main.yaml | 3 + playbooks/roles/limnoria/README.rst | 6 + playbooks/roles/limnoria/defaults/main.yaml | 176 ++ .../roles/limnoria/files/docker-compose.yaml | 18 + playbooks/roles/limnoria/handlers/main.yaml | 4 + playbooks/roles/limnoria/tasks/main.yaml | 72 + playbooks/roles/limnoria/tasks/webserver.yaml | 33 + .../limnoria/templates/limnoria.config.j2 | 1730 +++++++++++++++++ .../templates/meetingLocalConfig.py.j2 | 5 + .../roles/limnoria/templates/vhost.conf.j2 | 56 + playbooks/service-eavesdrop.yaml | 1 + zuul.d/docker-images/ircbot.yaml | 7 + zuul.d/project.yaml | 4 + zuul.d/system-config-run.yaml | 10 + 16 files changed, 2129 insertions(+) create mode 100644 inventory/service/host_vars/eavesdrop01.opendev.org.yaml create mode 100644 playbooks/roles/limnoria/README.rst create mode 100644 playbooks/roles/limnoria/defaults/main.yaml create mode 100644 playbooks/roles/limnoria/files/docker-compose.yaml create mode 100644 playbooks/roles/limnoria/handlers/main.yaml create mode 100644 playbooks/roles/limnoria/tasks/main.yaml create mode 100644 playbooks/roles/limnoria/tasks/webserver.yaml create mode 100644 playbooks/roles/limnoria/templates/limnoria.config.j2 create mode 100644 playbooks/roles/limnoria/templates/meetingLocalConfig.py.j2 create mode 100644 playbooks/roles/limnoria/templates/vhost.conf.j2 diff --git a/inventory/service/groups.yaml b/inventory/service/groups.yaml index adc8f2f3b9..fbef99357a 100644 --- a/inventory/service/groups.yaml +++ b/inventory/service/groups.yaml @@ -84,6 +84,7 @@ groups: - kdc04.openstack.org letsencrypt: - codesearch[0-9]*.opendev.org + - eavesdrop[0-9]*.opendev.org - etherpad[0-9]*.opendev.org - ethercalc[0-9]*.open*.org - gitea[0-9]*.opendev.org diff --git a/inventory/service/host_vars/eavesdrop01.opendev.org.yaml b/inventory/service/host_vars/eavesdrop01.opendev.org.yaml new file mode 100644 index 0000000000..0a68372edd --- /dev/null +++ b/inventory/service/host_vars/eavesdrop01.opendev.org.yaml @@ -0,0 +1,3 @@ +letsencrypt_certs: + eavesdrop01-opendev-org-main: + - eavesdrop01.opendev.org diff --git a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml index eabc2f589e..304285958f 100644 --- a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml +++ b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml @@ -11,6 +11,9 @@ # ("include_tasks" is okay). # https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html#imports-as-handlers +- name: letsencrypt updated eavesdrop01-opendev-org-main + include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml + - name: letsencrypt updated graphite02-main include_tasks: roles/letsencrypt-create-certs/handlers/restart_graphite.yaml diff --git a/playbooks/roles/limnoria/README.rst b/playbooks/roles/limnoria/README.rst new file mode 100644 index 0000000000..e9369c48f1 --- /dev/null +++ b/playbooks/roles/limnoria/README.rst @@ -0,0 +1,6 @@ +Setup limnoira and meetbot logging + +TODO + + * ubuntu-bots bug tracker to highlight bug links + * https://git.launchpad.net/~krytarik/ubuntu-bots/+git/ubuntu-bots/ diff --git a/playbooks/roles/limnoria/defaults/main.yaml b/playbooks/roles/limnoria/defaults/main.yaml new file mode 100644 index 0000000000..2873c88abb --- /dev/null +++ b/playbooks/roles/limnoria/defaults/main.yaml @@ -0,0 +1,176 @@ +limnoria_default_nick: opendevtest +limnoria_default_nickserv_password: 'abc123' +limnoria_default_user: 'Opendev IRC Services' +limnoria_directories_conf: /var/lib/limnoria/opendev/conf +limnoria_directories_data: /var/lib/limnoria/opendev/data +limnoria_directories_data_tmp: /var/lib/limnoria/opendev/data/tmp +limnoria_directories_data_web: /var/lib/limnoria/opendev/data/web +limnoria_directories_log: /var/lib/limnoria/opendev/logs + +limnoria_network_config: + oftc: + password: '' + servers: irc4.oftc.net:6697 + channels: '#opendev-sandbox' + ssl: 'True' + +# AVAILABLE SUPYBOT CONFIG KEYS: + +# ### +# # Determines what networks the bot will connect to. +# # +# # Default value: +# ### +# supybot.networks: {{ limnoria_networks }} + +# ### +# # Determines what certificate file (if any) the bot will use to connect +# # with SSL sockets to oftc. +# # +# # Default value: +# ### +# supybot.networks.oftc.certfile: + +# ### +# # Space-separated list of channels the bot will join only on oftc. +# # +# # Default value: +# ### +# supybot.networks.oftc.channels: #opendev + +# ### +# # Determines what key (if any) will be used to join the channel. +# # +# # Default value: +# ### +# supybot.networks.oftc.channels.key: + +# ### +# # Determines the bot's ident string, if the server doesn't provide one +# # by default. If empty, defaults to supybot.ident. +# # +# # Default value: +# ### +# supybot.networks.oftc.ident: + +# ### +# # Determines what nick the bot will use on this network. If empty, +# # defaults to supybot.nick. +# # +# # Default value: +# ### +# supybot.networks.oftc.nick: + +# ### +# # Determines what password will be used on oftc. Yes, we know that +# # technically passwords are server-specific and not network-specific, +# # but this is the best we can do right now. +# # +# # Default value: +# ### +# supybot.networks.oftc.password: + +# ### +# # Deprecated config value, keep it to False. +# # +# # Default value: False +# ### +# supybot.networks.oftc.requireStarttls: False + +# ### +# # Determines what SASL ECDSA key (if any) will be used on oftc. The +# # public key must be registered with NickServ for SASL ECDSA- +# # NIST256P-CHALLENGE to work. +# # +# # Default value: +# ### +# supybot.networks.oftc.sasl.ecdsa_key: + +# ### +# # Determines what SASL mechanisms will be tried and in which order. +# # +# # Default value: ecdsa-nist256p-challenge external plain +# ### +# supybot.networks.oftc.sasl.mechanisms: ecdsa-nist256p-challenge external plain + +# ### +# # Determines what SASL password will be used on oftc. +# # +# # Default value: +# ### +# supybot.networks.oftc.sasl.password: + +# ### +# # Determines whether the bot will abort the connection if the none of +# # the enabled SASL mechanism succeeded. +# # +# # Default value: False +# ### +# supybot.networks.oftc.sasl.required: False + +# ### +# # Determines what SASL username will be used on oftc. This should be the +# # bot's account name. +# # +# # Default value: +# ### +# supybot.networks.oftc.sasl.username: + +# ### +# # Space-separated list of servers the bot will connect to for oftc. Each +# # will be tried in order, wrapping back to the first when the cycle is +# # completed. +# # +# # Default value: +# ### +# supybot.networks.oftc.servers: irc.oftc.net:6697 + +# ### +# # If not empty, determines the hostname:port of the socks proxy that +# # will be used to connect to this network. +# # +# # Default value: +# ### +# supybot.networks.oftc.socksproxy: + +# ### +# # Determines whether the bot will attempt to connect with SSL sockets to +# # oftc. +# # +# # Default value: True +# ### +# supybot.networks.oftc.ssl: True + +# ### +# # A certificate that is trusted to verify certificates of this network +# # (aka. Certificate Authority). +# # +# # Default value: +# ### +# supybot.networks.oftc.ssl.authorityCertificate: + +# ### +# # Space-separated list of fingerprints of trusted certificates for this +# # network. Supported hash algorithms are: md5, sha1, sha224, sha256, +# # sha384, and sha512. If non-empty, Certification Authority signatures +# # will not be used to verify certificates. +# # +# # Default value: +# ### +# supybot.networks.oftc.ssl.serverFingerprints: + +# ### +# # Determines what user modes the bot will request from the server when +# # it first connects. If empty, defaults to supybot.protocols.irc.umodes +# # +# # Default value: +# ### +# supybot.networks.oftc.umodes: + +# ### +# # Determines the real name which the bot sends to the server. If empty, +# # defaults to supybot.user +# # +# # Default value: +# ### +# supybot.networks.oftc.user: diff --git a/playbooks/roles/limnoria/files/docker-compose.yaml b/playbooks/roles/limnoria/files/docker-compose.yaml new file mode 100644 index 0000000000..5635a4badd --- /dev/null +++ b/playbooks/roles/limnoria/files/docker-compose.yaml @@ -0,0 +1,18 @@ +# Version 2 is the latest that is supported by docker-compose in +# Ubuntu Xenial. +version: '2' + +services: + ircbot: + image: docker.io/opendevorg/ircbot:latest + network_mode: host + restart: always + logging: + driver: syslog + options: + tag: "docker-ircbot" + environment: + # This allows the meetbot plugin to find our config + PYTHONPATH: /var/lib/limnoria/ircmeeting + volumes: + - /var/lib/limnoria:/var/lib/limnoria diff --git a/playbooks/roles/limnoria/handlers/main.yaml b/playbooks/roles/limnoria/handlers/main.yaml new file mode 100644 index 0000000000..a7ec2ee0a4 --- /dev/null +++ b/playbooks/roles/limnoria/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: restart apache2 + service: + name: apache2 + state: restarted diff --git a/playbooks/roles/limnoria/tasks/main.yaml b/playbooks/roles/limnoria/tasks/main.yaml new file mode 100644 index 0000000000..e65389c880 --- /dev/null +++ b/playbooks/roles/limnoria/tasks/main.yaml @@ -0,0 +1,72 @@ +- name: Ensure /var/lib/limnoria directories + file: + state: directory + path: '/var/lib/{{ item }}' + mode: 0755 + loop: + - limnoria + - limnoria/opendev + +- name: Put limnoira config in place + template: + src: limnoria.config.j2 + dest: /var/lib/limnoria/limnoria.config + owner: root + group: root + mode: 0600 + +- name: Ensure /var/lib/limnoria/ircmeeting directory + file: + state: directory + path: /var/lib/limnoria/ircmeeting + mode: 0755 + +- name: Put meetbot local config in place + template: + src: meetingLocalConfig.py.j2 + dest: /var/lib/limnoria/ircmeeting/meetingLocalConfig.py + owner: root + group: root + mode: 0600 + +- name: Ensure /etc/ircbot-docker directory + file: + state: directory + path: /etc/ircbot-docker + mode: 0755 + +- name: Setup webserver + include_tasks: webserver.yaml + +- name: Put docker-compose file in place + copy: + src: docker-compose.yaml + dest: /etc/ircbot-docker/docker-compose.yaml + owner: root + group: root + mode: 0644 + +- name: 'Install logs2html cron job' + cron: + name: 'opendev {{ item.key }} logs2html' + state: present + user: root + job: >- + /usr/local/bin/docker-compose -f /etc/ircbot-docker/docker-compose.yaml exec -T ircbot + bash -c "find /var/lib/limnoria/opendev/logs/ChannelLogger/{{ item.key }}/ -mindepth 1 -maxdepth 1 -type d | xargs -n1 logs2html" + loop: '{{ limnoria_network_config | dict2items }}' + no_log: True + +- name: Run docker-compose pull + shell: + cmd: docker-compose pull + chdir: /etc/ircbot-docker/ + +- name: Run docker-compose up + shell: + cmd: "docker-compose up -d" + chdir: /etc/ircbot-docker/ + +- name: Run docker prune to cleanup unneeded images + shell: + cmd: docker image prune -f diff --git a/playbooks/roles/limnoria/tasks/webserver.yaml b/playbooks/roles/limnoria/tasks/webserver.yaml new file mode 100644 index 0000000000..b53ca8c2c1 --- /dev/null +++ b/playbooks/roles/limnoria/tasks/webserver.yaml @@ -0,0 +1,33 @@ +- name: Install Apache + package: + name: + - apache2 + - apache2-utils + state: present + +- name: Apache 2 ssl module + apache2_module: + state: present + name: ssl + +- name: Rewrite module + apache2_module: + state: present + name: rewrite + +- name: Create virtualhost + template: + src: vhost.conf.j2 + dest: /etc/apache2/sites-available/001-eavesdrop.conf + +- name: Disable default site + command: a2dissite 000-default.conf + args: + removes: /etc/apache2/sites-enabled/000-default.conf + +- name: Enable mirror virtual host + command: a2ensite 001-eavesdrop + args: + creates: /etc/apache2/sites-enabled/001-eavesdrop.conf + notify: + - restart apache2 diff --git a/playbooks/roles/limnoria/templates/limnoria.config.j2 b/playbooks/roles/limnoria/templates/limnoria.config.j2 new file mode 100644 index 0000000000..d9342ba3b3 --- /dev/null +++ b/playbooks/roles/limnoria/templates/limnoria.config.j2 @@ -0,0 +1,1730 @@ + +###### +# Although it is technically possible to do so, we do not recommend that +# you edit this file with a text editor. +# Whenever possible, do it on IRC using the Config plugin, which +# checks values you set are valid before writing them to the +# configuration. +# Moreover, if you edit this file while the bot is running, your +# changes may be lost. +###### + + +### +# Determines whether the bot will defend itself against command- +# flooding. +# +# Default value: True +### +supybot.abuse.flood.command: True + +### +# Determines whether the bot will defend itself against invalid command- +# flooding. +# +# Default value: True +### +supybot.abuse.flood.command.invalid: True + +### +# Determines how many invalid commands users are allowed per minute. If +# a user sends more than this many invalid commands in any 60 second +# period, they will be ignored for +# supybot.abuse.flood.command.invalid.punishment seconds. Typically, +# this value is lower than supybot.abuse.flood.command.maximum, since +# it's far less likely (and far more annoying) for users to flood with +# invalid commands than for them to flood with valid commands. +# +# Default value: 5 +### +supybot.abuse.flood.command.invalid.maximum: 5 + +### +# Determines whether the bot will notify people that they're being +# ignored for invalid command flooding. +# +# Default value: True +### +supybot.abuse.flood.command.invalid.notify: True + +### +# Determines how many seconds the bot will ignore users who flood it +# with invalid commands. Typically, this value is higher than +# supybot.abuse.flood.command.punishment, since it's far less likely +# (and far more annoying) for users to flood with invalid commands than +# for them to flood with valid commands. +# +# Default value: 600 +### +supybot.abuse.flood.command.invalid.punishment: 600 + +### +# Determines how many commands users are allowed per minute. If a user +# sends more than this many commands in any 60 second period, they will +# be ignored for supybot.abuse.flood.command.punishment seconds. +# +# Default value: 12 +### +supybot.abuse.flood.command.maximum: 12 + +### +# Determines whether the bot will notify people that they're being +# ignored for command flooding. +# +# Default value: True +### +supybot.abuse.flood.command.notify: True + +### +# Determines how many seconds the bot will ignore users who flood it +# with commands. +# +# Default value: 300 +### +supybot.abuse.flood.command.punishment: 300 + +### +# Determines the interval used for the history storage. +# +# Default value: 60 +### +supybot.abuse.flood.interval: 60 + +### +# Determines whether the bot will always join a channel when it's +# invited. If this value is False, the bot will only join a channel if +# the user inviting it has the 'admin' capability (or if it's explicitly +# told to join the channel using the Admin.join command). +# +# Default value: False +### +supybot.alwaysJoinOnInvite: False + +### +# These are the capabilities that are given to everyone by default. If +# they are normal capabilities, then the user will have to have the +# appropriate anti-capability if you want to override these +# capabilities; if they are anti-capabilities, then the user will have +# to have the actual capability to override these capabilities. See +# docs/CAPABILITIES if you don't understand why these default to what +# they do. +# +# Default value: -scheduler.add -alias.add -owner -scheduler.repeat -aka.remove -alias.remove -trusted -aka.set -admin -aka.add -scheduler.remove +### +supybot.capabilities: -scheduler.add -alias.add -owner -scheduler.repeat -admin -aka.remove -alias.remove -aka.set -trusted -aka.add -scheduler.remove + +### +# Determines whether the bot by default will allow users to have a +# capability. If this is disabled, a user must explicitly have the +# capability for whatever command they wish to run. To set this in a +# channel-specific way, use the 'channel capability setdefault' command. +# +# Default value: True +### +supybot.capabilities.default: True + +### +# Determines what capabilities the bot will never tell to a non-admin +# whether or not a user has them. +# +# Default value: +### +supybot.capabilities.private: + +### +# These are the capabilities that are given to every authenticated user +# by default. You probably want to use supybot.capabilities instead, to +# give these capabilities both to registered and non-registered users. +# +# Default value: +### +supybot.capabilities.registeredUsers: + +### +# Allows this bot's owner user to use commands that grants them shell +# access. This config variable exists in case you want to prevent MITM +# from the IRC network itself (vulnerable IRCd or IRCops) from gaining +# shell access to the bot's server by impersonating the owner. Setting +# this to False also disables plugins and commands that can be used to +# indirectly gain shell access. +# +# Default value: True +### +supybot.commands.allowShell: True + +### +# Determines what commands have default plugins set, and which plugins +# are set to be the default for each of those commands. +### +supybot.commands.defaultPlugins.addcapability: Admin +supybot.commands.defaultPlugins.capabilities: User +supybot.commands.defaultPlugins.disable: Owner +supybot.commands.defaultPlugins.enable: Owner +supybot.commands.defaultPlugins.help: Misc +supybot.commands.defaultPlugins.ignore: Admin + +### +# Determines what plugins automatically get precedence over all other +# plugins when selecting a default plugin for a command. By default, +# this includes the standard loaded plugins. You probably shouldn't +# change this if you don't know what you're doing; if you do know what +# you're doing, then also know that this set is case-sensitive. +# +# Default value: Admin Config Owner Channel User Misc +### +supybot.commands.defaultPlugins.importantPlugins: Channel Config Owner Admin User Misc +supybot.commands.defaultPlugins.list: Misc +supybot.commands.defaultPlugins.reload: Owner +supybot.commands.defaultPlugins.removecapability: Admin +supybot.commands.defaultPlugins.unignore: Admin + +### +# Determines what commands are currently disabled. Such commands will +# not appear in command lists, etc. They will appear not even to exist. +# +# Default value: +### +supybot.commands.disabled: + +### +# Determines whether the bot will allow nested commands, which rule. You +# definitely should keep this on. +# +# Default value: True +### +supybot.commands.nested: True + +### +# Supybot allows you to specify what brackets are used for your nested +# commands. Valid sets of brackets include [], <>, {}, and (). [] has +# strong historical motivation, but <> or () might be slightly superior +# because they cannot occur in a nick. If this string is empty, nested +# commands will not be allowed in this channel. +# +# Default value: [] +### +supybot.commands.nested.brackets: [] + +### +# Determines what the maximum number of nested commands will be; users +# will receive an error if they attempt commands more nested than this. +# +# Default value: 10 +### +supybot.commands.nested.maximum: 10 + +### +# Supybot allows nested commands. Enabling this option will allow nested +# commands with a syntax similar to UNIX pipes, for example: 'bot: foo | +# bar'. +# +# Default value: False +### +supybot.commands.nested.pipeSyntax: False + +### +# Determines what characters are valid for quoting arguments to commands +# in order to prevent them from being tokenized. +# +# Default value: " +### +supybot.commands.quotes: " + +### +# Determines what databases are available for use. If this value is not +# configured (that is, if its value is empty) then sane defaults will be +# provided. +# +# Default value: anydbm dbm cdb flat pickle +### +supybot.databases: + +### +# Determines what filename will be used for the channels database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: channels.conf +### +supybot.databases.channels.filename: channels.conf + +### +# Determines what filename will be used for the ignores database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: ignores.conf +### +supybot.databases.ignores.filename: ignores.conf + +### +# Determines what filename will be used for the networks database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: networks.conf +### +supybot.databases.networks.filename: networks.conf + +### +# Determines whether database-based plugins that can be channel-specific +# will be so. This can be overridden by individual channels. Do note +# that the bot needs to be restarted immediately after changing this +# variable or your db plugins may not work for your channel; also note +# that you may wish to set +# supybot.databases.plugins.channelSpecific.link appropriately if you +# wish to share a certain channel's databases globally. +# +# Default value: True +### +supybot.databases.plugins.channelSpecific: False + +### +# Determines what channel global (non-channel-specific) databases will +# be considered a part of. This is helpful if you've been running +# channel-specific for awhile and want to turn the databases for your +# primary channel into global databases. If +# supybot.databases.plugins.channelSpecific.link.allow prevents linking, +# the current channel will be used. Do note that the bot needs to be +# restarted immediately after changing this variable or your db plugins +# may not work for your channel. +# +# Default value: # +### +supybot.databases.plugins.channelSpecific.link: # + +### +# Determines whether another channel's global (non-channel-specific) +# databases will be allowed to link to this channel's databases. Do note +# that the bot needs to be restarted immediately after changing this +# variable or your db plugins may not work for your channel. +# +# Default value: True +### +supybot.databases.plugins.channelSpecific.link.allow: True + +### +# Determines whether the bot will require user registration to use 'add' +# commands in database-based Supybot plugins. +# +# Default value: True +### +supybot.databases.plugins.requireRegistration: True + +### +# Determines whether CDB databases will be allowed as a database +# implementation. +# +# Default value: True +### +supybot.databases.types.cdb: True + +### +# Determines how often CDB databases will have their modifications +# flushed to disk. When the number of modified records is greater than +# this fraction of the total number of records, the database will be +# entirely flushed to disk. +# +# Default value: 0.5 +### +supybot.databases.types.cdb.maximumModifications: 0.5 + +### +# Determines whether the bot will allow users to unregister their users. +# This can wreak havoc with already-existing databases, so by default we +# don't allow it. Enable this at your own risk. (Do also note that this +# does not prevent the owner of the bot from using the unregister +# command.) +# +# Default value: False +### +supybot.databases.users.allowUnregistration: False + +### +# Determines what filename will be used for the users database. This +# file will go into the directory specified by the +# supybot.directories.conf variable. +# +# Default value: users.conf +### +supybot.databases.users.filename: users.conf + +### +# Determines how long it takes identification to time out. If the value +# is less than or equal to zero, identification never times out. +# +# Default value: 0 +### +supybot.databases.users.timeoutIdentification: 0 + +### +# Determines whether the bot will automatically flush all flushers +# *very* often. Useful for debugging when you don't know what's breaking +# or when, but think that it might be logged. +# +# Default value: False +### +supybot.debug.flushVeryOften: False + +### +# Determines whether the bot will automatically thread all commands. +# +# Default value: False +### +supybot.debug.threadAllCommands: False + +### +# Determines whether the bot will ignore unidentified users by default. +# Of course, that'll make it particularly hard for those users to +# register or identify with the bot without adding their hostmasks, but +# that's your problem to solve. +# +# Default value: False +### +supybot.defaultIgnore: False + +### +# Determines what the default timeout for socket objects will be. This +# means that *all* sockets will timeout when this many seconds has gone +# by (unless otherwise modified by the author of the code that uses the +# sockets). +# +# Default value: 10 +### +supybot.defaultSocketTimeout: 10 + +### +# Determines what directory backup data is put into. Set it to /dev/null +# to disable backup (it is a special value, so it also works on Windows +# and systems without /dev/null). +# +# Default value: backup +### +supybot.directories.backup: /backup + +### +# Determines what directory configuration data is put into. +# +# Default value: conf +### +supybot.directories.conf: {{ limnoria_directories_conf }} + +### +# Determines what directory data is put into. +# +# Default value: data +### +supybot.directories.data: {{ limnoria_directories_data }} + +### +# Determines what directory temporary files are put into. +# +# Default value: tmp +### +supybot.directories.data.tmp: {{ limnoria_directories_data_tmp }} + +### +# Determines what directory files of the web server (templates, custom +# images, ...) are put into. +# +# Default value: web +### +supybot.directories.data.web: {{ limnoria_directories_data_web }} + +### +# Determines what directory the bot will store its logfiles in. +# +# Default value: logs +### +supybot.directories.log: {{ limnoria_directories_log }} + +### +# Determines what directories the bot will look for plugins in. Accepts +# a comma-separated list of strings. This means that to add another +# directory, you can nest the former value and add a new one. E.g. you +# can say: bot: 'config supybot.directories.plugins [config +# supybot.directories.plugins], newPluginDirectory'. +# +# Default value: +### +# supybot.directories.plugins: + +### +# Determines the maximum time the bot will wait before attempting to +# reconnect to an IRC server. The bot may, of course, reconnect earlier +# if possible. +# +# Default value: 300.0 +### +supybot.drivers.maxReconnectWait: 300.0 + +### +# Determines what driver module the bot will use. Current, the only (and +# default) driver is Socket. +# +# Default value: default +### +supybot.drivers.module: default + +### +# Determines the default length of time a driver should block waiting +# for input. +# +# Default value: 1.0 +### +supybot.drivers.poll: 1.0 + +### +# A string that is the external IP of the bot. If this is the empty +# string, the bot will attempt to find out its IP dynamically (though +# sometimes that doesn't work, hence this variable). This variable is +# not used by Limnoria and its built-in plugins: see +# supybot.protocols.irc.vhost / supybot.protocols.irc.vhost6 to set the +# IRC bind host, and supybot.servers.http.hosts4 / +# supybot.servers.http.hosts6 to set the HTTP server bind host. +# +# Default value: +### +supybot.externalIP: + +### +# Determines whether the bot will periodically flush data and +# configuration files to disk. Generally, the only time you'll want to +# set this to False is when you want to modify those configuration files +# by hand and don't want the bot to flush its current version over your +# modifications. Do note that if you change this to False inside the +# bot, your changes won't be flushed. To make this change permanent, you +# must edit the registry yourself. +# +# Default value: True +### +supybot.flush: True + +### +# Determines whether the bot will unidentify someone when that person +# changes their nick. Setting this to True will cause the bot to track +# such changes. It defaults to False for a little greater security. +# +# Default value: False +### +supybot.followIdentificationThroughNickChanges: False + +### +# Determines the bot's ident string, if the server doesn't provide one +# by default. +# +# Default value: limnoria +### +supybot.ident: limnoria + +### +# Determines the bot's default language if translations exist. Currently +# supported are 'de', 'en', 'es', 'fi', 'fr' and 'it'. +# +# Default value: en +### +supybot.language: en + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(name)s %(message)s +### +supybot.log.format: %(levelname)s %(asctime)s %(name)s %(message)s + +### +# Determines what the minimum priority level logged to file will be. Do +# note that this value does not affect the level logged to stdout; for +# that, you should set the value of supybot.log.stdout.level. Valid +# values are DEBUG, INFO, WARNING, ERROR, and CRITICAL, in order of +# increasing priority. +# +# Default value: INFO +### +supybot.log.level: DEBUG + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(message)s +### +supybot.log.plugins.format: %(levelname)s %(asctime)s %(message)s + +### +# Determines whether the bot will separate plugin logs into their own +# individual logfiles. +# +# Default value: False +### +supybot.log.plugins.individualLogfiles: False + +### +# Determines whether the bot will log to stdout. +# +# Default value: True +### +supybot.log.stdout: True + +### +# Determines whether the bot's logs to stdout (if enabled) will be +# colorized with ANSI color. +# +# Default value: False +### +supybot.log.stdout.colorized: True + +### +# Determines what the bot's logging format will be. The relevant +# documentation on the available formattings is Python's documentation +# on its logging module. +# +# Default value: %(levelname)s %(asctime)s %(message)s +### +supybot.log.stdout.format: %(levelname)s %(asctime)s %(message)s + +### +# Determines what the minimum priority level logged will be. Valid +# values are DEBUG, INFO, WARNING, ERROR, and CRITICAL, in order of +# increasing priority. +# +# Default value: INFO +### +supybot.log.stdout.level: INFO + +### +# Determines whether the bot will wrap its logs when they're output to +# stdout. +# +# Default value: False +### +supybot.log.stdout.wrap: False + +### +# Determines the format string for timestamps in logfiles. Refer to the +# Python documentation for the time module to see what formats are +# accepted. If you set this variable to the empty string, times will be +# logged in a simple seconds-since-epoch format. +# +# Default value: %Y-%m-%dT%H:%M:%S +### +supybot.log.timestampFormat: %Y-%m-%dT%H:%M:%S + +supybot.networks: {{ limnoria_network_config.keys() | join(' ') }} + +{% for network,settings in limnoria_network_config.items() %} +{% for key, value in settings.items() %} +supybot.networks.{{ network }}.{{ key }}: {{ value }} +{% endfor %} +{% endfor %} + +### +# Determines the bot's default nick. +# +# Default value: supybot +### +supybot.nick: {{ limnoria_default_nick }} + +### +# Determines what alternative nicks will be used if the primary nick +# (supybot.nick) isn't available. A %s in this nick is replaced by the +# value of supybot.nick when used. If no alternates are given, or if all +# are used, the supybot.nick will be perturbed appropriately until an +# unused nick is found. +# +# Default value: %s` %s_ +### +supybot.nick.alternates: %s` %s_ + +### +# Determines what file the bot should write its PID (Process ID) to, so +# you can kill it more easily. If it's left unset (as is the default) +# then no PID file will be written. A restart is required for changes to +# this variable to take effect. +# +# Default value: +### +supybot.pidFile: + +### +# List of all plugins that were ever loaded. Currently has no effect +# whatsoever. You probably want to use the 'load' or 'unload' commands, +# or edit supybot.plugins. instead of this. +# +# Default value: +### +supybot.plugins: + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Admin: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Admin.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.AutoMode: True + +### +# Determines whether the bot will check for 'alternative capabilities' +# (ie. autoop, autohalfop, autovoice) in addition to/instead of classic +# ones. +# +# Default value: True +### +supybot.plugins.AutoMode.alternativeCapabilities: True + +### +# Determines whether the bot will automatically ban people who join the +# channel and are on the banlist. +# +# Default value: True +### +supybot.plugins.AutoMode.ban: True + +### +# Determines how many seconds the bot will automatically ban a person +# when banning. +# +# Default value: 86400 +### +supybot.plugins.AutoMode.ban.period: 86400 + +### +# Determines how many seconds the bot will wait before applying a mode. +# Has no effect on bans. +# +# Default value: 0 +### +supybot.plugins.AutoMode.delay: 0 + +### +# Determines whether this plugin is enabled. +# +# Default value: True +### +supybot.plugins.AutoMode.enable: True + +### +# Extra modes that will be applied to a user. Example syntax: user1+o-v +# user2+v user3-v +# +# Default value: +### +supybot.plugins.AutoMode.extra: + +### +# Determines whether the bot will "fall through" to halfop/voicing when +# auto-opping is turned off but auto-halfopping/voicing are turned on. +# +# Default value: True +### +supybot.plugins.AutoMode.fallthrough: True + +### +# Determines whether the bot will automatically halfop people with the +# ,halfop capability when they join the channel. +# +# Default value: False +### +supybot.plugins.AutoMode.halfop: False + +### +# Determines whether the bot will automatically op people with the +# ,op capability when they join the channel. +# +# Default value: False +### +supybot.plugins.AutoMode.op: False + +### +# Determines whether this plugin will automode owners even if they don't +# have op/halfop/voice/whatever capability. +# +# Default value: False +### +supybot.plugins.AutoMode.owner: False + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.AutoMode.public: True + +### +# Determines whether the bot will automatically voice people with the +# ,voice capability when they join the channel. +# +# Default value: False +### +supybot.plugins.AutoMode.voice: False + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Channel: True + +### +# Determines whether the bot will always try to rejoin a channel +# whenever it's kicked from the channel. +# +# Default value: True +### +supybot.plugins.Channel.alwaysRejoin: True + +### +# Determines whether the output of 'nicks' will be sent in private. This +# prevents mass-highlights of a channel's users, accidental or on +# purpose. +# +# Default value: True +### +supybot.plugins.Channel.nicksInPrivate: True + +### +# Determines what part message should be used by default. If the part +# command is called without a part message, this will be used. If this +# value is empty, then no part message will be used (they are optional +# in the IRC protocol). The standard substitutions ($version, $nick, +# etc.) are all handled appropriately. +# +# Default value: Limnoria $version +### +supybot.plugins.Channel.partMsg: Limnoria $version + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Channel.public: True + +### +# Determines how many seconds the bot will wait before rejoining a +# channel if kicked and supybot.plugins.Channel.alwaysRejoin is on. +# +# Default value: 0 +### +supybot.plugins.Channel.rejoinDelay: 0 + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Config: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Config.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Misc: True + +### +# Sets a custom help string, displayed when the 'help' command is called +# without arguments. +# +# Default value: +### +supybot.plugins.Misc.customHelpString: + +### +# Determines whether or not the nick will be included in the output of +# last when it is part of a nested command +# +# Default value: False +### +supybot.plugins.Misc.last.nested.includeNick: False + +### +# Determines whether or not the timestamp will be included in the output +# of last when it is part of a nested command +# +# Default value: False +### +supybot.plugins.Misc.last.nested.includeTimestamp: False + +### +# Determines whether the bot will list private plugins with the list +# command if given the --private switch. If this is disabled, non-owner +# users should be unable to see what private plugins are loaded. +# +# Default value: False +### +supybot.plugins.Misc.listPrivatePlugins: False + +### +# Determines whether the bot will list unloaded plugins with the list +# command if given the --unloaded switch. If this is disabled, non-owner +# users should be unable to see what unloaded plugins are available. +# +# Default value: False +### +supybot.plugins.Misc.listUnloadedPlugins: False + +### +# Determines how many messages the bot will issue when using the 'more' +# command. +# +# Default value: 1 +### +supybot.plugins.Misc.mores: 1 + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Misc.public: True + +### +# Determines the format string for timestamps in the Misc.last command. +# Refer to the Python documentation for the time module to see what +# formats are accepted. If you set this variable to the empty string, +# the timestamp will not be shown. +# +# Default value: [%H:%M:%S] +### +supybot.plugins.Misc.timestampFormat: [%H:%M:%S] + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Network: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Network.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.NickAuth: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.NickAuth.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Owner: True + +### +# Determines the format of messages sent by the 'announce' command. +# $owner may be used for the username of the owner calling this command, +# and $text for the announcement being made. +# +# Default value: Announcement from my owner ($owner): $text +### +supybot.plugins.Owner.announceFormat: Announcement from my owner ($owner): $text + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Owner.public: True + +### +# Determines what quit message will be used by default. If the quit +# command is called without a quit message, this will be used. If this +# value is empty, the nick of the person giving the quit command will be +# used. The standard substitutions ($version, $nick, etc.) are all +# handled appropriately. +# +# Default value: Limnoria $version +### +supybot.plugins.Owner.quitMsg: Limnoria $version + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.User: True + +### +# Determines what message the bot sends when a user isn't identified or +# recognized. +# +# Default value: +### +supybot.plugins.User.customWhoamiError: + +### +# Determines whether the output of 'user list' will be sent in private. +# This prevents mass-highlights of people who use their nick as their +# bot username. +# +# Default value: True +### +supybot.plugins.User.listInPrivate: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.User.public: True + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.Utilities: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.Utilities.public: True + +### +# Determines whether the bot will always load important plugins (Admin, +# Channel, Config, Misc, Owner, and User) regardless of what their +# configured state is. Generally, if these plugins are configured not to +# load, you didn't do it on purpose, and you still want them to load. +# Users who don't want to load these plugins are smart enough to change +# the value of this variable appropriately :) +# +# Default value: True +### +supybot.plugins.alwaysLoadImportant: True + +### +# Determines how many bytes the bot will 'peek' at when looking through +# a URL for a doctype or title or something similar. It'll give up after +# it reads this many bytes, even if it hasn't found what it was looking +# for. +# +# Default value: 8192 +### +supybot.protocols.http.peekSize: 8192 + +### +# Determines what HTTP proxy all HTTP requests should go through. The +# value should be of the form 'host:port'. +# +# Default value: +### +supybot.protocols.http.proxy: + +### +# If set, the Accept-Language HTTP header will be set to this value for +# requests. Useful for overriding the auto-detected language based on +# the server's location. +# +# Default value: +### +supybot.protocols.http.requestLanguage: + +### +# If set, the User-Agent HTTP header will be set to a randomly selected +# value from this comma-separated list of strings for requests. +# +# Default value: +### +supybot.protocols.http.userAgents: + +### +# Determines what will be used as the default banmask style. +# +# Default value: host +### +supybot.protocols.irc.banmask: host + +### +# Determines what certificate file (if any) the bot will use connect +# with SSL sockets by default. +# +# Default value: +### +supybot.protocols.irc.certfile: + +### +# Determines whether the bot will enable draft/experimental extensions +# of the IRC protocol. Setting this to True may break your bot at any +# time without warning and/or break your configuration irreversibly. So +# keep it False unless you know what you are doing. +# +# Default value: False +### +supybot.protocols.irc.experimentalExtensions: False + +### +# Determines how many old messages the bot will keep around in its +# history. Changing this variable will not take effect on a network +# until it is reconnected. +# +# Default value: 1000 +### +supybot.protocols.irc.maxHistoryLength: 1000 + +### +# Determines whether the bot will send PINGs to the server it's +# connected to in order to keep the connection alive and discover +# earlier when it breaks. Really, this option only exists for debugging +# purposes: you always should make it True unless you're testing some +# strange server issues. +# +# Default value: True +### +supybot.protocols.irc.ping: True + +### +# Determines the number of seconds between sending pings to the server, +# if pings are being sent to the server. +# +# Default value: 120 +### +supybot.protocols.irc.ping.interval: 120 + +### +# Determines whether the bot will refuse duplicated messages to be +# queued for delivery to the server. This is a safety mechanism put in +# place to prevent plugins from sending the same message multiple times; +# most of the time it doesn't matter, unless you're doing certain kinds +# of plugin hacking. +# +# Default value: False +### +supybot.protocols.irc.queuing.duplicates: False + +### +# Determines how many seconds must elapse between JOINs sent to the +# server. +# +# Default value: 0.0 +### +supybot.protocols.irc.queuing.rateLimit.join: 0.0 + +### +# Determines whether the bot will strictly follow the RFC; currently +# this only affects what strings are considered to be nicks. If you're +# using a server or a network that requires you to message a nick such +# as services@this.network.server then you you should set this to False. +# +# Default value: False +### +supybot.protocols.irc.strictRfc: False + +### +# A floating point number of seconds to throttle queued messages -- that +# is, messages will not be sent faster than once per throttleTime +# seconds. +# +# Default value: 1.0 +### +supybot.protocols.irc.throttleTime: 1.0 + +### +# Determines what user modes the bot will request from the server when +# it first connects. Many people might choose +i; some networks allow +# +x, which indicates to the auth services on those networks that you +# should be given a fake host. +# +# Default value: +### +supybot.protocols.irc.umodes: + +### +# Determines what vhost the bot will bind to before connecting a server +# (IRC, HTTP, ...) via IPv4. +# +# Default value: +### +supybot.protocols.irc.vhost: + +### +# Determines what vhost the bot will bind to before connecting a server +# (IRC, HTTP, ...) via IPv6. +# +# Default value: +### +supybot.protocols.irc.vhostv6: + +### +# Determines whether server certificates will be verified, which checks +# whether the server certificate is signed by a known certificate +# authority, and aborts the connection if it is not. This is assumed to +# be True of serverFingerprints or authorityCertificate is set. +# +# Default value: False +### +supybot.protocols.ssl.verifyCertificates: False + +### +# Format used by generic database plugins (Lart, Dunno, Prase, Success, +# Quote, ...) to show an entry. You can use the following variables: +# $type/$types/$Type/$Types (plugin name and variants), $id, $text, $at +# (creation time), $userid/$username/$nick (author). +# +# Default value: $Type #$id: $text (added by $username at $at) +### +supybot.replies.databaseRecord: $Type #$id: $text (added by $username at $at) + +### +# Determines what error message the bot gives when it wants to be +# ambiguous. +### +supybot.replies.error: An error has occurred and has been logged. Please\ + contact this bot's administrator for more\ + information. + +### +# Determines what error message the bot gives to the owner when it wants +# to be ambiguous. +### +supybot.replies.errorOwner: An error has occurred and has been logged. Check\ + the logs for more information. + +### +# Determines what generic error message is given when the bot is telling +# someone that they aren't cool enough to use the command they tried to +# use, and the author of the code calling errorNoCapability didn't +# provide an explicit capability for whatever reason. +### +supybot.replies.genericNoCapability: You're missing some capability you\ + need. This could be because you\ + actually possess the anti-capability\ + for the capability that's required of\ + you, or because the channel provides\ + that anti-capability by default, or\ + because the global capabilities include\ + that anti-capability. Or, it could be\ + because the channel or\ + supybot.capabilities.default is set to\ + False, meaning that no commands are\ + allowed unless explicitly in your\ + capabilities. Either way, you can't do\ + what you want to do. + +### +# Determines what message the bot replies with when someone tries to use +# a command that requires being identified or having a password and +# neither credential is correct. +### +supybot.replies.incorrectAuthentication: Your hostmask doesn't match or your\ + password is wrong. + +### +# Determines what error message is given when the bot is telling someone +# they aren't cool enough to use the command they tried to use. +### +supybot.replies.noCapability: You don't have the %s capability. If you think\ + that you should have this capability, be sure\ + that you are identified before trying again.\ + The 'whoami' command can tell you if you're\ + identified. + +### +# Determines what error message the bot replies with when someone tries +# to accessing some information on a user the bot doesn't know about. +### +supybot.replies.noUser: I can't find %s in my user database. If you didn't\ + give a user name, then I might not know what your\ + user is, and you'll need to identify before this\ + command might work. + +### +# Determines what error message the bot replies with when someone tries +# to do something that requires them to be registered but they're not +# currently recognized. +### +supybot.replies.notRegistered: You must be registered to use this command.\ + If you are already registered, you must\ + either identify (using the identify command)\ + or add a hostmask matching your current\ + hostmask (using the "hostmask add" command). + +### +# Determines what message the bot sends when it thinks you've +# encountered a bug that the developers don't know about. +### +supybot.replies.possibleBug: This may be a bug. If you think it is, please\ + file a bug report at\ + . + +### +# Determines what error messages the bot sends to people who try to do +# things in a channel that really should be done in private. +### +supybot.replies.requiresPrivacy: That operation cannot be done in a channel. + +### +# Determines what message the bot replies with when a command succeeded. +# If this configuration variable is empty, no success message will be +# sent. +### +supybot.replies.success: The operation succeeded. + +### +# Determines whether error messages that result from bugs in the bot +# will show a detailed error message (the uncaught exception) or a +# generic error message. +# +# Default value: False +### +supybot.reply.error.detailed: False + +### +# Determines whether the bot will send error messages to users in +# private. You might want to do this in order to keep channel traffic to +# minimum. This can be used in combination with +# supybot.reply.error.withNotice. +# +# Default value: False +### +supybot.reply.error.inPrivate: False + +### +# Determines whether the bot will *not* provide details in the error +# message to users who attempt to call a command for which they do not +# have the necessary capability. You may wish to make this True if you +# don't want users to understand the underlying security system +# preventing them from running certain commands. +# +# Default value: False +### +supybot.reply.error.noCapability: False + +### +# Determines whether the bot will send error messages to users via +# NOTICE instead of PRIVMSG. You might want to do this so users can +# ignore NOTICEs from the bot and not have to see error messages; or you +# might want to use it in combination with supybot.reply.errorInPrivate +# so private errors don't open a query window in most IRC clients. +# +# Default value: False +### +supybot.reply.error.withNotice: False + +### +# Maximum number of items in a list before the end is replaced with 'and +# others'. Set to 0 to always show the entire list. +# +# Default value: 0 +### +supybot.reply.format.list.maximumItems: 0 + +### +# Determines how timestamps printed for human reading should be +# formatted. Refer to the Python documentation for the time module to +# see valid formatting characters for time formats. +# +# Default value: %Y-%m-%dT%H:%M:%S%z +### +supybot.reply.format.time: %Y-%m-%dT%H:%M:%S%z + +### +# Determines whether elapsed times will be given as "1 day, 2 hours, 3 +# minutes, and 15 seconds" or as "1d 2h 3m 15s". +# +# Default value: False +### +supybot.reply.format.time.elapsed.short: False + +### +# Determines how urls should be formatted. +# +# Default value: <%s> +### +supybot.reply.format.url: <%s> + +### +# Determines whether the bot will reply privately when replying in a +# channel, rather than replying to the whole channel. +# +# Default value: False +### +supybot.reply.inPrivate: False + +### +# Determines the absolute maximum length of the bot's reply -- no reply +# will be passed through the bot with a length greater than this. +# +# Default value: 131072 +### +supybot.reply.maximumLength: 131072 + +### +# Determines whether the bot will break up long messages into chunks and +# allow users to use the 'more' command to get the remaining chunks. +# +# Default value: True +### +supybot.reply.mores: True + +### +# Determines how many mores will be sent instantly (i.e., without the +# use of the more command, immediately when they are formed). Defaults +# to 1, which means that a more command will be required for all but the +# first chunk. +# +# Default value: 1 +### +supybot.reply.mores.instant: 1 + +### +# Determines how long individual chunks will be. If set to 0, uses our +# super-tweaked, get-the-most-out-of-an-individual-message default. +# +# Default value: 0 +### +supybot.reply.mores.length: 0 + +### +# Determines what the maximum number of chunks (for use with the 'more' +# command) will be. +# +# Default value: 50 +### +supybot.reply.mores.maximum: 50 + +### +# Determines whether the bot will send multi-message replies in a single +# message. This defaults to True in order to prevent the bot from +# flooding. If this is set to False the bot will send multi-message +# replies on multiple lines. +# +# Default value: True +### +supybot.reply.oneToOne: True + +### +# Determines whether the bot will allow you to send channel-related +# commands outside of that channel. Sometimes people find it confusing +# if a channel-related command (like Filter.outfilter) changes the +# behavior of the channel but was sent outside the channel itself. +# +# Default value: False +### +supybot.reply.requireChannelCommandsToBeSentInChannel: False + +### +# Supybot normally replies with the full help whenever a user misuses a +# command. If this value is set to True, the bot will only reply with +# the syntax of the command (the first line of the help) rather than the +# full help. +# +# Default value: False +### +supybot.reply.showSimpleSyntax: False + +### +# Determines what prefix characters the bot will reply to. A prefix +# character is a single character that the bot will use to determine +# what messages are addressed to it; when there are no prefix characters +# set, it just uses its nick. Each character in this string is +# interpreted individually; you can have multiple prefix chars +# simultaneously, and if any one of them is used as a prefix the bot +# will assume it is being addressed. +# +# Default value: +### +supybot.reply.whenAddressedBy.chars: ! + +### +# Determines whether the bot will reply when people address it by its +# nick, rather than with a prefix character. +# +# Default value: True +### +supybot.reply.whenAddressedBy.nick: True + +### +# Determines whether the bot will reply when people address it by its +# nick at the end of the message, rather than at the beginning. +# +# Default value: False +### +supybot.reply.whenAddressedBy.nick.atEnd: False + +### +# Determines what extra nicks the bot will always respond to when +# addressed by, even if its current nick is something else. +# +# Default value: +### +supybot.reply.whenAddressedBy.nicks: + +### +# Determines what strings the bot will reply to when they are at the +# beginning of the message. Whereas prefix.chars can only be one +# character (although there can be many of them), this variable is a +# space-separated list of strings, so you can set something like '@@ ??' +# and the bot will reply when a message is prefixed by either @@ or ??. +# +# Default value: +### +supybot.reply.whenAddressedBy.strings: + +### +# Determines whether the bot should attempt to reply to all messages +# even if they don't address it (either via its nick or a prefix +# character). If you set this to True, you almost certainly want to set +# supybot.reply.whenNotCommand to False. +# +# Default value: False +### +supybot.reply.whenNotAddressed: False + +### +# Determines whether the bot will reply with an error message when it is +# addressed but not given a valid command. If this value is False, the +# bot will remain silent, as long as no other plugins override the +# normal behavior. +# +# Default value: True +### +supybot.reply.whenNotCommand: True + +### +# Determines whether the bot will always prefix the user's nick to its +# reply to that user's command. +# +# Default value: True +### +supybot.reply.withNickPrefix: True + +### +# Determines whether the bot will reply with a notice when replying in a +# channel, rather than replying with a privmsg as normal. +# +# Default value: False +### +supybot.reply.withNotice: False + +### +# Determines whether the bot will reply with a notice when it is sending +# a private message, in order not to open a /query window in clients. +# +# Default value: True +### +supybot.reply.withNoticeWhenPrivate: True + +### +# Determines the path of the file served as favicon to browsers. +# +# Default value: +### +supybot.servers.http.favicon: + +### +# Space-separated list of IPv4 hosts the HTTP server will bind. +# +# Default value: 0.0.0.0 +### +supybot.servers.http.hosts4: 0.0.0.0 + +### +# Space-separated list of IPv6 hosts the HTTP server will bind. +# +# Default value: ::0 +### +supybot.servers.http.hosts6: ::0 + +### +# Determines whether the server will stay alive if no plugin is using +# it. This also means that the server will start even if it is not used. +# +# Default value: False +### +supybot.servers.http.keepAlive: False + +### +# Determines what port the HTTP server will bind. +# +# Default value: 8080 +### +supybot.servers.http.port: 8080 + +### +# Determines the public URL of the server. By default it is +# http://:/, but you will want to change this if there +# is a reverse proxy (nginx, apache, ...) in front of the bot. +# +# Default value: +### +supybot.servers.http.publicUrl: + +### +# If true, uses IPV6_V6ONLY to disable forwaring of IPv4 traffic to IPv6 +# sockets. On *nix, has the same effect as setting kernel variable +# net.ipv6.bindv6only to 1. +# +# Default value: True +### +supybot.servers.http.singleStack: True + +### +# A floating point number of seconds to throttle snarfed URLs, in order +# to prevent loops between two bots snarfing the same URLs and having +# the snarfed URL in the output of the snarf message. +# +# Default value: 10.0 +### +supybot.snarfThrottle: 10.0 + +### +# Determines the number of seconds between running the upkeep function +# that flushes (commits) open databases, collects garbage, and records +# some useful statistics at the debugging level. +# +# Default value: 3600 +### +supybot.upkeepInterval: 3600 + +### +# Determines the real name which the bot sends to the server. A standard +# real name using the current version of the bot will be generated if +# this is left empty. +# +# Default value: Limnoria $version +### +supybot.user: {{ limnoria_default_user }} + +### +# Determines whether this plugin is loaded by default. +### +supybot.plugins.ChannelLogger: True + +### +# Determines whether this plugin is publicly visible. +# +# Default value: True +### +supybot.plugins.ChannelLogger.public: True + +### +# Determines whether logging is enabled. +# +# Default value: True +### +supybot.plugins.ChannelLogger.enable: True + +### +# Determines whether channel logfiles will be flushed anytime they're +# written to, rather than being buffered by the operating system. +# +# Default value: False +### +supybot.plugins.ChannelLogger.flushImmediately: False + +### +# Determines whether formatting characters (such as bolding, color, +# etc.) are removed when writing the logs to disk. +# +# Default value: True +### +supybot.plugins.ChannelLogger.stripFormatting: True + +### +# Determines whether the logs for this channel are timestamped with the +# timestamp in supybot.log.timestampFormat. +# +# Default value: True +### +supybot.plugins.ChannelLogger.timestamp: True + +### +# Determines what string a message should be prefixed with in order not +# to be logged. If you don't want any such prefix, just set it to the +# empty string. +# +# Default value: [nolog] +### +supybot.plugins.ChannelLogger.noLogPrefix: [nolog] + +### +# Determines whether the bot will automatically rotate the logs for this +# channel. The bot will rotate logs when the timestamp for the log +# changes. The timestamp is set according to the 'filenameTimestamp' +# configuration variable. +# +# Default value: False +### +supybot.plugins.ChannelLogger.rotateLogs: True + +### +# Determines how to represent the timestamp used for the filename in +# rotated logs. When this timestamp changes, the old logfiles will be +# closed and a new one started. The format characters for the timestamp +# are in the time.strftime docs at python.org. In order for your logs to +# be rotated, you'll also have to enable +# supybot.plugins.ChannelLogger.rotateLogs. +# +# Default value: %Y-%m-%d +### +supybot.plugins.ChannelLogger.filenameTimestamp: %Y-%m-%d + +### +# Determines whether the bot will partition its channel logs into +# separate directories based on different criteria. +# +# Default value: True +### +supybot.plugins.ChannelLogger.directories: True + +### +# Determines whether the bot will use a network directory if using +# directories. +# +# Default value: True +### +supybot.plugins.ChannelLogger.directories.network: True + +### +# Determines whether the bot will use a channel directory if using +# directories. +# +# Default value: True +### +supybot.plugins.ChannelLogger.directories.channel: True + +### +# Determines whether the bot will use a timestamp (determined by +# supybot.plugins.ChannelLogger.directories.timestamp.format) if using +# directories. +# +# Default value: False +### +supybot.plugins.ChannelLogger.directories.timestamp: False + +### +# Determines what timestamp format will be used in the directory +# stucture for channel logs if +# supybot.plugins.ChannelLogger.directories.timestamp is True. +# +# Default value: %B +### +supybot.plugins.ChannelLogger.directories.timestamp.format: %B + +# Meetbot +supybot.plugins.MeetBot: True +supybot.plugins.MeetBot.public: True +supybot.plugins.MeetBot.enableSupybotBasedConfig: False + +# NickServ +supybot.plugins.Services.NickServ: NickServ +supybot.plugins.Services.NickServ.password.{{ limnoria_default_nick }}: {{ limnoria_default_nickserv_password }} diff --git a/playbooks/roles/limnoria/templates/meetingLocalConfig.py.j2 b/playbooks/roles/limnoria/templates/meetingLocalConfig.py.j2 new file mode 100644 index 0000000000..54df8eb170 --- /dev/null +++ b/playbooks/roles/limnoria/templates/meetingLocalConfig.py.j2 @@ -0,0 +1,5 @@ +class Config(object): + # These two are **required**: + logFileDir = '/var/lib/limnoria/opendev/meetings/' + logUrlPrefix = 'https://eavesdrop.opendev.org/meetings/' + filenamePattern = '%(meetingname)s/%%Y/%(meetingname)s.%%F-%%H.%%M' diff --git a/playbooks/roles/limnoria/templates/vhost.conf.j2 b/playbooks/roles/limnoria/templates/vhost.conf.j2 new file mode 100644 index 0000000000..c3ba0ed652 --- /dev/null +++ b/playbooks/roles/limnoria/templates/vhost.conf.j2 @@ -0,0 +1,56 @@ + + ServerName {{ inventory_hostname }} + + ErrorLog /var/log/apache2/{{ inventory_hostname }}_error.log + LogLevel warn + CustomLog /var/log/apache2/{{ inventory_hostname }}_access.log combined + ServerSignature Off + + Redirect / https://{{ inventory_hostname }}/ + + + + + + ServerName {{ inventory_hostname }} + + SSLEngine on + + SSLCertificateFile /etc/letsencrypt-certs/{{ inventory_hostname }}/{{ inventory_hostname }}.cer + SSLCertificateKeyFile /etc/letsencrypt-certs/{{ inventory_hostname }}/{{ inventory_hostname }}.key + SSLCertificateChainFile /etc/letsencrypt-certs/{{ inventory_hostname }}/ca.cer + + SSLProtocol All -SSLv2 -SSLv3 + # Note: this list should ensure ciphers that provide forward secrecy + SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!AES256:!aNULL:!eNULL:!MD5:!DSS:!PSK:!SRP + SSLHonorCipherOrder on + + DocumentRoot /var/log/nodepool/builds + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Require all granted + + + # Channel logs + Alias /irclogs /var/lib/limnoria/opendev/logs/ChannelLogger/oftc/ + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Require all granted + + + # Meeting logs + Alias /meetings /var/lib/limnoira/opendev/meetings/ + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Require all granted + + + ErrorLog /var/log/apache2/{{ inventory_hostname }}_error.log + LogLevel warn + CustomLog /var/log/apache2/{{ inventory_hostname }}_access.log combined + ServerSignature Off + + diff --git a/playbooks/service-eavesdrop.yaml b/playbooks/service-eavesdrop.yaml index 84d2907429..1aaf44682b 100644 --- a/playbooks/service-eavesdrop.yaml +++ b/playbooks/service-eavesdrop.yaml @@ -7,3 +7,4 @@ - sync-project-config - accessbot - gerritbot + - limnoria diff --git a/zuul.d/docker-images/ircbot.yaml b/zuul.d/docker-images/ircbot.yaml index 3bbca4647e..36d52fb21b 100644 --- a/zuul.d/docker-images/ircbot.yaml +++ b/zuul.d/docker-images/ircbot.yaml @@ -3,6 +3,10 @@ name: system-config-build-image-ircbot description: Build a ircbot image. parent: system-config-build-image + requires: &ircbot_requires + - python-base-3.9-container-image + - python-builder-3.9-container-image + provides: ircbot-container-image required-projects: &ircbot_required_projects - opendev/meetbot vars: &ircbot_vars @@ -18,9 +22,12 @@ name: system-config-upload-image-ircbot description: Build and upload a ircbot image. parent: system-config-upload-image + requires: *ircbot_requires + provides: ircbot-container-image required-projects: *ircbot_required_projects vars: *ircbot_vars files: *ircbot_files + - job: name: system-config-promote-image-ircbot description: Promote a previously published ircbot image to latest. diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index d21c08e568..214b8d888a 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -20,6 +20,8 @@ - name: opendev-buildset-registry - name: system-config-build-image-accessbot soft: true + - name: system-config-build-image-ircbot + soft: true - system-config-run-codesearch: dependencies: - name: opendev-buildset-registry @@ -147,6 +149,8 @@ - name: opendev-buildset-registry - name: system-config-upload-image-accessbot soft: true + - name: system-config-upload-image-ircbot + soft: true - system-config-run-codesearch: dependencies: - name: opendev-buildset-registry diff --git a/zuul.d/system-config-run.yaml b/zuul.d/system-config-run.yaml index cf811343f8..4c3416ac05 100644 --- a/zuul.d/system-config-run.yaml +++ b/zuul.d/system-config-run.yaml @@ -130,6 +130,7 @@ requires: - accessbot-container-image - gerritbot-container-image + - ircbot-container-image nodeset: nodes: - name: bridge.openstack.org @@ -138,13 +139,22 @@ label: ubuntu-focal vars: run_playbooks: + - playbooks/letsencrypt.yaml - playbooks/service-eavesdrop.yaml + host-vars: + eavesdrop01.opendev.org: + host_copy_output: + '/var/lib/limnoria': logs + '/var/log/apache2': logs + '/var/log/acme.sh': logs + '/etc/apache2': logs files: - playbooks/service-eavesdrop.yaml - playbooks/run-accessbot.yaml - inventory/service/group_vars/eavesdrop.yaml - playbooks/roles/install-docker - playbooks/roles/accessbot + - playbooks/roles/limnoria - playbooks/roles/logrotate - playbooks/zuul/templates/group_vars/eavesdrop.yaml.j2 - docker/accessbot/