pyenv.yml #2

  • //
  • guest/
  • russell_jackson/
  • ansible-sdp/
  • roles/
  • perforce-sdp-install/
  • tasks/
  • dependencies/
  • pyenv.yml
  • View
  • Commits
  • Open Download .zip Download (3 KB)
---
# Install pyenv for the perforce user, build the latest Python, and install
# p4python into that environment.
- name: "Install pyenv"  # noqa: command-instead-of-module
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.shell: "set -o pipefail; curl -fsSL https://pyenv.run | bash"
  args:
    executable: "/bin/bash"
    creates: "/p4/.pyenv/bin/pyenv"
  register: curl_pyenv_output

- name: "Add Pyenv to perforce user bashrc"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.blockinfile:
    path: "/p4/.bashrc"
    owner: "{{ perforce_user }}"
    group: "{{ perforce_group }}"
    insertafter: EOF
    create: true
    mode: '0644'
    block: |
      export PATH="${HOME}/.pyenv/bin:$PATH"
      eval "$(pyenv init -)"
      eval "$(pyenv virtualenv-init -)"

- name: "Add Pyenv to perforce user profile"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.blockinfile:
    path: "/p4/.profile"
    owner: "{{ perforce_user }}"
    group: "{{ perforce_group }}"
    insertafter: EOF
    create: true
    mode: '0644'
    block: |
      export PATH="${HOME}/.pyenv/bin:$PATH"
      eval "$(pyenv init -)"
      eval "$(pyenv virtualenv-init -)"

- name: "Get latest Python version available in pyenv"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.shell: "set -o pipefail; /p4/.pyenv/bin/pyenv install --list | grep -E '^\\s+3\\.[0-9]+\\.[0-9]+$' | tail -1 | tr -d ' '"
  args:
    executable: "bash"
  register: latest_python_version
  changed_when: false

- name: "Install the latest Python and set it as the pyenv global version"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.shell: >-
    set -o pipefail;
    echo N | /p4/.pyenv/bin/pyenv install {{ latest_python_version.stdout }};
    /p4/.pyenv/bin/pyenv global {{ latest_python_version.stdout }}
  args:
    executable: "bash"
    # The built version directory is the marker; skip the (slow) rebuild once it
    # exists so the task is idempotent.
    creates: "/p4/.pyenv/versions/{{ latest_python_version.stdout }}"
  register: pyenv_python_output

- name: "Check whether p4python is already installed"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.shell: "source /p4/.profile; source /p4/.bashrc; pip3 show p4python"
  args:
    executable: "bash"
  register: p4python_check
  changed_when: false
  failed_when: false

- name: "Install p4python"
  become: true
  become_user: "{{ perforce_user }}"
  ansible.builtin.shell: "source /p4/.profile;source /p4/.bashrc;pip3 install --upgrade pip;pip3 install p4python"
  args:
    executable: "bash"
  when: p4python_check.rc != 0
  register: pyenv_p4python_output
  changed_when: true

- name: "Create the p4python/bin directory"
  ansible.builtin.file:
    path: /p4/p4python/bin
    state: directory
    mode: '0755'
    owner: "{{ perforce_user }}"
    group: "{{ perforce_group }}"

- name: "Link python3 to old venv python3 location to avoid trigger breaks"
  ansible.builtin.file:
    src: /p4/.pyenv/shims/python3
    dest: /p4/p4python/bin/python3
    state: link
    force: true
    owner: "{{ perforce_user }}"
    group: "{{ perforce_group }}"
  failed_when: false
# Change User Description Committed
#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 32842 Russell C. Jackson (Rusty) Reorganize ansible-sdp into per-concern task files; ansible-lint production-clean

- Split install.yml/cron.yml/dependencies.yml and the monitoring role into thin
  orchestrators plus single-purpose phase files; extract shared steps into
  tasks/common/ (fetch_sdp, fetch_binaries, run_mkdirs, copy_ssl,
  configure_broker, sudoers).
- Full best-practices pass: FQCN, true/false, quoted modes, changed_when, loops,
  document-start markers; fill both roles' meta; add .ansible-lint.
- RedHat parity: parameterized EPEL enable, dnf, full upgrade, sysctl/bbr tuning.
- Collapse the 12 journal-rotation cron tasks to one; consolidate duplicate
  download/broker logic; fix broken tests/test.yml role reference.
- Validated ansible-lint clean at the production profile (ansible-core 2.21 /
  python 3.12) and ansible-playbook --syntax-check OK.