-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add BCD: a standalone, container-based dev environment
The current development environment requires four separate VMs (three from tinystage and one for Bodhi itself), plus some containers running inside the Bodhi VM. It's pretty heavy! This provides an alternative development environment that is standalone and entirely based on containers: a postgres container, a waiverdb container, a greenwave container, a rabbitmq container, an ipsilon container, and a bodhi container that functions similarly to the bodhi VM from the existing environment. There is no FreeIPA or FAS backing the ipsilon instance, we just use ipsilon's testauth mode, with some configuration to allow for testing different group memberships. The containers are Podman containers orchestrated by an ansible playbook, around which the `bcd` command is a light wrapper. They share a network namespace via a pod, and everything is accessed from the host as `localhost`, without SSL or Apache (these could be added if we really want, but it seemed unnecessary). Signed-off-by: Adam Williamson <[email protected]>
- Loading branch information
Showing
32 changed files
with
885 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#!/usr/bin/python | ||
|
||
import argparse | ||
import os | ||
import subprocess | ||
import sys | ||
|
||
CONTAINERS = ( | ||
"database", | ||
"waiverdb", | ||
"greenwave", | ||
"rabbitmq", | ||
"ipsilon", | ||
"bodhi", | ||
) | ||
|
||
|
||
def ansible(args): | ||
"""Run an ansible playbook command based on the parser name.""" | ||
# this is the subcommand that was run - 'run', 'stop' etc. | ||
here = os.path.abspath(os.path.dirname(__file__)) | ||
ret = subprocess.run( | ||
( | ||
"ansible-playbook", | ||
f"{here}/devel/ansible-podman/playbook.yml", | ||
f"-e bodhi_dev_{args.subcommand}=true" | ||
) | ||
) | ||
sys.exit(ret.returncode) | ||
|
||
|
||
def logs(args): | ||
fullc = f"bodhi-dev-{args.container}" | ||
ret = subprocess.run(("podman", "logs", fullc)) | ||
sys.exit(ret.returncode) | ||
|
||
|
||
def shell(args): | ||
fullc = f"bodhi-dev-{args.container}" | ||
ret = subprocess.run(("podman", "exec", "-it", fullc, "/bin/bash")) | ||
sys.exit(ret.returncode) | ||
|
||
|
||
def parse_args(): | ||
"""Parse arguments with argparse.""" | ||
parser = argparse.ArgumentParser( | ||
description=( | ||
"Bodhi Container Development environment. Controls a complete Bodhi development " | ||
"environment in Podman containers orchestrated by Ansible." | ||
) | ||
) | ||
subparsers = parser.add_subparsers(dest="subcommand") | ||
subparsers.required = True | ||
parser_run = subparsers.add_parser( | ||
"run", | ||
description="Prepare and run the environment" | ||
) | ||
parser_run.set_defaults(func=ansible) | ||
parser_stop = subparsers.add_parser( | ||
"stop", | ||
description="Stop the environment (does not remove containers)" | ||
) | ||
parser_stop.set_defaults(func=ansible) | ||
parser_remove = subparsers.add_parser( | ||
"remove", | ||
description="Stop and remove all containers" | ||
) | ||
parser_remove.set_defaults(func=ansible) | ||
parser_cis = subparsers.add_parser( | ||
"cis", | ||
description="Clear Ipsilon sessions (to allow you to log in as a different user)" | ||
) | ||
parser_cis.set_defaults(func=ansible) | ||
parser_shell = subparsers.add_parser( | ||
"shell", | ||
description="Open a shell in a container. Container must be running" | ||
) | ||
parser_shell.add_argument( | ||
"container", | ||
help="The container to open a shell in (default: bodhi)", | ||
default="bodhi", | ||
nargs='?', | ||
choices=CONTAINERS | ||
) | ||
parser_shell.set_defaults(func=shell) | ||
parser_logs = subparsers.add_parser( | ||
"logs", | ||
description="Show logs of the specified container (does not work on bodhi, use journalctl)" | ||
) | ||
parser_logs.add_argument( | ||
"container", | ||
help="The container to show logs for", | ||
choices=[cont for cont in CONTAINERS if cont != "bodhi"], | ||
) | ||
parser_logs.set_defaults(func=logs) | ||
parser_prep = subparsers.add_parser( | ||
"prep", | ||
description="Run preparation steps only" | ||
) | ||
parser_prep.set_defaults(func=ansible) | ||
parser_start = subparsers.add_parser( | ||
"start", | ||
description="Start containers only (do not run prep, will fail if prep has not already run)" | ||
) | ||
parser_start.set_defaults(func=ansible) | ||
return parser.parse_args() | ||
|
||
|
||
def main(): | ||
"""Main loop.""" | ||
try: | ||
args = parse_args() | ||
args.func(args) | ||
except KeyboardInterrupt: | ||
sys.stderr.write("Interrupted, exiting...\n") | ||
sys.exit(1) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() | ||
|
||
# vim: set textwidth=100 ts=8 et sw=4: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
FROM fedora:latest | ||
LABEL \ | ||
summary="Bodhi development environment" \ | ||
description="Distribution software update management system" \ | ||
maintainer="Red Hat, Inc." \ | ||
license="GPLv2+" \ | ||
url="https://github.com/fedora-infra/bodhi" \ | ||
vcs-type="git" \ | ||
io.k8s.display-name="Bodhi DE" | ||
MAINTAINER adamwill | ||
RUN set -exo pipefail \ | ||
# to get bodhi's runtime deps installed, install the official | ||
# packages then remove them (in a single step so we don't get a | ||
# layer with them included) | ||
&& dnf install -y --setopt install_weak_deps=false --nodocs bodhi-server bodhi-client python3-bodhi-messages \ | ||
&& dnf remove -y --noautoremove bodhi-server bodhi-client python3-bodhi-messages \ | ||
# install test and dev env deps (and any new deps not yet in the | ||
# package) | ||
&& dnf install -y --setopt install_weak_deps=false --nodocs \ | ||
# missing runtime deps | ||
# there are errors in the logs if this isn't installed | ||
procps-ng \ | ||
# dev env creation and control deps | ||
poetry \ | ||
postgresql \ | ||
python3-pip \ | ||
sed \ | ||
systemd \ | ||
# dev env QOL and debug deps | ||
bash-completion \ | ||
htop \ | ||
httpie \ | ||
nano \ | ||
nmap-ncat \ | ||
pcp-system-tools \ | ||
python3-ipdb \ | ||
python3-pydocstyle \ | ||
screen \ | ||
tmux \ | ||
tree \ | ||
vim-enhanced \ | ||
# doc build deps | ||
graphviz \ | ||
make \ | ||
python3-sqlalchemy_schemadisplay \ | ||
python3-sphinx \ | ||
# test deps | ||
createrepo_c \ | ||
pre-commit \ | ||
python3-createrepo_c \ | ||
python3-diff-cover \ | ||
python3-pytest \ | ||
python3-pytest-cov \ | ||
python3-pytest-mock \ | ||
python3-responses \ | ||
python3-webtest \ | ||
# pre-commit uses flake8, mypy, pydocstyle and ruff-pre-commit, | ||
# but it always pulls them from repos, never uses packages | ||
&& dnf clean all \ | ||
&& rm -rf /var/cache/* /var/log/dnf* | ||
|
||
# note we use the devel/ directory as the build context so we can access | ||
# development.ini.example here | ||
COPY ./ansible-podman/containers/bodhi/celery.service /etc/systemd/system/celery.service | ||
COPY ./ansible-podman/containers/bodhi/bodhi.service /etc/systemd/system/bodhi.service | ||
COPY ./ansible-podman/containers/bodhi/motd /etc/motd | ||
COPY ./ansible-podman/containers/bodhi/bashrc /root/.bashrc | ||
COPY ./ansible-podman/containers/bodhi/vimrc /root/.vimrc | ||
COPY ./ansible-podman/containers/bodhi/config.toml /etc/fedora-messaging/config.toml | ||
COPY ./ansible-podman/containers/bodhi/printer.toml /etc/fedora-messaging/printer.toml | ||
COPY ./ansible-podman/containers/bodhi/remote.toml /etc/fedora-messaging/remote.toml | ||
COPY ./ansible-podman/containers/bodhi/bodhi-wait.py /usr/local/bin/bodhi-wait.py | ||
COPY ./development.ini.example /etc/bodhi/production.ini | ||
|
||
RUN set -ex \ | ||
&& sed -i -e "s,celery_config.*,celery_config = /bodhi/bodhi-server/celeryconfig.py,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,pungi.basepath.*,pungi.basepath = /bodhi/devel/ci/integration/bodhi/,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,base_address.*,base_address = http://localhost.localdomain:6543/,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,cors_origins_rw.*,cors_origins_rw = *,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,cors_connect_src.*,cors_connect_src = *,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,openid.provider.*,openid.provider = http://localhost.localdomain:6546/openid/,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,openid.url.*,openid.url = http://localhost.localdomain:6546/,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,openid_template.*,openid_template = {username}.localdomain,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,oidc.fedora.client_id.*,oidc.fedora.client_id = integration-tests,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,oidc.fedora.client_secret.*,oidc.fedora.client_secret = integration-tests,g" /etc/bodhi/production.ini \ | ||
&& sed -i -e "s,oidc.fedora.server_metadata_url.*,oidc.fedora.server_metadata_url = http://localhost.localdomain:6546/openidc/.well-known/openid-configuration,g" /etc/bodhi/production.ini | ||
|
||
RUN pip install pyramid_debugtoolbar | ||
RUN ln -s /usr/bin/true /usr/bin/pungi-koji | ||
RUN mkdir -p /srv/{composes/final,composes/stage} | ||
RUN systemctl enable [email protected] [email protected] celery.service bodhi.service | ||
RUN systemctl disable pmcd.service pmie.service pmlogger.service pmlogger_farm.service | ||
RUN poetry config virtualenvs.create false | ||
EXPOSE 6543 | ||
CMD [ "/usr/sbin/init" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# .bashrc | ||
|
||
# Source global definitions | ||
if [ -f /etc/bashrc ]; then | ||
. /etc/bashrc | ||
fi | ||
|
||
# Uncomment the following line if you don't like systemctl's auto-paging feature: | ||
# export SYSTEMD_PAGER= | ||
|
||
shopt -s expand_aliases | ||
alias bdocs="make -C /bodhi/docs clean && make -C /bodhi/docs html && make -C /bodhi/docs man" | ||
alias blog="journalctl -u bodhi -u fm-consumer@config" | ||
alias brestart="systemctl restart bodhi.service celery.service [email protected] [email protected] && echo 'The application is running on http://localhost.localdomain:6543'" | ||
alias bstart="systemctl start bodhi.service celery.service [email protected] [email protected] && echo 'The application is running on http://localhost.localdomain:6543'" | ||
alias bstop="systemctl stop bodhi.service celery.service [email protected] [email protected]" | ||
alias blint="pre-commit run -a" | ||
alias bmessages="journalctl -u fm-consumer@printer -f" | ||
|
||
|
||
function bresetdb { | ||
bstop; | ||
psql -U postgres -h localhost -c "DROP DATABASE bodhi2"; | ||
createdb -U postgres -h localhost bodhi2; | ||
if [ ! -f "/tmp/bodhi2.dump.xz" ] ; then | ||
curl -o /tmp/bodhi2.dump.xz https://infrastructure.fedoraproject.org/infra/db-dumps/bodhi2.dump.xz | ||
fi | ||
xzcat /tmp/bodhi2.dump.xz | psql -U postgres -h localhost bodhi2; | ||
pushd /bodhi/bodhi-server; | ||
# we call 'python3' explicitly to dodge some options in the | ||
# shebang which break finding our bodhi modules | ||
python3 /usr/bin/alembic upgrade head; | ||
popd; | ||
bstart; | ||
} | ||
|
||
|
||
function btest { | ||
find /bodhi -name "*.pyc" -delete; | ||
pushd /bodhi | ||
blint || return $? | ||
bdocs || return $? | ||
for module in bodhi-messages bodhi-client bodhi-server; do | ||
pushd $module | ||
python3 -m pytest $@ tests || return $? | ||
popd | ||
done | ||
diff-cover bodhi-*/coverage.xml --compare-branch=develop --fail-under=100 | ||
popd | ||
} | ||
|
||
|
||
export BODHI_URL="http://localhost.localdomain:6543/" | ||
export BODHI_OPENID_PROVIDER="http://localhost.localdomain:6546/openidc" | ||
export PYTHONWARNINGS="once" | ||
export BODHI_CI_ARCHIVE_PATH="/bodhi-ci-test_results/" | ||
|
||
cat /etc/motd | ||
cd /bodhi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/python3 | ||
|
||
import time | ||
|
||
from bodhi.server.config import config | ||
from sqlalchemy import engine_from_config | ||
from sqlalchemy.exc import OperationalError | ||
|
||
config.load_config() | ||
engine = engine_from_config(config) | ||
|
||
|
||
# stolen from waiverdb, GPLv2+, thanks Dan Callaghan | ||
def wait_for_db(): | ||
poll_interval = 10 # seconds | ||
while True: | ||
try: | ||
engine.connect() | ||
except OperationalError as e: | ||
print('Failed to connect to database: {}'.format(e)) | ||
print(f'Sleeping for {poll_interval} seconds...') | ||
time.sleep(poll_interval) | ||
print('Retrying...') | ||
else: | ||
break | ||
|
||
|
||
if __name__ == '__main__': | ||
wait_for_db() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[Unit] | ||
Description=bodhi | ||
After=network-online.target | ||
Wants=network-online.target | ||
|
||
[Service] | ||
Environment=PYTHONWARNINGS=once | ||
WorkingDirectory=/bodhi/bodhi-server | ||
ExecStartPre=/usr/bin/poetry -C /bodhi/bodhi-messages install --only-root | ||
ExecStartPre=/usr/bin/poetry -C /bodhi/bodhi-client install --only-root | ||
ExecStartPre=/usr/bin/poetry -C /bodhi/bodhi-server install --only-root | ||
ExecStartPre=/usr/local/bin/bodhi-wait.py | ||
# we don't run alembic and pserve directly from /usr/bin as some | ||
# options in their shebangs break finding our bodhi modules | ||
ExecStartPre=python3 -m alembic -c alembic.ini upgrade head | ||
ExecStart=python3 -m pyramid.scripts.pserve /etc/bodhi/production.ini --reload | ||
TimeoutStartSec=600 | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[Unit] | ||
Description=celery | ||
After=bodhi.service | ||
Wants=bodhi.service | ||
|
||
[Service] | ||
Environment=BODHI_CONFIG=/etc/bodhi/development.ini | ||
WorkingDirectory=/bodhi/bodhi-server | ||
ExecStart=/usr/bin/poetry run celery -A bodhi.server.tasks.app worker -l info -Q celery,has_koji_mount -B | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
amqp_url = "amqp://" | ||
publish_exchange = "amq.topic" | ||
callback = "bodhi.server.consumers:Consumer" | ||
|
||
[[bindings]] | ||
queue = "bodhi_local_queue" | ||
exchange = "amq.topic" | ||
routing_keys = [ | ||
"org.fedoraproject.*.bodhi.update.edit", | ||
"org.fedoraproject.*.bodhi.update.request.testing", | ||
"org.fedoraproject.*.waiverdb.waiver.new" | ||
] | ||
|
||
[tls] | ||
ca_cert = "/etc/pki/tls/certs/ca-bundle.crt" | ||
keyfile = "/my/client/key.pem" | ||
certfile = "/my/client/cert.pem" | ||
|
||
[client_properties] | ||
app = "Bodhi dev local" | ||
|
||
[queues.bodhi_local_queue] | ||
durable = true | ||
auto_delete = false | ||
exclusive = false | ||
arguments = {} | ||
|
||
[qos] | ||
prefetch_size = 0 | ||
prefetch_count = 25 | ||
|
||
[log_config] | ||
version = 1 | ||
disable_existing_loggers = true | ||
|
||
[log_config.formatters.simple] | ||
format = "[%(name)s %(levelname)s] %(message)s" | ||
|
||
[log_config.handlers.console] | ||
class = "logging.StreamHandler" | ||
formatter = "simple" | ||
stream = "ext://sys.stdout" | ||
|
||
[log_config.loggers.fedora_messaging] | ||
level = "INFO" | ||
propagate = false | ||
handlers = ["console"] | ||
|
||
[log_config.root] | ||
level = "WARNING" | ||
handlers = ["console"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../development.ini.example |
Oops, something went wrong.