---
# Full-integration Molecule scenario for the perforce-sdp-install role.
#
# Brings up a real (unlicensed) p4d inside a systemd-enabled container on both
# Debian (Ubuntu) and RedHat/EL (Rocky) families, configures it with
# configure_new_server.sh, and runs the SDP functional test harness.
#
# Requires Docker with systemd-capable images (the geerlingguy *-ansible images
# run systemd as PID 1). The containers are privileged with the host cgroup
# mounted so systemctl can manage the p4d_1 service.
#
# Run: molecule test # full create/converge/verify/destroy
# molecule converge # bring up p4d + configure
# molecule verify # assertions + SDP test harness
# MOLECULE_NO_DESTROY=1 molecule converge # keep the container for poking
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: sdp-ubuntu2204
image: geerlingguy/docker-ubuntu2204-ansible:latest
command: ${MOLECULE_DOCKER_COMMAND:-""}
privileged: true
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
pre_build_image: true
groups:
- main
- name: sdp-rocky9
image: geerlingguy/docker-rockylinux9-ansible:latest
command: ${MOLECULE_DOCKER_COMMAND:-""}
privileged: true
cgroupns_mode: host
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
pre_build_image: true
groups:
- main
provisioner:
name: ansible
config_options:
defaults:
# The role relies on facts (os_family, distribution_major_version, etc.).
gathering: smart
# SDP scripts and p4d are noisy; keep output readable. (community.general's
# 'yaml' callback was removed; use the built-in default with YAML format.)
stdout_callback: ansible.builtin.default
result_format: yaml
inventory:
group_vars:
all:
# The geerlingguy images run as root. Declaring the connection user as
# root lets Ansible skip 'become' for become_user: root tasks
# (become_allow_same_user defaults to false), so the role does not depend
# on a working sudo/PAM stack inside the container.
ansible_user: root
# Use su for root->non-root become (become_user: perforce). The
# geerlingguy EL9 image's sudo PAM stack fails in-container; su
# (root -> any user, no password) works. Real hosts use sudo.
ansible_become_method: ansible.builtin.su
# --- flow control: full fresh install, no broker/license for the test ---
perforce_clean: false
# main-playbook.yml sets this as a play var; the role references it bare
# (sdp_upgrade), so provide it here when running the role standalone.
update_perforce: false
update_dependencies: true
new_sdp: true
new_p4d: false
p4d_enabled: true
install_broker: false
copy_license: false
dummy_interface: false
perforce_depots_use_nfs: false
# Map the configured DNS names to this container in /etc/hosts so the
# master-targeting scripts and the harness can connect to themselves.
manage_etc_hosts: true
# --- identity / topology (single commit-server) ---
perforce_id: "1"
perforce_server_type: "p4d_master"
perforce_master_id: "master"
perforce_replica_id: "standby"
p4serviceuser: "svc_master"
perforce_dnsname: "{{ inventory_hostname }}"
perforce_standby_dnsname: "{{ inventory_hostname }}-standby"
commit_dns: "{{ inventory_hostname }}"
target_server: "{{ commit_dns }}"
# --- ports / server config ---
perforce_case_sensitive: "0"
perforce_service: "p4d_{{ perforce_id }}"
perforce_ssl_prefix: ""
perforce_p4_port: "1666"
perforce_p4broker_port: "ssl:1667"
perforce_p4broker_target_port: "1666"
# --- OS user / group ---
perforce_user: "perforce"
perforce_uid: "10666"
perforce_group: "perforce"
perforce_gid: "10666"
# --- binary versions (downloaded from ftp.perforce.com) ---
perforce_version: "25.2"
perforce_broker_version: "25.2"
# --- volume path *fragments* (no leading slash; prepare.yml creates them) ---
perforce_data_volume: "hxdepots"
perforce_common_volume: "hxdepots"
perforce_log_volume: "hxlogs"
perforce_online_metadata_volume: "hxmetadata"
perforce_offline_metadata_volume: "hxmetadata"
# --- mail / domain (template values only) ---
perforce_domain: "molecule.test"
perforce_mailfrom_email: "perforce-admin@{{ perforce_domain }}"
perforce_mailto_email: "perforce-admin@{{ perforce_domain }}"
perforce_smtp_server: "smtp.{{ perforce_domain }}"
# --- admin / passwords (test-only; never used in production) ---
perforce_admin_user: "p4admin"
perforce_admin_user_pass: "F@stSCM!"
admin_users: []
# perforce_user_password (a SHA-512 crypt hash) is defined in
# molecule/default/group_vars/all.yml -- its leading dollar-sign
# sequences cannot live here because Molecule interpolates this file.
verifier:
name: ansible
scenario:
# The role (and the converge's configure step) are guarded to be idempotent, so
# the idempotence step re-runs converge and asserts zero changes.
test_sequence:
- dependency
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #4 | 32894 | Russell C. Jackson (Rusty) |
Add group resource guardrails to perforce-sdp-install; inventory cleanup Guardrails (gated on guardrails_enabled, commit server): - New group_limits phase (thin orchestrator + group_limits/ subdir: deploy_scripts, set_limits, populate) included from main.yml. Templates the SDP keep_group_unset.py trigger and update_limits.py from inventory so no group/user name is hardcoded; sets Max* on each managed group via the new idempotent files/manage_p4group.py helper; populates the limits group once (marker-guarded). No new cron -- the SDP's hourly master cron maintains membership. - Every group name is its own variable (p4_baseline_group, p4_integrators_group, p4_unlimited_group, p4_admins_group, p4_replicas_group); p4_group_limits is a list of {name, limits}. Naming convention in group_vars/main; per-environment values + enable flag in each commit server's host_vars; safe fallbacks in defaults. - Molecule: install scenario now runs the guardrails phase after configure_new_server and verifies the scripts are deployed and the limits/p4-unlimited groups carry the expected values. README + docs updated. Inventory cleanup: - Removed the 2kgla1tst2 and la1v-rjackson commit hosts (host_vars + inventory). - Renamed the top-level inventory group central -> main (group_vars dir moved, references updated across inventory, molecule, README, CLAUDE.md). ansible-lint production-clean; playbooks syntax-check; helper/templates compile. |
||
| #3 | 32879 | Russell C. Jackson (Rusty) | Harness: tolerate optional/absent scripts + accept ccheck PASS (Grade A or B) | ||
| #2 | 32876 | Russell C. Jackson (Rusty) |
Make both ansible roles idempotent (full converge re-runs cleanly) Existence gate: - main.yml: stat /p4/common/bin/p4_vars -> sdp_installed fact; gate the destructive cleanup (wipe sdp folder + crontab) on 'not sdp_installed' so a re-converge skips wipe/reinstall and only reconciles idempotent config. Run-once installers gated with creates/checks: - run_mkdirs.sh: creates /p4/common/bin/p4_vars (drop changed_when:true). - pyenv: drop changed_when on the creates-guarded bootstrap; add creates for the Python build; gate p4python install on 'pip3 show p4python'. - monitoring prometheus.yml: gate the p4prometheus install script on creates /usr/local/bin/p4prometheus. changed_when:true lies fixed: - login.yml: gate admin/service logins on 'p4 login -s' (only log in when no valid ticket); use command for the no-shell status check. - network_interface.yml: ifup gated on the interface not already being UP. touch/cron idempotence: - authorized_keys touch: modification_time/access_time preserve. - cron/common.yml: remove 'crontab -r' (cron/cronvar modules manage entries idempotently by name; cron.yml is now the authoritative crontab manager). - install/crontab.yml removed + its include dropped: the SDP-generated p4.crontab load was redundant (cron.yml's reset discarded it every run). - packages.yml: apt update_cache cache_valid_time=3600. Molecule: configure_new_server gated behind a marker in the install converge and monitoring prepare; re-added the 'idempotence' step to both scenarios' test_sequence. ansible-lint production-clean; all playbooks syntax-check. |
||
| #1 | 32873 | Russell C. Jackson (Rusty) |
Add full-integration Molecule scenarios for both ansible roles roles/{perforce-sdp-install,perforce-sdp-monitoring}/molecule/default/ each with molecule.yml + prepare.yml + converge.yml + verify.yml. Uses the docker driver with geerlingguy systemd images on Ubuntu 22.04 and Rocky 9 (Debian + RedHat/EL). - install: prepare creates SDP volume dirs; converge runs the role (fresh SDP install -> p4d up) then configure_new_server.sh; verify asserts the service is active, p4 info reports ServerID master, and runs the SDP functional test harness (run_sdp_tests). - monitoring: prepare brings up + configures p4d via the install role; converge applies the monitoring role; verify checks the probe scripts/cron are deployed and runs p4_healthcheck.sh, asserting p4_up=1 against the live server. Idempotence step omitted (a full p4d install is not idempotent). README documents prerequisites and usage. Validated with ansible-playbook --syntax-check and ansible-lint (production profile clean for both the scenarios and the whole project). |