Files
Ansible-Build/task
T

758 lines
26 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
help-table() {
local cmd_width=30
local opt_width=26
local desc_width=70
local column="| %-${cmd_width}s | %-${opt_width}s | %-${desc_width}s |\n"
printf "$column" 'Command' 'Option' 'Description'
echo "|$(printf '%*s' $((cmd_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((opt_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((desc_width + 2)) '' | tr ' ' '-')|"
# Env
printf "$column" 'version' '' 'Show tool versions.'
# Galaxy
printf "$column" 'build-galaxy' '' 'Create tarball of collection.'
printf "$column" 'publish-galaxy' '' 'Publish tarball to Ansible Galaxy.'
# Docs
printf "$column" 'build-vuepress' '' 'Create vuepress build.'
printf "$column" 'dev-vuepress' '' 'Start vuepress development server.'
printf "$column" 'docs' '' 'Update docs.'
printf "$column" 'install-vuepress' '' 'Install build dependencies.'
printf "$column" 'serve-vuepress' '' 'Serve vuepress build.'
printf "$column" 'update-roles-doc' '' 'Update readme files in roles folder.'
# LLM
printf "$column" 'commit-with-llm' '' 'Commit with llm generated commit message.'
printf "$column" 'update-with-llm' '[glob][prompt]' 'Feed files matching glob with prompt to LLM and apply file changes.'
# Docker
printf "$column" "login-docker" "[user][token]" "Run Docker login and create docker config."
# Vault
printf "$column" 'convert-vault-file' '[vault_id] [path]' 'Re-encrypt vault file as single strings.'
printf "$column" 'decrypt-file' '[path]' 'Decrypt Ansible Vault file.'
printf "$column" 'encrypt-file' '[vault_id] [path]' 'Encrypt file with Ansible Vault.'
printf "$column" 'encrypt-string' '[vault_id] [key:value] -q' 'Generate encrypted string with Ansible Vault.'
printf "$column" 'generate-vault-password' '[vault_id] [password]' 'Generate a password file for Ansible vault.'
printf "$column" 'show-vault-file' '[vault_id] [path]' 'Show content of encrypted strings or fully encrypted vault file.'
# Setup
printf "$column" 'install' '' 'Install Ansible and dependencies with uv.'
printf "$column" 'install-ansible-build-scripts' '[role]' 'Install scripts of the specified Ansbile role.'
printf "$column" 'install-exo' '' 'Install Exoscale CLI.'
printf "$column" 'show-passwordless-sudo' '[username]' 'Give instructions to setup passwordless sudo.'
printf "$column" 'upgrade' '' 'Upgrade Ansible and dependencies with uv.'
# Development
printf "$column" 'lint' '' 'Lint Ansible roles and playbooks.'
printf "$column" 'source' '' 'Source the Python virtual env.'
# Report
printf "$column" 'get-last-hostname' '[role]' 'Search inventory for $ROLE_hostname entries.'
printf "$column" 'list-hosts' '[path]' 'Lists all hosts of an inventory.'
printf "$column" 'list-roles' '' 'Lists all roles.'
printf "$column" 'list-vault' '' 'Lists vault identities.'
printf "$column" 'list-deployments-odoo' '[path]' 'List Odoo deplyments.'
# Git
printf "$column" 'pull-repos' '' 'Pull git repos in inventories folder.'
# Run
printf "$column" 'play' '' 'Run ansible-playbook command.'
printf "$column" 'run' '' 'Run ansible command.'
printf "$column" 'connect-host' '[host]' 'Connect to host with configs.'
# Test
printf "$column" 'test-localhost' '[cleanup]' 'Deploy to localhost. Pass option '\''cleanup'\'' to reset test env.'
printf "$column" 'test-scripts' '[cleanup]' 'Install and test scripts. Pass option '\''cleanup'\'' to reset test env.'
}
help() {
echo
if [[ -n "$1" ]]; then
help-table | grep -i "$1" | column -t -s'|'
else
echo 'task <command> [options]'
echo
echo 'commands:'
echo
help-table
fi
echo
}
# Dynamic env vars
GIT_BRANCH=$(git symbolic-ref --short -q HEAD)
LLM_MODEL=${LLM_MODEL:="llama"}
if [[ -a ".env" ]]; then
export $(cat .env | sed 's/^#.*//g' | xargs)
fi
# Import commands
clone-taskfile(){
if [ ! -d "$HOME/taskfile.build" ]; then
echo -e "\033[38;5;214mGit\033[0m: Clone taskfile repo"
git clone https://git.taskfile.build "$HOME/taskfile.build"
else
echo -e "\033[38;5;214mGit\033[0m: Pull taskfile repo"
git -C "$HOME/taskfile.build" pull
fi
}
if [ -d "$HOME/taskfile.build/bin" ]; then
for file in "$HOME/taskfile.build/bin/"*; do
if [ -f "$file" ]; then
source "$file"
fi
done
fi
# Vault
connect-host() {
if [[ -z "$1" ]]; then
echo 'Host name cannot be empty'
return 1
fi
local search_host="$1"
# Find hosts.yaml file in inventories folder
local hosts_files
hosts_files=$(find ./inventories -type f -name 'hosts.yml')
# Search for host name match
local host_config=""
local hosts_file
for hosts_file in $hosts_files; do
local command="yq e '.all.children.*.hosts.$search_host' $hosts_file"
host_config=$(eval "$command" | sed '/null/d' | head -5)
if [[ -z "$host_config" ]]; then
command="yq e '.all.hosts.$search_host' $hosts_file"
host_config=$(eval "$command" | sed '/null/d' | head -5)
fi
if [[ -n "$host_config" ]]; then
break
fi
done
if [[ -z "$host_config" ]]; then
echo "Host '$search_host' not found in hosts.yml file"
return 1
fi
# Get Ansible vars from the host configuration
local ansible_host
local ansible_port
local ansible_user
local ansible_common_args
ansible_host=$(echo "$host_config" | grep -m1 '^ansible_host' | cut -d: -f2 | xargs)
ansible_port=$(echo "$host_config" | grep -m1 '^ansible_port' | cut -d: -f2 | xargs)
ansible_user=$(echo "$host_config" | grep -m1 '^ansible_user' | cut -d: -f2 | xargs)
ansible_common_args=$(echo "$host_config" | grep -m1 'ansible_ssh_common_args' | cut -d: -f2 | xargs)
# Build SSH command using extracted connection details
local ssh_command="ssh"
if [[ "$ansible_port" != "null" ]] && [[ -n "$ansible_port" ]]; then
ssh_command+=" -p $ansible_port"
fi
if [[ "$ansible_common_args" != "null" ]] && [[ -n "$ansible_common_args" ]]; then
ssh_command+=" $ansible_common_args"
fi
if [[ "$ansible_user" != "null" ]] && [[ -n "$ansible_user" ]]; then
ssh_command+=" $ansible_user@$ansible_host"
else
ssh_command+=" $ansible_host"
fi
echo "Run command: $ssh_command"
$ssh_command
}
decrypt-file() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
echo "Decrypt file $1."
ansible-vault decrypt --output="$1" "$1"
}
encrypt-file() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
if [[ -z "$2" ]]; then echo '$2 is empty'; exit; fi
echo "Encrypt file $2 with vault id $1."
ansible-vault encrypt --encrypt-vault-id="$1" "$2"
}
list-vault() {
grep 'vault_identity_list' ansible.cfg | sed 's/^vault_identity_list = //' | tr ',' '\n' | sed '/^$/d'
}
generate-vault-password() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
if [[ -z "$2" ]]; then echo '$2 is empty'; exit; fi
local vault_id="$1"
local vaultpassword="$2"
export VAULT_ID="$vault_id"
export VAULTPASSWORD="$vaultpassword"
echo "$vaultpassword" > ".vault_pass_$vault_id"
chmod 600 ".vault_pass_$vault_id"
echo "Password file .vault_pass_$vault_id created."
}
encrypt-string() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
if [[ -z "$2" ]]; then echo '$2 is empty'; exit; fi
# Split multiline
local string_key
local string_value
string_key=$(echo "$2" | cut -d ':' -f 1)
string_value=$(echo "$2" | cut -d ':' -f 2 | sed 's/^ *//')
if [[ "$3" != "-q" ]]; then
echo "Found key: $string_key"
echo "Encrypting value: $string_value"
fi
ansible-vault encrypt_string --encrypt-vault-id="$1" --name "$string_key" "$string_value"
}
convert-vault-file() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
if [[ -z "$2" ]]; then echo '$2 is empty'; exit; fi
local vault_id="$1"
local file_path="$2"
local temp_file
temp_file=$(mktemp)
# Decrypt the vault file
ansible-vault decrypt --output="$file_path" "$file_path"
# Process each key-value pair
yq eval '.' "$file_path" | while IFS= read -r line; do
local key
local value
key=$(echo "$line" | cut -d':' -f1)
value=$(echo "$line" | cut -d':' -f2-)
value=$(echo "$value" | sed 's/^[[:space:]"]*//;s/[[:space:]"]*$//')
# Re-encrypt the key-value pair
local encrypted
encrypted=$(ansible-vault encrypt_string --encrypt-vault-id="$vault_id" --name "$key" "$value" 2>/dev/null)
echo "$encrypted" >> "$temp_file"
done
# Move temp file to vault file
mv "$temp_file" "$file_path"
echo "Converted file saved as $file_path"
}
show-vault-file() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit 1; fi
if [[ -z "$2" ]]; then echo '$2 is empty'; exit 1; fi
local vault_id="$1"
local file_path="$2"
local temp_file
local temp_part_file
temp_file=$(mktemp)
temp_part_file=$(mktemp)
if head -n 1 "$file_path" | grep -q "^\$ANSIBLE_VAULT;1.2;AES256;$vault_id"; then
ansible-vault decrypt --output="$temp_file" "$file_path"
else
local write_finished=false
local current_key=""
while IFS= read -r line; do
if [[ "$line" =~ "!vault" ]]; then
# Process previous vault entry if it exists
if [[ "$write_finished" = true ]] && [[ -n "$current_key" ]] && [[ -s "$temp_part_file" ]]; then
ansible-vault decrypt "$temp_part_file"
local value
value=$(cat "$temp_part_file")
echo "$current_key: $value" >> "$temp_file"
fi
# Set up for new vault entry
current_key=$(echo "$line" | cut -d':' -f1)
: > "$temp_part_file"
write_finished=true
else
if [[ "$write_finished" = true ]]; then
echo "$line" | sed 's/^[[:space:]"]*//;s/[[:space:]"]*$//' >> "$temp_part_file"
fi
fi
done < "$file_path"
# Process the final vault entry
if [[ "$write_finished" = true ]] && [[ -n "$current_key" ]] && [[ -s "$temp_part_file" ]]; then
ansible-vault decrypt "$temp_part_file"
local value
value=$(cat "$temp_part_file")
echo "$current_key: $value" >> "$temp_file"
fi
fi
bat --paging=always "$temp_file"
rm -f "$temp_file"
rm -f "$temp_part_file"
}
# Env
install() {
echo "Ensure Python version $(cat .python-version) is installed."
uv python install
remove-venv
activate-venv
echo "Setup Ansible log file"
sudo touch /var/log/ansible.log
sudo chown $USER: /var/log/ansible.log
echo "Install Ansible and Python dependencies"
uv pip install -r requirements.txt
}
install-exo() {
curl -fsSL https://raw.githubusercontent.com/exoscale/cli/master/install-latest.sh | sh
}
version() {
uv --version
ansible --version
}
show-passwordless-sudo() {
local user="${1:-$USERNAME}"
echo "echo \"$user ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers"
}
# Run
play() {
ansible-playbook "$@"
}
run() {
ansible "$@"
}
upgrade() {
echo "Update Ansible"
uv pip install --upgrade ansible
}
lint() {
ansible-lint --fix --offline roles/*
}
# Report
list-hosts() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
find "$1" -name 'hosts.yml' | sort | while read -r hosts_file; do
echo -e "\n<<< $hosts_file >>>\n"
# Check if any host has a 'customer' field
local has_customers=$(yq e '.all.children.*.hosts | .[] | has("customer")' "$hosts_file" | grep -m1 true)
if [[ -n "$has_customers" ]]; then
# Handle inventories with customer info
local aliases=$(yq e '.all.children.*.hosts' "$hosts_file" | grep '^[a-zA-Z]' | cut -d: -f1)
local hosts=$(yq e '.all.children.*.hosts | .[] | .ansible_host' "$hosts_file")
local customers=$(yq e '.all.children.*.hosts | .[] | .customer' "$hosts_file")
if [[ -z "$aliases" || -z "$hosts" ]]; then
echo "No hosts found in $hosts_file"
continue
fi
local alias_width=15
local host_width=25
local cust_width=35
local column="| %-${alias_width}s | %-${host_width}s | %-${cust_width}s |\n"
printf "$column" 'Alias' 'Host' 'Customer'
echo "|$(printf '%*s' $((alias_width + 2)) '' | tr ' ' '-')+$(printf '%*s' $((host_width + 2)) '' | tr ' ' '-')+$(printf '%*s' $((cust_width + 2)) '' | tr ' ' '-')|"
paste <(echo "$aliases") <(echo "$hosts") <(echo "$customers") | sort -u | while read -r alias host customer; do
printf "$column" "$alias" "$host" "$customer"
done
else
# Regular inventory without customer field
local aliases=$(yq e '.all.hosts' "$hosts_file" | grep '^[a-zA-Z]' | cut -d: -f1)
local hosts=$(yq e '.all.hosts | .[] | .ansible_host' "$hosts_file")
if [[ -z "$aliases" || -z "$hosts" ]]; then
echo "No hosts found in $hosts_file"
continue
fi
local alias_width=15
local host_width=25
local column="| %-${alias_width}s | %-${host_width}s |\n"
printf "$column" 'Alias' 'Host'
echo "|$(printf '%*s' $((alias_width + 2)) '' | tr ' ' '-')+$(printf '%*s' $((host_width + 2)) '' | tr ' ' '-')|"
paste <(echo "$aliases") <(echo "$hosts") | while read -r alias host; do
printf "$column" "$alias" "$host"
done
fi
done
}
list-roles() {
local role_width=30
local description_width=70
local column="| %-${role_width}s | %-${description_width}s |\n"
printf "$column" 'Role' 'Description'
echo "|$(printf '%*s' $((role_width + 2)) '' | tr ' ' '-')|$(printf '%*s' $((description_width + 2)) '' | tr ' ' '-')|"
local md_files
md_files=$(find roles -name 'README.md' | sort)
local readme
for readme in $md_files; do
local role
role=$(basename $(dirname "$readme"))
local description
description=$(sed '5q;d' "$readme")
printf "$column" "$role" "$description"
done
}
get-last-hostname() {
if [[ -z "$1" ]]; then echo '$1 is empty'; exit; fi
local role="$1"
echo "Search inventories folder for '${role}_hostname: $role'"
local all_hostnames
all_hostnames=$(rg -I "^${role}_hostname: $role" inventories | cut -d' ' -f2 | sort -u)
local highest
highest=$(echo "$all_hostnames" | sed "s/${role}//g" | sort -n | tail -1)
echo "Highest hostname: ${role}$highest"
echo "Free hostnames:"
for i in $(seq 1 $highest); do
local num
num=$(printf "%02d" $i)
local hostname="${role}${num}"
if ! echo "$all_hostnames" | grep -q "$hostname"; then
echo "$hostname"
fi
done
}
pull-repos() {
local git_folder
for git_folder in $(find inventories -name .git); do
local repo
repo=$(dirname "$git_folder")
echo "Pull repo $repo."
git -C "$repo" pull
done
}
list-deployments-odoo() {
INVENTORY_DIR="$1"
HOST_VARS_DIR="$INVENTORY_DIR/host_vars"
COL_WIDTH_ALIAS=15
COL_WIDTH_HOSTNAME=15
COL_WIDTH_IMAGE=80
printf "| %-${COL_WIDTH_ALIAS}s | %-${COL_WIDTH_HOSTNAME}s | %-${COL_WIDTH_IMAGE}s |\n" "alias" "odoo_hostname" "odoo_image"
printf "| %-${COL_WIDTH_ALIAS}s | %-${COL_WIDTH_HOSTNAME}s | %-${COL_WIDTH_IMAGE}s |\n" \
"$(printf '%.0s-' {1..$COL_WIDTH_ALIAS} | sed 's/-/---/')" \
"$(printf '%.0s-' {1..$COL_WIDTH_HOSTNAME} | sed 's/-/---/')" \
"$(printf '%.0s-' {1..$COL_WIDTH_IMAGE} | sed 's/-/---/')"
mapfile -t FILE_LIST < <(find "$HOST_VARS_DIR" -type f -name "vars.yml" -o -path "$HOST_VARS_DIR/*.yml" | sort)
for FILE_PATH in "${FILE_LIST[@]}"; do
if [[ "$FILE_PATH" == *vault* ]]; then
continue
fi
if [[ "$FILE_PATH" == */vars.yml ]]; then
ALIAS=$(basename "$(dirname "$FILE_PATH")")
VARS_FILE="$FILE_PATH"
elif [[ "$FILE_PATH" == *.yml ]]; then
ALIAS=$(basename "$FILE_PATH" .yml)
VARS_FILE="$FILE_PATH"
else
continue
fi
if [[ "$ALIAS" == "vars" ]] || [[ "$ALIAS" == "vault" ]] || [[ -z "$ALIAS" ]]; then
continue
fi
ODOO_HOSTNAME=$(yq eval '.odoo_hostname // "N/A"' "$VARS_FILE" | head -1)
ODOO_IMAGE=$(yq eval '.odoo_image // "N/A"' "$VARS_FILE" | head -1)
printf "| %-${COL_WIDTH_ALIAS}s | %-${COL_WIDTH_HOSTNAME}s | %-${COL_WIDTH_IMAGE}s |\n" \
"$ALIAS" "$ODOO_HOSTNAME" "$ODOO_IMAGE"
done
}
# Galaxy
build-galaxy() {
local version=$(yq eval '.version' galaxy.yml)
local namespace=$(yq eval '.namespace' galaxy.yml)
local name=$(yq eval '.name' galaxy.yml)
ansible-galaxy collection build
mv $namespace-$name-$version.tar.gz tmp/
}
publish-galaxy() {
local version=$(yq eval '.version' galaxy.yml)
local namespace=$(yq eval '.namespace' galaxy.yml)
local name=$(yq eval '.name' galaxy.yml)
ansible-galaxy collection publish tmp/$namespace-$name-$version.tar.gz --token "$GALAXY_API_TOKEN"
}
# Test commands
test-localhost() {
version
if [[ "$1" = "cleanup" ]]; then
echo "Cleanup localhost"
ansible-playbook -i inventory plays/cleanup.yml -t "odoo,odoo_data,odoo_volume,\
postgres,postgres_data,postgres_volume,\
meilisearch,meilisearch_data,meilisearch_volume,\
pgadmin,pgadmin_data,pgadmin_volume,\
n8n,n8n_data,n8n_volume,\
nginx,nginx_data,nginx_volume,\
metabase,metabase_data,metabase_volume,\
prometheus,prometheus_data,prometheus_volume,\
grafana,grafana_data,grafana_volume,\
loki,loki_data,loki_volume,\
promtail,promtail_data,promatil_volume,\
docker_compose,docker_compose_data"
else
echo "Setup localhost"
ansible-playbook -i inventory plays/localhost.yml --skip-tags check
echo "Curl the services and check HTTP code."
local fail=0
local code=$(curl -o /dev/null -s -w "%{http_code}" -L "http://n8n.local:8080")
[[ $code -eq 200 ]] || { echo "http://n8n.local:8080 -> $code"; fail=1; }
local code=$(curl -o /dev/null -s -w "%{http_code}" -L "http://odoo.local:8080")
[[ $code -eq 200 ]] || { echo "http://odoo.local:8080 -> $code"; fail=1; }
local code=$(curl -o /dev/null -s -w "%{http_code}" -L "http://odoo.local:8080/website/info")
[[ $code -eq 403 ]] || { echo "http://odoo.local:8080/website/info -> $code"; fail=1; }
local code=$(curl -o /dev/null -s -w "%{http_code}" -L "http://metabase.local:8080")
[[ $code -eq 200 ]] || { echo "http://metabase.local:8080 -> $code"; fail=1; }
local code=$(curl -o /dev/null -s -w "%{http_code}" -L "http://grafana.local:8080")
[[ $code -eq 200 ]] || { echo "http://grafana.local:8080 -> $code"; fail=1; }
echo "Exit code is: $fail"
if [[ $fail -eq 1 ]]; then
echo "Checking Docker containers status..."
containers=$(docker ps -a --format "{{.Names}}:{{.Status}}")
failed_containers=()
echo "Containers NOT running:"
while IFS= read -r line; do
name=$(echo "$line" | cut -d: -f1)
container_status=$(echo "$line" | cut -d: -f2)
if [[ ! "$container_status" =~ ^(Up|Running) ]]; then
echo " $name — $container_status"
failed_containers+=("$name")
fi
done <<< "$containers"
if [[ ${#failed_containers[@]} -gt 0 ]]; then
echo "Logs for failed containers:"
for container in "${failed_containers[@]}"; do
echo "<<< $container >>>"
docker logs "$container" 2>/dev/null || echo "Could not fetch logs for $container"
echo ""
done
else
echo "All containers are running — issue may be DNS, port mapping, or service internal error."
fi
fi
exit $fail
fi
}
test-scripts() {
set -e
if [[ "$1" = "cleanup" ]]; then
echo -e "\033[38;5;214mTEST\033[0m: Cleanup test environment."
ansible localhost -m ansible.builtin.cron -a 'name="test" state="absent"'
ansible-playbook -i inventory plays/cleanup.yml -t "odoo,odoo_data,odoo_volume,\
postgres,postgres_data,postgres_volume"
else
echo -e "\033[38;5;214mTEST\033[0m: Test restic scripts"
sudo ./roles/cron/files/install
# Add cron job
ansible localhost -m ansible.builtin.cron -a 'name="test" minute="0" hour="*/6" job="echo \"test\""'
# List cron job and compare output
[[ "$(cron-job-list)" == "[1] 0 */6 * * * test" ]]
cron-job-run -i 1
echo -e "\033[38;5;214mTEST\033[0m: Test postgres scripts"
sudo ./roles/postgres/files/install
# Start postgres container
ansible-playbook -i inventory plays/localhost.yml -t postgres
docker-postgres-create -c postgres01 -d test
docker-postgres-list -c postgres01 | grep "test"
docker-postgres-shell -c postgres01 -d test -s 'CREATE TABLE example(id int);'
docker-postgres-duplicate -c postgres01 -s test -t example
docker-postgres-drop -c postgres01 -d test
docker-postgres-size -c postgres01 -d example | grep "0 bytes"
docker-postgres-backup -c postgres01 -d example
docker-postgres-restore -c postgres01 -f /var/tmp/postgres01/example.sql -d test -i
docker-postgres-size -c postgres01 -d test | grep "0 bytes"
mkdir -p tmp
echo 'DROP TABLE example;' > tmp/drop.sql
docker-postgres-patch -c postgres01 -d test -f ./tmp/drop.sql
docker-postgres-rename -c postgres01 -s test -t example -r
echo -e "\033[38;5;214mTEST\033[0m: Test odoo scripts"
sudo ./roles/odoo/files/install
# Start odoo container
ansible-playbook -i inventory plays/localhost.yml -t odoo --skip-tags depends
docker-odoo-init -c odoo01-prod -d odoo-prod -i contacts -w
docker-odoo-rename -c odoo01-prod -s odoo-prod -t odoo
docker-odoo-list -c odoo01-prod | grep "odoo$"
docker-odoo-user -c odoo01-prod -d odoo -a list | grep "admin"
docker-odoo-drop -c odoo01-int -d odoo-int
docker-odoo-duplicate -c odoo01-prod -s odoo -t odoo-int
docker-odoo-neutralize -c odoo01-int -d odoo-int
docker exec odoo01-int clone-git-addons
docker restart odoo01-int
docker-odoo-init -c odoo01-int -d odoo-int -i partner_firstname
docker-odoo-shell -c odoo01-int -d odoo-int -f -p 'env["res.partner"].browse(1).write({"name": "admint"})'
[[ "admint" == $(docker-odoo-shell -c odoo01-int -d odoo-int -p 'print(env["res.partner"].browse(1).name)') ]]
docker-odoo-upgrade -c postgres01 -d odoo-int -s "17.0" -n upgrade -t "18.0" -m test -l "$ODOO_ENTERPRISE_CODE"
echo -e "\033[38;5;214mTEST\033[0m: Test docker volume scripts"
docker stop postgres01
docker-volume-backup -c postgres01 -v postgres01
docker-volume-backup -c postgres01 -a
docker rm -f postgres01
docker volume rm postgres01
docker-volume-restore -v postgres01 -f /var/tmp/postgres01/postgres01.tar
ansible-playbook -i inventory plays/localhost.yml -t postgres --skip-tags depends
docker-postgres-list -c postgres01 | grep "example"
fi
}
# Docs
docs() {
echo "Update roles.md"
echo "# Roles" > "roles.md"
echo "" >> "roles.md"
echo "| Logo | Role | Description |" >> "roles.md"
echo "| --- | --- | --- |" >> "roles.md"
local md_files=$(find roles -name 'README.md' | sort)
for readme in $md_files; do
local role
role=$(basename $(dirname "$readme"))
local description
description=$(sed '5q;d' "$readme")
echo "| ![$role logo](/logos/$role.png) | [$role]($readme) | $description |" >> "roles.md"
done
}
update-roles-doc() {
local md_files=$(find roles -name 'README.md' | sort)
for readme in $md_files; do
local role
role=$(basename "$(dirname "$readme")")
echo "Update README of $role role."
local logo_line="<img src=\"/logos/$role.png\" alt=\"$role logo\" width=\"100\" height=\"100\">"
local tmpfile
tmpfile=$(mktemp)
{
echo "$logo_line"
echo ""
cat "$readme"
} > "$tmpfile" && mv "$tmpfile" "$readme"
done
}
install-vuepress() {
pnpm install
}
dev-vuepress() {
echo "Copy logos folder to vuepress public folder."
cp -r logos .vuepress/public/
pnpm run dev
}
build-vuepress() {
echo "Copy logos folder to vuepress public folder."
cp -r logos .vuepress/public/
pnpm run build
echo "Create vuepress script folders."
mkdir -p .vuepress/dist/ansible_scripts
mkdir -p .vuepress/dist/cron
mkdir -p .vuepress/dist/certbot
mkdir -p .vuepress/dist/docker
mkdir -p .vuepress/dist/docker_volume
mkdir -p .vuepress/dist/grafana
mkdir -p .vuepress/dist/mysql
mkdir -p .vuepress/dist/nginx
mkdir -p .vuepress/dist/odoo
mkdir -p .vuepress/dist/postgres
echo "Copy script files to vuepress folder."
cp roles/ansible_scripts/files/* .vuepress/dist/ansible_scripts
cp roles/cron/files/* .vuepress/dist/cron
cp roles/certbot/files/* .vuepress/dist/certbot
cp roles/docker/files/* .vuepress/dist/docker
cp roles/docker_volume/files/* .vuepress/dist/docker_volume
cp roles/grafana/files/* .vuepress/dist/grafana
cp roles/mysql/files/* .vuepress/dist/mysql
cp roles/nginx/files/* .vuepress/dist/nginx
cp roles/odoo/files/* .vuepress/dist/odoo
cp roles/postgres/files/* .vuepress/dist/postgres
}
serve-vuepress() {
cd .vuepress/dist
pnpx serve
}
if declare -f "$1" > /dev/null; then
activate-venv 2>/dev/null || true
"$1" "${@:2}"
else
case "$1" in
source)
activate-venv
;;
*)
echo "Unknown command: $1"
help
exit 1
;;
esac
fi