diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 4e77c6dd..3d026afb 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,6 +2,7 @@ ## Requirements +### For Virtual Machine Development * Vagrant - 2.2+ * Ansible - 2.14+ * [Vagrant Libvirt provider plugin](https://github.com/vagrant-libvirt/vagrant-libvirt) @@ -9,6 +10,9 @@ Follow [instruction](https://github.com/theforeman/forklift/blob/master/docs/vagrant.md) to install vagrant +### For Container Development (Alternative) +* Podman - 5.0+ (recommended for systemd support) +* Ansible - 2.14+ ## Development environment @@ -21,6 +25,8 @@ source .venv/bin/activate ## Deployment +### Using Virtual Machines + This setup uses Vagrant to create a basic VM for running the deployment on: ``` @@ -30,6 +36,34 @@ source .venv/bin/activate ./foremanctl deploy --foreman-initial-admin-password=changeme ``` +### Using Containers (Alternative) + +As an alternative to VMs, you can use containers for faster deployment and testing: + +``` +./setup-environment +source .venv/bin/activate +./forge containers start +./foremanctl deploy --foreman-initial-admin-password=changeme +``` + +The containers command provides the following benefits: +- **Faster startup** - No VM boot time required +- **Lower resource usage** - Containers use less memory and CPU than VMs +- **Systemd support** - Properly configured systemd environment for service management + +Container management commands: +``` +./forge containers start # Start container (default name: quadlet) +./forge containers status # Check container status +./forge containers stop # Stop and remove container +``` + +You can also specify a custom container name: +``` +./forge containers start mycontainer +``` + ## Deploy hammer (optional) ``` @@ -38,10 +72,16 @@ source .venv/bin/activate ``` To teardown the environment: +**For VMs:** ``` ./forge vms stop ``` +**For containers:** +``` +./forge containers stop +``` + ## Testing Ensure you have a deployment. Now run the tests: diff --git a/development/playbooks/containers/containers.yaml b/development/playbooks/containers/containers.yaml new file mode 100644 index 00000000..8e410be5 --- /dev/null +++ b/development/playbooks/containers/containers.yaml @@ -0,0 +1,118 @@ +--- +- name: Create a container to deploy and test in + gather_facts: false + hosts: + - localhost + vars: + container: quadlet + tasks: + - name: Start containers + when: container_action == 'start' + block: + - name: Start CentOS 9 Stream container + containers.podman.podman_container: + name: "{{ container }}" + image: quay.io/centos/centos:stream9 + state: started + force_restart: true + privileged: true + hostname: "{{ container }}.example.com" + restart_policy: "always" + ports: + - "22" + - "8080:80" + - "8443:443" + command: sleep infinity + + - name: Wait for container to be ready + ansible.builtin.wait_for: + timeout: 10 + + - name: Install systemd and SSH in container + containers.podman.podman_container_exec: + name: "{{ container }}" + command: "{{ item }}" + loop: + - "dnf install -y systemd openssh-server passwd python3 podman" + - "echo 'root:password' | chpasswd" + - "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config" + changed_when: false + + - name: Commit container with systemd installed + ansible.builtin.command: + cmd: "podman commit {{ container }} {{ container }}-systemd" + changed_when: false + + - name: Stop container to restart with systemd + containers.podman.podman_container: + name: "{{ container }}" + state: stopped + + - name: Remove container completely + containers.podman.podman_container: + name: "{{ container }}" + state: absent + + - name: Start new container with systemd as PID 1 + containers.podman.podman_container: + name: "{{ container }}" + image: "{{ container }}-systemd" + state: started + privileged: true + hostname: "{{ container }}.example.com" + restart_policy: "always" + ports: + - "22" + - "8080:80" + - "8443:443" + command: /usr/sbin/init + + - name: Wait for systemd to initialize + ansible.builtin.wait_for: + timeout: 15 + + - name: Create local_containers inventory + ansible.builtin.copy: + dest: "{{ inventory_dir }}/local_containers" + content: | + all: + hosts: + {{ container }}: + ansible_connection: podman + ansible_user: root + mode: "0664" + + - name: Stop containers + when: container_action == 'stop' + block: + - name: Stop and remove container + containers.podman.podman_container: + name: "{{ container }}" + state: absent + + - name: Remove containers inventory + ansible.builtin.file: + state: absent + path: "{{ inventory_dir }}/local_containers" + + - name: Show container status + when: container_action == 'status' + block: + - name: Get container status + containers.podman.podman_container_info: + name: "{{ container }}" + register: container_info + ignore_errors: true + + - name: Display container status + ansible.builtin.debug: + msg: | + Container Status: + {% if container_info.containers | length > 0 %} + Name: {{ container_info.containers[0].Name }} + State: {{ container_info.containers[0].State.Status }} + Image: {{ container_info.containers[0].Config.Image }} + Created: {{ container_info.containers[0].Created }} + {% else %} + Container "{{ container }}" not found or not running + {% endif %} diff --git a/development/playbooks/containers/metadata.obsah.yaml b/development/playbooks/containers/metadata.obsah.yaml new file mode 100644 index 00000000..a4f6257e --- /dev/null +++ b/development/playbooks/containers/metadata.obsah.yaml @@ -0,0 +1,15 @@ +--- +help: | + Manage development and testing containers. + +variables: + container_action: + parameter: container_action + help: Start the containers + choices: + - start + - stop + - status + containers: + help: Which containers to manage, defaults to quadlet. + action: store diff --git a/development/requirements.yml b/development/requirements.yml index b47a2162..1f496e82 100644 --- a/development/requirements.yml +++ b/development/requirements.yml @@ -2,6 +2,8 @@ collections: - ansible.posix - community.general + - name: containers.podman + version: ">=1.16.4" - name: https://github.com/theforeman/forklift type: git - name: theforeman.operations