Initial commit

This commit is contained in:
Richard Megginson
2024-10-22 10:07:09 -06:00
committed by GitHub
commit e898442752
63 changed files with 2164 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
---
profile: production
kinds:
- yaml: "**/meta/collection-requirements.yml"
- playbook: "**/tests/get_coverage.yml"
- yaml: "**/tests/collection-requirements.yml"
- playbook: "**/tests/tests_*.yml"
- playbook: "**/tests/setup-snapshot.yml"
- tasks: "**/tests/*.yml"
- playbook: "**/tests/playbooks/*.yml"
- tasks: "**/tests/tasks/*.yml"
- tasks: "**/tests/tasks/*/*.yml"
- vars: "**/tests/vars/*.yml"
- playbook: "**/examples/*.yml"
skip_list:
- fqcn-builtins
- var-naming[no-role-prefix]
exclude_paths:
- tests/roles/
- .github/
- .markdownlint.yaml
- examples/roles/
mock_roles:
- linux-system-roles.template
supported_ansible_also:
- "2.14.0"
+141
View File
@@ -0,0 +1,141 @@
module.exports = {
parserPreset: 'conventional-changelog-conventionalcommits',
rules: {
'body-leading-blank': [1, 'always'],
'body-max-line-length': [2, 'always', 100],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [2, 'always', 100],
'header-max-length': [2, 'always', 100],
'subject-case': [
2,
'never',
['start-case', 'pascal-case', 'upper-case'],
],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
'tests',
],
],
},
prompt: {
questions: {
type: {
description: "Select the type of change that you're committing",
enum: {
feat: {
description: 'A new feature',
title: 'Features',
emoji: '✨',
},
fix: {
description: 'A bug fix',
title: 'Bug Fixes',
emoji: '🐛',
},
docs: {
description: 'Documentation only changes',
title: 'Documentation',
emoji: '📚',
},
style: {
description:
'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
title: 'Styles',
emoji: '💎',
},
refactor: {
description:
'A code change that neither fixes a bug nor adds a feature',
title: 'Code Refactoring',
emoji: '📦',
},
perf: {
description: 'A code change that improves performance',
title: 'Performance Improvements',
emoji: '🚀',
},
test: {
description: 'Adding missing tests or correcting existing tests',
title: 'Tests',
emoji: '🚨',
},
tests: {
description: 'Adding missing tests or correcting existing tests',
title: 'Tests',
emoji: '🚨',
},
build: {
description:
'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
title: 'Builds',
emoji: '🛠',
},
ci: {
description:
'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
title: 'Continuous Integrations',
emoji: '⚙️',
},
chore: {
description: "Other changes that don't modify src or test files",
title: 'Chores',
emoji: '♻️',
},
revert: {
description: 'Reverts a previous commit',
title: 'Reverts',
emoji: '🗑',
},
},
},
scope: {
description:
'What is the scope of this change (e.g. component or file name)',
},
subject: {
description:
'Write a short, imperative tense description of the change',
},
body: {
description: 'Provide a longer description of the change',
},
isBreaking: {
description: 'Are there any breaking changes?',
},
breakingBody: {
description:
'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
},
breaking: {
description: 'Describe the breaking changes',
},
isIssueAffected: {
description: 'Does this change affect any open issues?',
},
issuesBody: {
description:
'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
},
issues: {
description: 'Add issue references (e.g. "fix #123", "re #123".)',
},
},
},
};
+1
View File
@@ -0,0 +1 @@
1
+3
View File
@@ -0,0 +1,3 @@
# https://help.github.com/en/articles/about-code-owners
# Default reviewers for everything
* @spetrosi @nhosoi @richm
+9
View File
@@ -0,0 +1,9 @@
---
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
commit-message:
prefix: ci
+7
View File
@@ -0,0 +1,7 @@
Enhancement:
Reason:
Result:
Issue Tracker Tickets (Jira or BZ if any):
+49
View File
@@ -0,0 +1,49 @@
---
name: Ansible Lint
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
workflow_dispatch:
env:
LSR_ROLE2COLL_NAMESPACE: fedora
LSR_ROLE2COLL_NAME: linux_system_roles
permissions:
contents: read
jobs:
ansible_lint:
runs-on: ubuntu-latest
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Checkout repo
uses: actions/checkout@v4
- name: Install tox, tox-lsr
run: |
set -euxo pipefail
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.4.0"
- name: Convert role to collection format
run: |
set -euxo pipefail
TOXENV=collection lsr_ci_runtox
coll_dir=".tox/ansible_collections/$LSR_ROLE2COLL_NAMESPACE/$LSR_ROLE2COLL_NAME"
# ansible-lint action requires a .git directory???
# https://github.com/ansible/ansible-lint/blob/main/action.yml#L45
mkdir -p "$coll_dir/.git"
- name: Run ansible-lint
uses: ansible/ansible-lint@v24
with:
working_directory: ${{ github.workspace }}/.tox/ansible_collections/${{ env.LSR_ROLE2COLL_NAMESPACE }}/${{ env.LSR_ROLE2COLL_NAME }}
@@ -0,0 +1,38 @@
---
name: Check for ansible_managed variable use in comments
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
ansible_managed_var_comment:
runs-on: ubuntu-latest
steps:
- name: Update pip, git
run: |
set -euxo pipefail
python3 -m pip install --upgrade pip
sudo apt update
sudo apt install -y git
- name: Checkout repo
uses: actions/checkout@v4
- name: Install tox, tox-lsr
run: |
set -euxo pipefail
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.4.0"
- name: Run ansible-plugin-scan
run: |
set -euxo pipefail
TOXENV=ansible-managed-var-comment lsr_ci_runtox
+38
View File
@@ -0,0 +1,38 @@
---
name: Ansible Plugin Scan
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
ansible_plugin_scan:
runs-on: ubuntu-latest
steps:
- name: Update pip, git
run: |
set -euxo pipefail
python3 -m pip install --upgrade pip
sudo apt update
sudo apt install -y git
- name: Checkout repo
uses: actions/checkout@v4
- name: Install tox, tox-lsr
run: |
set -euxo pipefail
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.4.0"
- name: Run ansible-plugin-scan
run: |
set -euxo pipefail
TOXENV=ansible-plugin-scan lsr_ci_runtox
+48
View File
@@ -0,0 +1,48 @@
---
name: Ansible Test
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
workflow_dispatch:
env:
LSR_ROLE2COLL_NAMESPACE: fedora
LSR_ROLE2COLL_NAME: linux_system_roles
permissions:
contents: read
jobs:
ansible_test:
runs-on: ubuntu-latest
steps:
- name: Update pip, git
run: |
set -euxo pipefail
python3 -m pip install --upgrade pip
sudo apt update
sudo apt install -y git
- name: Checkout repo
uses: actions/checkout@v4
- name: Install tox, tox-lsr
run: |
set -euxo pipefail
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.4.0"
- name: Convert role to collection format
run: |
set -euxo pipefail
TOXENV=collection lsr_ci_runtox
- name: Run ansible-test
uses: ansible-community/ansible-test-gh-action@release/v1
with:
testing-type: sanity # wokeignore:rule=sanity
ansible-core-version: stable-2.17
collection-src-directory: ${{ github.workspace }}/.tox/ansible_collections/${{ env.LSR_ROLE2COLL_NAMESPACE }}/${{ env.LSR_ROLE2COLL_NAME }}
+104
View File
@@ -0,0 +1,104 @@
---
# yamllint disable rule:line-length
name: Convert README.md to HTML and push to docs branch
on: # yamllint disable-line rule:truthy
push:
branches:
- main
paths:
- README.md
release:
types:
- published
permissions:
contents: read
jobs:
build_docs:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure the docs branch
run: |
set -euxo pipefail
branch=docs
existed_in_remote=$(git ls-remote --heads origin $branch)
if [ -z "${existed_in_remote}" ]; then
echo "Creating $branch branch"
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
git checkout --orphan $branch
git reset --hard
git commit --allow-empty -m "Initializing $branch branch"
git push origin $branch
echo "Created $branch branch"
else
echo "Branch $branch already exists"
fi
- name: Checkout the docs branch
uses: actions/checkout@v4
with:
ref: docs
- name: Fetch README.md and .pandoc_template.html5 template from the workflow branch
uses: actions/checkout@v4
with:
sparse-checkout: |
README.md
.pandoc_template.html5
sparse-checkout-cone-mode: false
path: ref_branch
- name: Set RELEASE_VERSION based on whether run on release or on push
run: |
set -euxo pipefail
if [ ${{ github.event_name }} = release ]; then
echo "RELEASE_VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
elif [ ${{ github.event_name }} = push ]; then
echo "RELEASE_VERSION=latest" >> $GITHUB_ENV
else
echo Unsupported event
exit 1
fi
- name: Ensure that version and docs directories exist
run: mkdir -p ${{ env.RELEASE_VERSION }} docs
- name: Remove badges from README.md prior to converting to HTML
run: sed -i '1,8 {/^\[\!.*actions\/workflows/d}' ref_branch/README.md
- name: Convert README.md to HTML and save to the version directory
uses: docker://pandoc/core:latest
with:
args: >-
--from gfm --to html5 --toc --shift-heading-level-by=-1
--template ref_branch/.pandoc_template.html5
--output ${{ env.RELEASE_VERSION }}/README.html ref_branch/README.md
- name: Copy latest README.html to docs/index.html for GitHub pages
if: env.RELEASE_VERSION == 'latest'
run: cp ${{ env.RELEASE_VERSION }}/README.html docs/index.html
- name: Commit changes
run: |
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
git add ${{ env.RELEASE_VERSION }}/README.html docs/index.html
git commit -m "Update README.html for ${{ env.RELEASE_VERSION }}"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: docs
+91
View File
@@ -0,0 +1,91 @@
---
# yamllint disable rule:line-length
name: Tag, release, and publish role based on CHANGELOG.md push
on: # yamllint disable-line rule:truthy
push:
branches:
- main
paths:
- CHANGELOG.md
permissions:
contents: read
jobs:
tag_release_publish:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: checkout PR
uses: actions/checkout@v4
- name: Get tag and message from the latest CHANGELOG.md commit
id: tag
run: |
set -euxo pipefail
print=false
while read -r line; do
if [[ "$line" =~ ^\[([0-9]+\.[0-9]+\.[0-9]+)\]\ -\ [0-9-]+ ]]; then
if [ "$print" = false ]; then
_tagname="${BASH_REMATCH[1]}"
echo "$line"
print=true
else
break
fi
elif [ "$print" = true ]; then
echo "$line"
fi
done < CHANGELOG.md > ./.tagmsg.txt
git fetch --all --tags
for t in $( git tag -l ); do
if [ "$t" = "$_tagname" ]; then
echo INFO: tag "$t" already exists
exit 1
fi
done
# Get name of the branch that the change was pushed to
_branch="${GITHUB_REF_NAME:-}"
if [ "$_branch" = master ] || [ "$_branch" = main ]; then
echo Using branch name ["$_branch"] as push branch
else
echo WARNING: GITHUB_REF_NAME ["$_branch"] is not main or master
_branch=$( git branch -r | grep -o 'origin/HEAD -> origin/.*$' | \
awk -F'/' '{print $3}' || : )
fi
if [ -z "$_branch" ]; then
_branch=$( git branch --points-at HEAD --no-color --format='%(refname:short)' )
fi
if [ -z "$_branch" ]; then
echo ERROR: unable to determine push branch
git branch -a
exit 1
fi
echo "tagname=$_tagname" >> "$GITHUB_OUTPUT"
echo "branch=$_branch" >> "$GITHUB_OUTPUT"
- name: Create tag
uses: mathieudutour/github-tag-action@v6.2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
custom_tag: ${{ steps.tag.outputs.tagname }}
tag_prefix: ''
- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.tag.outputs.tagname }}
name: Version ${{ steps.tag.outputs.tagname }}
bodyFile: ./.tagmsg.txt
makeLatest: true
- name: Publish role to Galaxy
uses: robertdebock/galaxy-action@1.2.1
with:
galaxy_api_key: ${{ secrets.galaxy_api_key }}
git_branch: ${{ steps.tag.outputs.branch }}
+38
View File
@@ -0,0 +1,38 @@
---
# yamllint disable rule:line-length
name: Markdown Lint
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
markdownlint:
runs-on: ubuntu-latest
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Check out code
uses: actions/checkout@v4
# CHANGELOG.md is generated automatically from PR titles and descriptions
# It might have issues but they are not critical
- name: Lint all markdown files except for CHANGELOG.md
uses: docker://avtodev/markdown-lint:master
with:
args: >-
--ignore=CHANGELOG.md
**/*.md
config: .markdownlint.yaml
+32
View File
@@ -0,0 +1,32 @@
---
name: PR Title Lint
on: # yamllint disable-line rule:truthy
pull_request:
types:
- opened
- synchronize
- reopened
- edited
merge_group:
branches:
- main
types:
- checks_requested
permissions:
contents: read
jobs:
commit-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install conventional-commit linter
run: npm install @commitlint/config-conventional @commitlint/cli
- name: Run commitlint on PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
# Echo from env variable to avoid bash errors with extra characters
run: echo "$PR_TITLE" | npx commitlint --verbose
+34
View File
@@ -0,0 +1,34 @@
---
name: ShellCheck
on: # yamllint disable-line rule:truthy
pull_request:
push:
branches:
- main
workflow_dispatch:
env:
# some scripts source tox-lsr scripts - suppress that check
SHELLCHECK_OPTS: -e SC1091
permissions:
contents: read
jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- name: Update git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Checkout repo
uses: actions/checkout@v4
- name: Run ShellCheck
id: shellcheck_id
uses: ludeeus/action-shellcheck@master
- name: Show file paths scanned
run: |
echo Files scanned:
echo "${{ steps.shellcheck_id.outputs.files }}"
@@ -0,0 +1,46 @@
---
# yamllint disable rule:line-length
name: Test converting README.md to README.html
on: # yamllint disable-line rule:truthy
pull_request:
merge_group:
branches:
- main
types:
- checks_requested
push:
branches:
- main
permissions:
contents: read
jobs:
test_converting_readme:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Check out code
uses: actions/checkout@v4
- name: Remove badges from README.md prior to converting to HTML
run: sed -i '1,8 {/^\[\!.*actions\/workflows/d}' README.md
- name: Convert README.md to HTML
uses: docker://pandoc/core:latest
with:
args: >-
--from gfm --to html5 --toc --shift-heading-level-by=-1
--template .pandoc_template.html5
--output README.html README.md
- name: Upload README.html as an artifact
uses: actions/upload-artifact@master
with:
name: README.html
path: README.html
+194
View File
@@ -0,0 +1,194 @@
---
name: Run integration tests in Testing Farm
on:
issue_comment:
types:
- created
permissions:
contents: read
# This is required for the ability to create/update the Pull request status
statuses: write
jobs:
prepare_vars:
name: Get info from role and PR to determine if and how to test
# The concurrency key is used to prevent multiple workflows from running at the same time
concurrency:
# group name contains reponame-pr_num to allow simualteneous runs in different PRs
group: testing-farm-${{ github.event.repository.name }}-${{ github.event.issue.number }}
cancel-in-progress: true
# Let's schedule tests only on user request. NOT automatically.
# Only repository owner or member can schedule tests
if: |
github.event.issue.pull_request
&& contains(github.event.comment.body, '[citest]')
&& (contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.comment.author_association)
|| contains('systemroller', github.event.comment.user.login))
runs-on: ubuntu-latest
outputs:
supported_platforms: ${{ steps.supported_platforms.outputs.supported_platforms }}
head_sha: ${{ steps.head_sha.outputs.head_sha }}
memory: ${{ steps.memory.outputs.memory }}
steps:
- name: Dump github context
run: echo "$GITHUB_CONTEXT"
shell: bash
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
- name: Checkout repo
uses: actions/checkout@v4
- name: Get head sha of the PR
id: head_sha
run: |
head_sha=$(gh api "repos/$REPO/pulls/$PR_NO" --jq '.head.sha')
echo "head_sha=$head_sha" >> $GITHUB_OUTPUT
env:
REPO: ${{ github.repository }}
PR_NO: ${{ github.event.issue.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout PR
uses: actions/checkout@v4
with:
ref: ${{ steps.head_sha.outputs.head_sha }}
- name: Get memory
id: memory
run: |
if [ -d tests/provision.fmf ]; then
memory=$(grep -rPo ' m: \K(.*)' tests/provision.fmf)
fi
if [ -n "$memory" ]; then
echo "memory=$memory" >> $GITHUB_OUTPUT
else
echo "memory=2048" >> $GITHUB_OUTPUT
fi
- name: Get supported platforms
id: supported_platforms
run: |
supported_platforms=""
meta_main=meta/main.yml
# All Fedora are supported, add latest Fedora versions to supported_platforms
if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi fedora$; then
supported_platforms+=" Fedora-39"
supported_platforms+=" Fedora-40"
fi
# Specific Fedora versions supported
if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qiP 'fedora\d+$'; then
for fedora_ver in $(yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -iPo 'fedora\K(\d+$)'); do
supported_platforms+=" Fedora-$fedora_ver"
done
fi
if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi el7; then
supported_platforms+=" CentOS-7-latest"
fi
for ver in 8 9 10; do
if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi el"$ver"; then
supported_platforms+=" CentOS-Stream-$ver"
fi
done
echo "supported_platforms=$supported_platforms" >> $GITHUB_OUTPUT
testing-farm:
name: ${{ matrix.platform }}/ansible-${{ matrix.ansible_version }}
needs: prepare_vars
strategy:
fail-fast: false
matrix:
include:
- platform: Fedora-39
ansible_version: 2.17
- platform: Fedora-40
ansible_version: 2.17
- platform: CentOS-7-latest
ansible_version: 2.9
- platform: CentOS-Stream-8
ansible_version: 2.9
# On CentOS-Stream-8, latest supported Ansible is 2.16
- platform: CentOS-Stream-8
ansible_version: 2.16
- platform: CentOS-Stream-9
ansible_version: 2.17
- platform: CentOS-Stream-10
ansible_version: 2.17
runs-on: ubuntu-latest
env:
ARTIFACTS_DIR_NAME: "tf_${{ github.event.repository.name }}-${{ github.event.issue.number }}_\
${{ matrix.platform }}-${{ matrix.ansible_version }}_\
${{ needs.prepare_vars.outputs.datetime }}/artifacts"
ARTIFACT_TARGET_DIR: /srv/pub/alt/${{ vars.LINUXSYSTEMROLES_USER }}/logs
steps:
- name: Set variables with DATETIME and artifact location
id: set_vars
run: |
printf -v DATETIME '%(%Y%m%d-%H%M%S)T' -1
ARTIFACTS_DIR_NAME="tf_${{ github.event.repository.name }}-${{ github.event.issue.number }}_\
${{ matrix.platform }}-${{ matrix.ansible_version }}_$DATETIME/artifacts"
ARTIFACTS_TARGET_DIR=/srv/pub/alt/${{ vars.LINUXSYSTEMROLES_USER }}/logs
ARTIFACTS_DIR=$ARTIFACTS_TARGET_DIR/$ARTIFACTS_DIR_NAME
ARTIFACTS_URL=https://dl.fedoraproject.org/pub/alt/${{ vars.LINUXSYSTEMROLES_USER }}/logs/$ARTIFACTS_DIR_NAME
echo "DATETIME=$DATETIME" >> $GITHUB_OUTPUT
echo "ARTIFACTS_DIR=$ARTIFACTS_DIR" >> $GITHUB_OUTPUT
echo "ARTIFACTS_URL=$ARTIFACTS_URL" >> $GITHUB_OUTPUT
- name: Set commit status as pending
if: contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
uses: myrotvorets/set-commit-status-action@master
with:
sha: ${{ needs.prepare_vars.outputs.head_sha }}
status: pending
context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
description: Test started
targetUrl: ""
- name: Set commit status as success with a description that platform is skipped
if: "!contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)"
uses: myrotvorets/set-commit-status-action@master
with:
sha: ${{ needs.prepare_vars.outputs.head_sha }}
status: success
context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
description: The role does not support this platform. Skipping.
targetUrl: ""
- name: Run test in testing farm
uses: sclorg/testing-farm-as-github-action@v3
if: contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
with:
git_url: https://github.com/linux-system-roles/tft-tests
git_ref: main
pipeline_settings: '{ "type": "tmt-multihost" }'
environment_settings: '{ "provisioning": { "tags": { "BusinessUnit": "system_roles" } } }'
# Keeping ARTIFACTS_URL at the bottom makes the link in logs clickable
variables: "ANSIBLE_VER=${{ matrix.ansible_version }};\
REPO_NAME=${{ github.event.repository.name }};\
GITHUB_ORG=${{ github.repository_owner }};\
PR_NUM=${{ github.event.issue.number }};\
ARTIFACTS_DIR=${{ steps.set_vars.outputs.ARTIFACTS_DIR }};\
TEST_LOCAL_CHANGES=false;\
LINUXSYSTEMROLES_USER=${{ vars.LINUXSYSTEMROLES_USER }};\
ARTIFACTS_URL=${{ steps.set_vars.outputs.ARTIFACTS_URL }}"
# Note that LINUXSYSTEMROLES_SSH_KEY must be single-line, TF doesn't read multi-line variables fine.
secrets: "LINUXSYSTEMROLES_DOMAIN=${{ secrets.LINUXSYSTEMROLES_DOMAIN }};\
LINUXSYSTEMROLES_SSH_KEY=${{ secrets.LINUXSYSTEMROLES_SSH_KEY }}"
compose: ${{ matrix.platform }}
# There are two blockers for using public ranch:
# 1. multihost is not supported in public https://github.com/teemtee/tmt/issues/2620
# 2. Security issue that leaks long secrets - Jira TFT-2698
tf_scope: private
api_key: ${{ secrets.TF_API_KEY_RH }}
update_pull_request_status: false
tmt_hardware: '{ "memory": ">= ${{ needs.prepare_vars.outputs.memory }} MB" }'
tmt_plan_filter: "tag:general,template"
- name: Set final commit status
uses: myrotvorets/set-commit-status-action@master
if: always() && contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
with:
sha: ${{ needs.prepare_vars.outputs.head_sha }}
status: ${{ job.status }}
context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
description: Test finished
targetUrl: ${{ steps.set_vars.outputs.ARTIFACTS_URL }}
+43
View File
@@ -0,0 +1,43 @@
---
name: Re-run failed testing farm tests
on:
issue_comment:
types:
- created
permissions:
contents: read
jobs:
citest_bad_rerun:
if: |
github.event.issue.pull_request
&& contains(fromJson('["[citest_bad]", "[citest-bad]", "[citest bad]"]'), github.event.comment.body)
&& contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.comment.author_association)
permissions:
actions: write # for re-running failed jobs: https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#re-run-a-job-from-a-workflow-run
runs-on: ubuntu-latest
steps:
- name: Wait 10s until tft.yml workflow is created and skipped because new comment don't match [citest]
run: sleep 10s
- name: Re-run failed jobs for this PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR_TITLE: ${{ github.event.issue.title }}
run: |
PENDING_RUN=$(gh api "repos/$REPO/actions/workflows/tft.yml/runs?event=issue_comment" \
| jq -r "[.workflow_runs[] | select( .display_title == \"$PR_TITLE\") | \
select(.status == \"pending\" or .status == \"queued\" or .status == \"in_progress\") | .id][0]")
# if pending run don't exist, take the last run with failure state
if [ "$PENDING_RUN" != "null" ]; then
echo "The workflow $PENDING_RUN is still running, wait for it to finish to re-run"
exit 1
fi
RUN_ID=$(gh api "repos/$REPO/actions/workflows/tft.yml/runs?event=issue_comment" \
| jq -r "[.workflow_runs[] | select( .display_title == \"$PR_TITLE\" ) | select( .conclusion == \"failure\" ) | .id][0]")
if [ "$RUN_ID" = "null" ]; then
echo "Failed workflow not found, exitting"
exit 1
fi
echo "Re-running workflow $RUN_ID"
gh api --method POST repos/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs
+84
View File
@@ -0,0 +1,84 @@
---
# yamllint disable rule:line-length
name: Weekly CI trigger
on: # yamllint disable-line rule:truthy
workflow_dispatch:
schedule:
- cron: 0 0 * * 6
env:
BRANCH_NAME: weekly-ci
COMMIT_MESSAGE: "ci: This PR is to trigger periodic CI testing"
BODY_MESSAGE: >-
This PR is for the purpose of triggering periodic CI testing.
We don't currently have a way to trigger CI without a PR,
so this PR serves that purpose.
COMMENT: "[citest]"
permissions:
contents: read
jobs:
weekly_ci:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: write
steps:
- name: Update pip, git
run: |
set -euxo pipefail
sudo apt update
sudo apt install -y git
- name: Checkout latest code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create or rebase commit, add dump_packages callback
run: |
set -euxo pipefail
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout ${{ env.BRANCH_NAME }} || git checkout -b ${{ env.BRANCH_NAME }}
git rebase main
if [ ! -d tests/callback_plugins ]; then
mkdir -p tests/callback_plugins
fi
curl -L -s -o tests/callback_plugins/dump_packages.py https://raw.githubusercontent.com/linux-system-roles/auto-maintenance/main/callback_plugins/dump_packages.py
git add tests/callback_plugins
git commit --allow-empty -m "${{ env.COMMIT_MESSAGE }}"
git push -f --set-upstream origin ${{ env.BRANCH_NAME }}
- name: Create and comment pull request
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_PUSH_TOKEN }}
script: |
const head = [context.repo.owner, ":", "${{ env.BRANCH_NAME }}"].join("");
const response = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: head,
base: context.ref,
state: "open"
});
let pr_number = '';
if (response.data.length === 0) {
pr_number = (await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: "${{ env.COMMIT_MESSAGE }}",
body: "${{ env.BODY_MESSAGE }}",
head: "${{ env.BRANCH_NAME }}",
base: context.ref,
draft: true
})).data.number;
} else {
pr_number = response.data[0].number;
}
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr_number,
body: "${{ env.COMMENT }}",
});
+20
View File
@@ -0,0 +1,20 @@
---
# yamllint disable rule:line-length
name: Woke
on: # yamllint disable-line rule:truthy
- pull_request
jobs:
woke:
name: Detect non-inclusive language
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run lsr-woke-action
# Originally, uses: get-woke/woke-action@v0
uses: linux-system-roles/lsr-woke-action@main
with:
woke-args: "-c https://raw.githubusercontent.com/linux-system-roles/tox-lsr/main/src/tox_lsr/config_files/woke.yml --count-only-error-for-failure"
# Cause the check to fail on any broke rules
fail-on-error: true
+14
View File
@@ -0,0 +1,14 @@
passes.yml
vault.yml
*.pyc
*.retry
/tests/.coverage
/tests/htmlcov*
/.tox
/venv*/
/.venv/
.vscode/
artifacts/
__pycache__/
*~
.pytest_cache/
+261
View File
@@ -0,0 +1,261 @@
---
# Default state for all rules
default: true
# Path to configuration file to extend
extends: null
# MD001/heading-increment/header-increment - Heading levels should only increment by one level at a time
MD001: true
# MD002/first-heading-h1/first-header-h1 - First heading should be a top-level heading
MD002:
# Heading level
level: 1
# MD003/heading-style/header-style - Heading style
MD003:
# Heading style
style: "consistent"
# MD004/ul-style - Unordered list style
MD004:
# List style
style: "consistent"
# MD005/list-indent - Inconsistent indentation for list items at the same level
MD005: true
# MD006/ul-start-left - Consider starting bulleted lists at the beginning of the line
MD006: true
# MD007/ul-indent - Unordered list indentation
MD007:
# Spaces for indent
indent: 2
# Whether to indent the first level of the list
start_indented: false
# Spaces for first level indent (when start_indented is set)
start_indent: 2
# MD009/no-trailing-spaces - Trailing spaces
MD009:
# Spaces for line break
br_spaces: 2
# Allow spaces for empty lines in list items
list_item_empty_lines: false
# Include unnecessary breaks
strict: false
# MD010/no-hard-tabs - Hard tabs
MD010:
# Include code blocks
code_blocks: true
# Fenced code languages to ignore
ignore_code_languages: []
# Number of spaces for each hard tab
spaces_per_tab: 1
# MD011/no-reversed-links - Reversed link syntax
MD011: true
# MD012/no-multiple-blanks - Multiple consecutive blank lines
MD012:
# Consecutive blank lines
maximum: 1
# Modified for LSR
# GFM does not limit line length
# MD013/line-length - Line length
MD013: false
# # Number of characters
# # line_length: 80
# line_length: 999
# # Number of characters for headings
# heading_line_length: 80
# # Number of characters for code blocks
# code_block_line_length: 80
# # Include code blocks
# code_blocks: true
# # Include tables
# tables: true
# # Include headings
# headings: true
# # Include headings
# headers: true
# # Strict length checking
# strict: false
# # Stern length checking
# stern: false
# MD014/commands-show-output - Dollar signs used before commands without showing output
MD014: true
# MD018/no-missing-space-atx - No space after hash on atx style heading
MD018: true
# MD019/no-multiple-space-atx - Multiple spaces after hash on atx style heading
MD019: true
# MD020/no-missing-space-closed-atx - No space inside hashes on closed atx style heading
MD020: true
# MD021/no-multiple-space-closed-atx - Multiple spaces inside hashes on closed atx style heading
MD021: true
# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines
MD022:
# Blank lines above heading
lines_above: 1
# Blank lines below heading
lines_below: 1
# MD023/heading-start-left/header-start-left - Headings must start at the beginning of the line
MD023: true
# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content
MD024: true
# MD025/single-title/single-h1 - Multiple top-level headings in the same document
MD025:
# Heading level
level: 1
# RegExp for matching title in front matter
front_matter_title: "^\\s*title\\s*[:=]"
# MD026/no-trailing-punctuation - Trailing punctuation in heading
MD026:
# Punctuation characters not allowed at end of headings
punctuation: ".,;:!。,;:!"
# MD027/no-multiple-space-blockquote - Multiple spaces after blockquote symbol
MD027: true
# MD028/no-blanks-blockquote - Blank line inside blockquote
MD028: true
# MD029/ol-prefix - Ordered list item prefix
MD029:
# List style
style: "one_or_ordered"
# MD030/list-marker-space - Spaces after list markers
MD030:
# Spaces for single-line unordered list items
ul_single: 1
# Spaces for single-line ordered list items
ol_single: 1
# Spaces for multi-line unordered list items
ul_multi: 1
# Spaces for multi-line ordered list items
ol_multi: 1
# MD031/blanks-around-fences - Fenced code blocks should be surrounded by blank lines
MD031:
# Include list items
list_items: true
# MD032/blanks-around-lists - Lists should be surrounded by blank lines
MD032: true
# MD033/no-inline-html - Inline HTML
MD033:
# Allowed elements
allowed_elements: []
# MD034/no-bare-urls - Bare URL used
MD034: true
# MD035/hr-style - Horizontal rule style
MD035:
# Horizontal rule style
style: "consistent"
# MD036/no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading
MD036:
# Punctuation characters
punctuation: ".,;:!?。,;:!?"
# MD037/no-space-in-emphasis - Spaces inside emphasis markers
MD037: true
# MD038/no-space-in-code - Spaces inside code span elements
MD038: true
# MD039/no-space-in-links - Spaces inside link text
MD039: true
# MD040/fenced-code-language - Fenced code blocks should have a language specified
MD040:
# List of languages
allowed_languages: []
# Require language only
language_only: false
# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading
MD041:
# Heading level
level: 1
# RegExp for matching title in front matter
front_matter_title: "^\\s*title\\s*[:=]"
# MD042/no-empty-links - No empty links
MD042: true
# Modified for LSR
# Disabling, we do not need this
# MD043/required-headings/required-headers - Required heading structure
MD043: false
# # List of headings
# headings: []
# # List of headings
# headers: []
# # Match case of headings
# match_case: false
# MD044/proper-names - Proper names should have the correct capitalization
MD044:
# List of proper names
names: []
# Include code blocks
code_blocks: true
# Include HTML elements
html_elements: true
# MD045/no-alt-text - Images should have alternate text (alt text)
MD045: true
# MD046/code-block-style - Code block style
MD046:
# Block style
style: "consistent"
# MD047/single-trailing-newline - Files should end with a single newline character
MD047: true
# MD048/code-fence-style - Code fence style
MD048:
# Code fence style
style: "consistent"
# MD049/emphasis-style - Emphasis style should be consistent
MD049:
# Emphasis style should be consistent
style: "consistent"
# MD050/strong-style - Strong style should be consistent
MD050:
# Strong style should be consistent
style: "consistent"
# MD051/link-fragments - Link fragments should be valid
MD051: true
# MD052/reference-links-images - Reference links and images should use a label that is defined
MD052: true
# MD053/link-image-reference-definitions - Link and image reference definitions should be needed
MD053:
# Ignored definitions
ignored_definitions:
- "//"
+3
View File
@@ -0,0 +1,3 @@
*NOTE*: The `*.txt` files are used by `get_ostree_data.sh` to create the lists
of packages, and to find other system roles used by this role. DO NOT use them
directly.
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env bash
set -euo pipefail
ostree_dir="${OSTREE_DIR:-"$(dirname "$(realpath "$0")")"}"
if [ -z "${4:-}" ] || [ "${1:-}" = help ] || [ "${1:-}" = -h ]; then
cat <<EOF
Usage: $0 packages [runtime|testing] DISTRO-MAJOR[.MINOR] [json|yaml|raw|toml]
The script will use the packages and roles files in $ostree_dir to
construct the list of packages needed to build the ostree image. The script
will output the list of packages in the given format
- json is a JSON list like ["pkg1","pkg2",....,"pkgN"]
- yaml is the YAML list format
- raw is the list of packages, one per line
- toml is a list of [[packages]] elements as in https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/composing_installing_and_managing_rhel_for_edge_images/index#creating-an-image-builder-blueprint-for-a-rhel-for-edge-image-using-the-command-line-interface_composing-a-rhel-for-edge-image-using-image-builder-command-line
The DISTRO-MAJOR.MINOR is the same format used by Ansible for distribution e.g. CentOS-8, RedHat-8.9, etc.
EOF
exit 1
fi
category="$1"
pkgtype="$2"
distro_ver="$3"
format="$4"
pkgtypes=("$pkgtype")
if [ "$pkgtype" = testing ]; then
pkgtypes+=(runtime)
fi
get_rolepath() {
local ostree_dir role rolesdir roles_parent_dir coll_path path
ostree_dir="$1"
role="$2"
roles_parent_dir="$(dirname "$(dirname "$ostree_dir")")"
rolesdir="$roles_parent_dir/$role/.ostree"
# assumes collection format
if [ -d "$rolesdir" ]; then
echo "$rolesdir"
return 0
fi
# assumes legacy role format like linux-system-roles.$role/
for rolesdir in "$roles_parent_dir"/*-system-roles."$role"/.ostree; do
if [ -d "$rolesdir" ]; then
echo "$rolesdir"
return 0
fi
done
# look elsewhere
coll_path="${ANSIBLE_COLLECTIONS_PATH:-}"
if [ -z "$coll_path" ]; then
coll_path="${ANSIBLE_COLLECTIONS_PATHS:-}"
fi
if [ -n "${coll_path}" ]; then
for path in ${coll_path//:/ }; do
for rolesdir in "$path"/ansible_collections/*/*_system_roles/roles/"$role"/.ostree; do
if [ -d "$rolesdir" ]; then
echo "$rolesdir"
return 0
fi
done
done
fi
1>&2 echo ERROR - could not find role "$role" - please use ANSIBLE_COLLECTIONS_PATH
exit 2
}
get_packages() {
local ostree_dir pkgtype pkgfile rolefile
ostree_dir="$1"
for pkgtype in "${pkgtypes[@]}"; do
for suff in "" "-$distro" "-${distro}-${major_ver}" "-${distro}-${ver}"; do
pkgfile="$ostree_dir/packages-${pkgtype}${suff}.txt"
if [ -f "$pkgfile" ]; then
cat "$pkgfile"
fi
done
rolefile="$ostree_dir/roles-${pkgtype}.txt"
if [ -f "$rolefile" ]; then
local roles role rolepath
roles="$(cat "$rolefile")"
for role in $roles; do
rolepath="$(get_rolepath "$ostree_dir" "$role")"
if [ -z "$rolepath" ]; then
1>&2 echo ERROR - could not find role "$role" - please use ANSIBLE_COLLECTIONS_PATH
exit 2
fi
get_packages "$rolepath"
done
fi
done | sort -u
}
format_packages_json() {
local comma pkgs pkg
comma=""
pkgs="["
while read -r pkg; do
pkgs="${pkgs}${comma}\"${pkg}\""
comma=,
done
pkgs="${pkgs}]"
echo "$pkgs"
}
format_packages_raw() {
cat
}
format_packages_yaml() {
while read -r pkg; do
echo "- $pkg"
done
}
format_packages_toml() {
while read -r pkg; do
echo "[[packages]]"
echo "name = \"$pkg\""
echo "version = \"*\""
done
}
distro="${distro_ver%%-*}"
ver="${distro_ver##*-}"
if [[ "$ver" =~ ^([0-9]*) ]]; then
major_ver="${BASH_REMATCH[1]}"
else
echo ERROR: cannot parse major version number from version "$ver"
exit 1
fi
"get_$category" "$ostree_dir" | "format_${category}_$format"
File diff suppressed because one or more lines are too long
+4
View File
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: MIT
---
ignore: |
/.tox/
+19
View File
@@ -0,0 +1,19 @@
Copyright <YEAR> <COPYRIGHT HOLDER>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+5
View File
@@ -0,0 +1,5 @@
# Introduction to Ansible for Linux System Roles
If you are not familiar with Ansible, please see
[Introduction to Ansible for Linux System Roles](https://linux-system-roles.github.io/documentation/intro-to-ansible-for-system-roles.html),
where many useful links are presented.
+66
View File
@@ -0,0 +1,66 @@
# rpm-ostree
The role supports running on [rpm-ostree](https://coreos.github.io/rpm-ostree/)
systems. The primary issue is that the `/usr` filesystem is read-only, and the
role cannot install packages. Instead, it will just verify that the necessary
packages and any other `/usr` files are pre-installed. The role will change the
package manager to one that is compatible with `rpm-ostree` systems.
## Building
To build an ostree image for a particular operating system distribution and
version, use the script `.ostree/get_ostree_data.sh` to get the list of
packages. If the role uses other system roles, then the script will include the
packages for the other roles in the list it outputs. The list of packages will
be sorted in alphanumeric order.
Usage:
```bash
.ostree/get_ostree_data.sh packages runtime DISTRO-VERSION FORMAT
```
`DISTRO-VERSION` is in the format that Ansible uses for `ansible_distribution`
and `ansible_distribution_version` - for example, `Fedora-38`, `CentOS-8`,
`RedHat-9.4`
`FORMAT` is one of `toml`, `json`, `yaml`, `raw`
* `toml` - each package in a TOML `[[packages]]` element
```toml
[[packages]]
name = "package-a"
version = "*"
[[packages]]
name = "package-b"
version = "*"
...
```
* `yaml` - a YAML list of packages
```yaml
- package-a
- package-b
...
```
* `json` - a JSON list of packages
```json
["package-a","package-b",...]
```
* `raw` - a plain text list of packages, one per line
```bash
package-a
package-b
...
```
What format you choose depends on which image builder you are using. For
example, if you are using something based on
[osbuild-composer](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/composing_installing_and_managing_rhel_for_edge_images/index#creating-an-image-builder-blueprint-for-a-rhel-for-edge-image-using-the-command-line-interface_composing-a-rhel-for-edge-image-using-image-builder-command-line),
you will probably want to use the `toml` output format.
+105
View File
@@ -0,0 +1,105 @@
# Role Name
[![ansible-lint.yml](https://github.com/linux-system-roles/template/actions/workflows/ansible-lint.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/ansible-lint.yml) [![ansible-test.yml](https://github.com/linux-system-roles/template/actions/workflows/ansible-test.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/ansible-test.yml) [![markdownlint.yml](https://github.com/linux-system-roles/template/actions/workflows/markdownlint.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/markdownlint.yml) [![shellcheck.yml](https://github.com/linux-system-roles/template/actions/workflows/shellcheck.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/shellcheck.yml) [![tft.yml](https://github.com/linux-system-roles/template/actions/workflows/tft.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/tft.yml) [![tft_citest_bad.yml](https://github.com/linux-system-roles/template/actions/workflows/tft_citest_bad.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/tft_citest_bad.yml) [![woke.yml](https://github.com/linux-system-roles/template/actions/workflows/woke.yml/badge.svg)](https://github.com/linux-system-roles/template/actions/workflows/woke.yml)
![template](https://github.com/linux-system-roles/template/workflows/tox/badge.svg)
A template for an ansible role that configures some GNU/Linux subsystem or
service. A brief description of the role goes here.
## Requirements
Any prerequisites that may not be covered by Ansible itself or the role should
be mentioned here. This includes platform dependencies not managed by the
role, hardware requirements, external collections, etc. There should be a
distinction between *control node* requirements (like collections) and
*managed node* requirements (like special hardware, platform provisioning).
### Collection requirements
For instance, if the role depends on some collections and has a
`meta/collection-requirements.yml` file for installing those dependencies, and
in order to manage `rpm-ostree` systems, it should be mentioned here that the
user should run
```bash
ansible-galaxy collection install -vv -r meta/collection-requirements.yml
```
on the *control node* before using the role.
## Role Variables
A description of all input variables (i.e. variables that are defined in
`defaults/main.yml`) for the role should go here as these form an API of the
role. Each variable should have its own section e.g.
### template_foo
This variable is required. It is a string that lists the foo of the role.
There is no default value.
### template_bar
This variable is optional. It is a boolean that tells the role to disable bar.
The default value is `true`.
Variables that are not intended as input, like variables defined in
`vars/main.yml`, variables that are read from other roles and/or the global
scope (ie. hostvars, group vars, etc.) can be also mentioned here but keep in
mind that as these are probably not part of the role API they may change during
the lifetime.
Example of setting the variables:
```yaml
template_foo: "oof"
template_bar: false
```
## Variables Exported by the Role
This section is optional. Some roles may export variables for playbooks to
use later. These are analogous to "return values" in Ansible modules. For
example, if a role performs some action that will require a system reboot, but
the user wants to defer the reboot, the role might set a variable like
`template_reboot_needed: true` that the playbook can use to reboot at a more
convenient time.
Example:
### template_reboot_needed
Default `false` - if `true`, this means a reboot is needed to apply the changes
made by the role
## Example Playbook
Including an example of how to use your role (for instance, with variables
passed in as parameters) is always nice for users too:
```yaml
- name: Manage the template subsystem
hosts: all
vars:
template_foo: "foo foo!"
template_bar: false
roles:
- linux-system-roles.template
```
More examples can be provided in the [`examples/`](examples) directory. These
can be useful, especially for documentation.
## rpm-ostree
See README-ostree.md
## License
Whenever possible, please prefer MIT.
## Author Information
An optional section for the role authors to include contact information, or a
website (HTML is not allowed).
+21
View File
@@ -0,0 +1,21 @@
# Contributing to the template Linux System Role
## Where to start
The first place to go is [Contribute](https://linux-system-roles.github.io/contribute.html).
This has all of the common information that all role developers need:
* Role structure and layout
* Development tools - How to run tests and checks
* Ansible recommended practices
* Basic git and github information
* How to create git commits and submit pull requests
**Bugs and needed implementations** are listed on
[Github Issues](https://github.com/linux-system-roles/template/issues).
Issues labeled with
[**help wanted**](https://github.com/linux-system-roles/template/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
are likely to be suitable for new contributors!
**Code** is managed on [Github](https://github.com/linux-system-roles/template), using
[Pull Requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
+8
View File
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: MIT
---
# Here is the right place to put the role's input variables.
# This file also serves as a documentation for such a variables.
# Examples of role input variables:
template_foo: foo
template_bar: true
+9
View File
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: MIT
---
- name: Example template role invocation
hosts: all
vars:
template_foo: example variable value
template_bar: false
roles:
- linux-system-roles.template
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
- name: Handler for template to restart services
service:
name: "{{ item }}"
state: restarted
loop: "{{ __template_services }}"
+4
View File
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: MIT
---
collections:
- ansible.posix
+20
View File
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: MIT
---
galaxy_info:
author: John Doe <jdoe@corp.com>
description: Basic template for Linux system roles
company: John Doe, Inc.
license: MIT
min_ansible_version: "2.9"
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- "9"
galaxy_tags:
- el9
- el10
- fedora
dependencies: []
+27
View File
@@ -0,0 +1,27 @@
# SPDX-License-Identifier: MIT
---
- name: Set platform/version specific variables
include_tasks: tasks/set_vars.yml
# Examples of some tasks:
- name: Ensure required packages are installed
package:
name: "{{ __template_packages }}"
state: present
use: "{{ (__template_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
- name: Ensure required services are enabled and started
service:
name: "{{ item }}"
state: started
enabled: true
loop: "{{ __template_services }}"
- name: Generate /etc/{{ __template_foo_config }}
template:
src: "{{ __template_foo_config }}.j2"
dest: /etc/{{ __template_foo_config }}
backup: true
mode: "0400"
notify: Handler for template to restart services
+33
View File
@@ -0,0 +1,33 @@
---
- name: Ensure ansible_facts used by role
setup:
gather_subset: "{{ __template_required_facts_subsets }}"
when: __template_required_facts |
difference(ansible_facts.keys() | list) | length > 0
- name: Determine if system is ostree and set flag
when: not __template_is_ostree is defined
block:
- name: Check if system is ostree
stat:
path: /run/ostree-booted
register: __ostree_booted_stat
- name: Set flag to indicate system is ostree
set_fact:
__template_is_ostree: "{{ __ostree_booted_stat.stat.exists }}"
- name: Set platform/version specific variables
include_vars: "{{ __vars_file }}"
loop:
- "{{ ansible_facts['os_family'] }}.yml"
- "{{ ansible_facts['distribution'] }}.yml"
- >-
{{ ansible_facts['distribution'] ~ '_' ~
ansible_facts['distribution_major_version'] }}.yml
- >-
{{ ansible_facts['distribution'] ~ '_' ~
ansible_facts['distribution_version'] }}.yml
vars:
__vars_file: "{{ role_path }}/vars/{{ item }}"
when: __vars_file is file
+9
View File
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: MIT
#
# Example of a template of configuration file
#
{{ ansible_managed | comment }}
{{ "system_role:template" | comment(prefix="", postfix="") }}
[foo]
foo = {{ template_foo }}
bar = {{ template_bar }}
+10
View File
@@ -0,0 +1,10 @@
---
# tasks file for caller
- name: Include role
include_role:
name: "{{ roletoinclude }}"
- name: Assert variable not overridden
assert:
that: not __caller_override
+3
View File
@@ -0,0 +1,3 @@
---
# vars file for caller
__caller_override: false
+1
View File
@@ -0,0 +1 @@
../../../defaults
+1
View File
@@ -0,0 +1 @@
../../../handlers
+1
View File
@@ -0,0 +1 @@
../../../meta
+1
View File
@@ -0,0 +1 @@
../../../tasks
+1
View File
@@ -0,0 +1 @@
../../../templates
+1
View File
@@ -0,0 +1 @@
../../../vars
+14
View File
@@ -0,0 +1,14 @@
---
- name: Setup snapshot
hosts: all
tasks:
- name: Set platform/version specific variables
include_role:
name: linux-system-roles.template
tasks_from: set_vars.yml
public: true
- name: Install test packages
package:
name: "{{ __template_packages }}"
state: present
+16
View File
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: MIT
---
- name: Get file
slurp:
path: "{{ __file }}"
register: __content
when: not __file_content is defined
- name: Check for presence of ansible managed header, fingerprint
assert:
that:
- ansible_managed in content
- __fingerprint in content
vars:
content: "{{ (__file_content | d(__content)).content | b64decode }}"
ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}"
+1
View File
@@ -0,0 +1 @@
{{ ansible_managed | comment(__comment_type | d("plain")) }}
+13
View File
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: MIT
---
- name: Ensure that the role runs with default parameters
hosts: all
gather_facts: false # test that role works in this case
roles:
- linux-system-roles.template
tasks:
- name: Check header for ansible_managed, fingerprint
include_tasks: tasks/check_header.yml
vars:
__file: /etc/foo.conf
__fingerprint: system_role:template
+55
View File
@@ -0,0 +1,55 @@
---
- name: Test role include variable override
hosts: all
gather_facts: true
tasks:
- name: Create var file in caller that can override the one in called role
delegate_to: localhost
copy:
# usually the fake file will cause the called role to crash of
# overriding happens, but if not, set a variable that will
# allow to detect the bug
content: "__caller_override: true"
# XXX ugly, self-modifying code - changes the "caller" role on
# the controller
dest: "{{ playbook_dir }}/roles/caller/vars/{{ item }}.yml"
mode: preserve
loop: "{{ varfiles | unique }}"
# In case the playbook is executed against multiple hosts, use
# only the first one. Otherwise the hosts would stomp on each
# other since they are changing files on the controller.
when: inventory_hostname == ansible_play_hosts_all[0]
vars:
# change to hostvars['localhost']['ansible_facts'] to use the
# information for localhost
facts: "{{ ansible_facts }}"
versions:
- "{{ facts['distribution_version'] }}"
- "{{ facts['distribution_major_version'] }}"
separators: ["-", "_"]
# create all variants like CentOS, CentOS_8.1, CentOS-8.1,
# CentOS-8, CentOS-8.1
# more formally:
# {{ ansible_distribution }}-{{ ansible_distribution_version }}
# {{ ansible_distribution }}-{{ ansible_distribution_major_version }}
# {{ ansible_distribution }}
# {{ ansible_os_family }}
# and the same for _ as separator.
varfiles: "{{ [facts['distribution']] | product(separators) |
map('join') | product(versions) | map('join') | list +
[facts['distribution'], facts['os_family']] }}"
register: __varfiles_created
- name: Import role
import_role:
name: caller
vars:
roletoinclude: linux-system-roles.template
- name: Cleanup
file:
path: "{{ item.dest }}"
state: absent
loop: "{{ __varfiles_created.results }}"
delegate_to: localhost
when: inventory_hostname == ansible_play_hosts_all[0]
+3
View File
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: MIT
[lsr_config]
lsr_enable = true
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with CentOS 10 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with CentOS 7 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with CentOS 8 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with CentOS 9 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with Fedora specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with Red Hat Enterprise Linux 10 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with Red Hat Enterprise Linux 7 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with Red Hat Enterprise Linux 8 specific values.
# Example:
__template_packages: []
__template_services: []
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: MIT
---
# Put internal variables here with Red Hat Enterprise Linux 9 specific values.
# Example:
__template_packages: []
__template_services: []
+21
View File
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: MIT
---
# Put the role's internal variables here that are not distribution specific.
# You can override these by defining the same variable with a different
# value in a platform/version specific file in vars/
# Examples of non-distribution specific (generic) internal variables:
__template_foo_config: foo.conf
__template_packages: []
__template_services: []
# ansible_facts required by the role
__template_required_facts:
- distribution
- distribution_major_version
- distribution_version
- os_family
# the subsets of ansible_facts that need to be gathered in case any of the
# facts in required_facts is missing; see the documentation of
# the 'gather_subset' parameter of the 'setup' module
__template_required_facts_subsets: "{{ ['!all', '!min'] +
__template_required_facts }}"