Scripting sections in docs
Documentation regarding scripting (usually in devops or sysadmin context).
Interesting example from justfile documentation:
where it create mktemp and set it in variable then by concatenation you get a full path to the tar.gz.
Then the Recipe “publish” create the artifact again and push it to a server.
1tmpdir := `mktemp` # Create a tmp file
2version := "0.2.7"
3tardir := tmpdir / "awesomesauce-" + version
4tarball := tardir + ".tar.gz" # use tmpfile path to create a tarball
5
6publish:
7 rm -f {{tarball}}
8 mkdir {{tardir}}
9 cp README.md *.c {{tardir}}
10 tar zcvf {{tarball}} {{tardir}}
11 scp {{tarball}} me@server.com:release/
12 rm -rf {{tarball}} {{tardir}}
This one can be really usefull to define a default value which can be redefine with env variable:
$$var $$( python -c ‘import sys; print(sys.implementation.name)’ )
T ?= foo # give a default value T := $(shell whoami) # execute shell immediately to put in the var
Example 1
1SUBDIRS = foo bar baz
2
3## dir is a Shell variables
4## SUBDIR and MAKE are Internal make variables
5subdirs:
6 for dir in $(SUBDIRS); do \
7 $(MAKE) -C $$dir; \
8 done
Example 2
1SUBDIRS = foo bar baz
2
3.PHONY: subdirs $(SUBDIRS)
4subdirs: $(SUBDIRS)
5$(SUBDIRS):
6 $(MAKE) -C $@
7foo: baz
1git clone xxx /tmp/xxx&& make -C !$/Makefile
2make download le conteneur
3make build le binaire
4make met le dans /use/local/bin
5make clean
6make help
1# Install GO
2GO_VERSION="1.21.0"
3wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
4sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
5export PATH=$PATH:/usr/local/go/bin
6
7# Install Cobra - CLI builder
8go install github.com/spf13/cobra-cli@latest
9sudo cp -pr ./go /usr/local/.
1mkdir -p ${project} && cd ${project}
2go mod init ${project}
3cobra-cli init
4go build
5go install
6cobra-cli add timezone
CUE stands for Configure, Unify, Execute
1# Install GO
2GO_VERSION="1.21.0"
3wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
4sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
5export PATH=$PATH:/usr/local/go/bin
6
7go install cuelang.org/go/cmd/cue@latest
8sudo cp -pr ./go /usr/local/.
9
10# or use Container
11printf "\e[1;34m[INFO]\e[m Install CUElang:\n";
12podman pull docker.io/cuelang/cue:latest
top -> schema -> constraint -> data -> bottom
1# import a file
2cue import imageset-config.yaml
3
4# Validate
5cue vet imageset-config.cue imageset-config.yaml
6
7
8* Some basics example
9
10```go
11// This is a comment
12_greeting: "Welcome" // Hidden fields start with "_"
13#project: "CUE" // Definitions start with "#"
14
15message: "\(_greeting) to \(#project)!" // Regular fields are exported
16
17#Person: {
18 age: number // Mandatory condition and must be a number
19 hobbies?: [...string] // non mandatory but if present must be a list of string
20}
21
22// Constrain which call #Person and check if age
23#Adult: #Person & {
24 age: >=18
25}
26
27// =~ match a regular expression
28#Phone: string & =~ "[0-9]+"
29
30// Mapping
31instanceType: {
32 web: "small"
33 app: "medium"
34 db: "large"
35}
36
37server1: {
38 role: "app"
39 instance: instanceType[role]
40}
41
42// server1.instance: "medium"
1# executable have extension name "_tool.cue"
2
3# usage
4cue cmd prompter
1package foo
2
3import (
4 "tool/cli"
5 "tool/exec"
6 "tool/file"
7)
8
9// moved to the data.cue file to show how we can reference "pure" Cue files
10city: "Amsterdam"
11
12// A command named "prompter"
13command: prompter: {
14
15 // save transcript to this file
16 var: {
17 file: *"out.txt" | string @tag(file)
18 } // you can use "-t flag=filename.txt" to change the output file, see "cue help injection" for more details
19
20 // prompt the user for some input
21 ask: cli.Ask & {
22 prompt: "What is your name?"
23 response: string
24 }
25
26 // run an external command, starts after ask
27 echo: exec.Run & {
28 // note the reference to ask and city here
29 cmd: ["echo", "Hello", ask.response + "!", "Have you been to", city + "?"]
30 stdout: string // capture stdout, don't print to the terminal
31 }
32
33 // append to a file, starts after echo
34 append: file.Append & {
35 filename: var.file
36 contents: echo.stdout // because we reference the echo task
37 }
38
39 // also starts after echo, and concurrently with append
40 print: cli.Print & {
41 text: echo.stdout // write the output to the terminal since we captured it previously
42 }
43}
1# Import values with details connexion
2. .\values.ps1
3
4$scriptFilePath ="$MyPath\Install\MysqlBase\Script.sql"
5
6# Load the required DLL file (depend on your connector)
7[void][System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\MySQL\MySQL Connector Net 8.0.23\Assemblies\v4.5.2\MySql.Data.dll")
8
9# Load in var the SQL script file
10$scriptContent = Get-Content -Path $scriptFilePath -Raw
11
12# Execute the modified SQL script
13$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{
14 ConnectionString = "server=$MysqlIP;uid=$MysqlUser;Port=3306;user id=$MysqlUser;pwd=$MysqlPassword;database=$MysqlDatabase;pooling=false;CharSet=utf8;SslMode=none"
15 }
16 $sql = New-Object MySql.Data.MySqlClient.MySqlCommand
17 $sql.Connection = $Connection
18 $sql.CommandText = $scriptContent
19 write-host $sql.CommandText
20 $Connection.Open()
21 $sql.ExecuteNonQuery()
22 $Connection.Close()
1# Convert your json in object and put it in variable
2$a = Get-Content 'D:\temp\mytest.json' -raw | ConvertFrom-Json
3$a.update | % {if($_.name -eq 'test1'){$_.version=3.0}}
4
5$a | ConvertTo-Json -depth 32| set-content 'D:\temp\mytestBis.json'
1#The file we want to change
2$xmlFilePath = "$MyPath\EXAMPLE\some.config"
3
4 # Read the XML file content
5 $xml = [xml](Get-Content $xmlFilePath)
6
7 $node = $xml.connectionStrings.add | where {$_.name -eq 'MetaData' -And $_.providerName -eq 'MySql.Data.MySqlClient'}
8 $node.connectionString = $AuditDB_Value
9
10 $node1 = $xml.connectionStrings.add | where {$_.name -eq 'Account'}
11 $node1.connectionString = $Account_Value
12
13 # Save the updated XML back to the file
14 $xml.Save($xmlFilePath)
15
16 Write-Host "$xmlFilePath Updated"
1# Read the JSON file and convert to a PowerShell object
2$jsonContent = Get-Content -Raw -Path ".\example.json" | ConvertFrom-Json
3
4# Read CSV and set a Header to determine the column
5$csvState = Import-CSV -Path .\referentials\states.csv -Header "ID", "VALUE" -Delimiter "`t"
6# Convert in object
7$csvState | ForEach-Object { $TableState[$_.ID] = $_.VALUE }
8
9# Loop through the Entities array and look for the state
10foreach ($item in $jsonContent.Entities) {
11 $stateValue = $item.State
12
13 # Compare the ID and stateValue then get the Value
14 $status = ($csvState | Where-Object { $_.'ID' -eq $stateValue }).VALUE
15
16 Write-Host "Status: $status"
17}
https://devblogs.microsoft.com/powershell-community/update-xml-files-using-powershell/
1# curl method
2curl -LsSf https://astral.sh/uv/install.sh | sh
3
4# Pip method
5pip install uv
1pyenv install 3.12
2pyenv local 3.12
3python -m venv .venv
4source .venv/bin/activate
5pip install pandas
6python
7
8# equivalent in uv
9uv run --python 3.12 --with pandas python
1uv python list --only-installed
2uv python install 3.12
3uv venv /path/to/environment --python 3.12
4uv pip install django
5uv pip compile requirements.in -o requirements.txt
6
7uv init myproject
8uv sync
9uv run manage.py runserver
import statements:1#!/usr/bin/env -S uv run --script
2# /// script
3# requires-python = ">=3.12"
4# dependencies = [
5# "ffmpeg-normalize",
6# ]
7# ///
Then can be run with uv run sync-flickr-dates.py. uv will create a Python 3.12 venv for us.
For me this is in ~/.cache/uv (which you can find via uv cache dir).
Let’s take as an example py dependencies for Netbox
1# Tools needed
2dnf install -y python3.11
3pip install --upgrade pip setuptool python-pypi-mirror twine
4
5# init mirror
6python3.11 -m venv mirror
7mkdir download
8
9# Get list of Py packages needed
10curl raw.githubusercontent.com/netbox-community/netbox/v3.7.3/requirements.txt -o requirements.txt
11echo pip >> requirements.txt
12echo setuptools >> requirements.txt
13echo uwsgi >> requirements.txt
14
15# Make sure repository CA is installed
16curl http://pki.server/pki/cacerts/ISSUING_CA.pem -o /etc/pki/ca-trust/source/anchors/issuing.crt
17curl http://pki.server/pki/cacerts/ROOT_CA.pem -o /etc/pki/ca-trust/source/anchors/root.crt
18update-ca-trust
19
20
21source mirror/bin/activate
22pypi-mirror download -b -d download -r requirements.tx
23twine upload --repository-url https://nexus3.server/repository/internal-pypi/ download/*.whl --cert /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
24twine upload --repository-url https://nexus3.server/repository/internal-pypi/ /download/*.tar.gz --cert /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
Then on target host inside /etc/pip.conf :
1pip3 freeze netaddr > requirements.txt
2pip3 download -r requirements.txt -d wheel
3mv requirements.txt wheel
4tar -zcf wheelhouse.tar.gz wheel
5tar -zxf wheelhouse.tar.gz
6pip3 install -r wheel/requirements.txt --no-index --find-links wheel
1curl -sSL https://install.python-poetry.org | python3 -
2poetry new rp-poetry
3poetry add ansible
4poetry add poetry
5poetry add netaddr
6poetry add kubernetes
7poetry add jsonpatch
8poetry add `cat ~/.ansible/collections/ansible_collections/kubernetes/core/requirements.txt`
9
10poetry build
11
12pip3 install dist/rp_poetry-0.1.0-py3-none-any.whl
13
14poetry export --without-hashes -f requirements.txt -o requirements.txt
1poetry config repositories.test http://localhost
2poetry publish -r test
1podman login registry.redhat.io
2podman pull registry.redhat.io/ansible-automation-platform-22/ansible-python-base-rhel8:1.0.0-230
3
4pyenv local 3.9.13
5python -m pip install poetry
6poetry init
7poetry add ansible-builder
awk is treat each line as a table, by default space are separators of columns.
General syntax is awk 'search {action}' file_to_parse.
1# Give the value higher than 75000 in column $4
2df | awk '$4 > 75000'
3
4# Print the all line when column $4 is higher than 75000
5df | awk '$4 > 75000 {print $0}'
But if you look for a string, the search need to be included in /search/ or ;search;.
When you print $0 represent the all line, $1 first column, $2 second column etc.
1sed -e 'โฆ' -e 'โฆ' # Several execution
2sed -i # Replace in place
3sed -r # Play with REGEX
4
5# The most usefull
6sed -e '/^[ ]*#/d' -e '/^$/d' <fich.> # openfile without empty or commented lines
7sed 's/ -/\n -/g' # replace all "-" with new lines
8sed 's/my_match.*/ /g' # remove from the match till end of line
9sed -i '4048d;3375d' ~/.ssh/known_hosts # delete lines Number
10
11# Buffer
12s/.*@(.*)/$1/; # keep what is after @ put it in buffer ( ) and reuse it with $1.
13sed -e '/^;/! s/.*-reserv.*/; Reserved: &/' file.txt # resuse search with &
14
15# Search a line
16sed -e '/192.168.130/ s/^/#/g' -i /etc/hosts # Comment a line
17sed -re 's/^;(r|R)eserved:/; Reserved:/g' file.txt # Search several string
18
19# Insert - add two lines below a match pattern
20sed -i '/.*\"description\".*/s/$/ \n \"after\" : \"network.target\"\,\n \"requires\" : \"network.target\"\,/g' my_File
21
22# Append
23sed '/WORD/ a Add this line after every line with WORD'
24
25# if no occurence, then add it after "use_authtok"
26sed -e '/remember=10/!s/use_authtok/& remember=10/' -i /etc/pam.d/system-auth-permanent