From 7a14fa70d4f852d9ba10da5cdfe3abf711ca6d17 Mon Sep 17 00:00:00 2001 From: LocalT0aster Dan <90502400+LocalT0aster@users.noreply.github.com> Date: Thu, 29 Jan 2026 00:09:53 +0300 Subject: [PATCH 01/16] Lab01 Completed (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lab01 python app done * lab01 docs and small fixes * forgot about 2.4 💀 * lab01 go app implemented --- .gitattributes | 99 ++++++++++++ app_go/.gitignore | 33 ++++ app_go/README.md | 30 ++++ app_go/build.sh | 2 + app_go/docs/GO.md | 10 ++ app_go/docs/LAB01.md | 42 +++++ app_go/docs/img/lab01go.png | Bin 0 -> 278577 bytes app_go/go.mod | 3 + app_go/main.go | 286 ++++++++++++++++++++++++++++++++++ app_python/.gitattributes | 30 ++++ app_python/.gitignore | 217 ++++++++++++++++++++++++++ app_python/README.md | 39 +++++ app_python/app.py | 184 ++++++++++++++++++++++ app_python/docs/LAB01.md | 191 +++++++++++++++++++++++ app_python/docs/img/lab01.png | Bin 0 -> 353760 bytes app_python/requirements.txt | 12 ++ app_python/tests/__init__.py | 0 17 files changed, 1178 insertions(+) create mode 100644 .gitattributes create mode 100644 app_go/.gitignore create mode 100644 app_go/README.md create mode 100644 app_go/build.sh create mode 100644 app_go/docs/GO.md create mode 100644 app_go/docs/LAB01.md create mode 100644 app_go/docs/img/lab01go.png create mode 100644 app_go/go.mod create mode 100644 app_go/main.go create mode 100644 app_python/.gitattributes create mode 100644 app_python/.gitignore create mode 100644 app_python/README.md create mode 100644 app_python/app.py create mode 100644 app_python/docs/LAB01.md create mode 100644 app_python/docs/img/lab01.png create mode 100644 app_python/requirements.txt create mode 100644 app_python/tests/__init__.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..fe8a581226 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,99 @@ +# https://github.com/gitattributes/gitattributes/blob/fddc586cf0f10ec4485028d0d2dd6f73197a4258/Common.gitattributes +# Common settings that generally should always be used with your language specific settings + +# Auto detect text files and perform LF normalization +* text=auto + +# +# The above will handle all files NOT found below +# + +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text diff=markdown +*.mdx text diff=markdown +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text eol=crlf +*.tab text +*.tsv text +*.txt text +*.sql text +*.epub diff=astextplain + +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as text by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary +*.eps binary + +# Scripts +*.bash text eol=lf +*.fish text eol=lf +*.ksh text eol=lf +*.sh text eol=lf +*.zsh text eol=lf +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf + +# Serialisation +*.json text +*.toml text +*.xml text +*.yaml text +*.yml text + +# Archives +*.7z binary +*.bz binary +*.bz2 binary +*.bzip2 binary +*.gz binary +*.lz binary +*.lzma binary +*.rar binary +*.tar binary +*.taz binary +*.tbz binary +*.tbz2 binary +*.tgz binary +*.tlz binary +*.txz binary +*.xz binary +*.Z binary +*.zip binary +*.zst binary + +# Text files where line endings should be preserved +*.patch -text + +# +# Exclude files from exporting +# + +.gitattributes export-ignore +.gitignore export-ignore +.gitkeep export-ignore diff --git a/app_go/.gitignore b/app_go/.gitignore new file mode 100644 index 0000000000..add20bc5eb --- /dev/null +++ b/app_go/.gitignore @@ -0,0 +1,33 @@ +# https://github.com/github/gitignore/blob/53fee13f20a05efc93ef4edcad0c62863520e268/Go.gitignore +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Code coverage profiles and other test artifacts +*.out +coverage.* +*.coverprofile +profile.cov + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# env file +.env + +# Editor/IDE +.idea/ +.vscode/ diff --git a/app_go/README.md b/app_go/README.md new file mode 100644 index 0000000000..22a27fa787 --- /dev/null +++ b/app_go/README.md @@ -0,0 +1,30 @@ +# DevOps Info Service (Go) + +## Overview +Simple Go web service that exposes system/runtime details and a health check. + +## Prerequisites +- Go 1.25+ + +## Build +```bash +go build -o devops-info-service.out . +``` + +## Run +```bash +./devops-info-service.out +# Or with custom config +HOST=127.0.0.1 PORT=8080 ./devops-info-service.out +``` + +## Endpoints +- `GET /` - service + system + runtime + request info +- `GET /health` - health check + +## Configuration + +| Variable | Default | Description | +| --- | --- | --- | +| `HOST` | `0.0.0.0` | Bind address for the server | +| `PORT` | `5000` | Port to listen on | diff --git a/app_go/build.sh b/app_go/build.sh new file mode 100644 index 0000000000..2832311420 --- /dev/null +++ b/app_go/build.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +go build -o devops-info-service.out . diff --git a/app_go/docs/GO.md b/app_go/docs/GO.md new file mode 100644 index 0000000000..3f4073e0d8 --- /dev/null +++ b/app_go/docs/GO.md @@ -0,0 +1,10 @@ +# Go Language Justification + +## Why Go + +I chose Go because it produces small, static binaries, compiles quickly, and has a minimal standard library that already covers HTTP servers. That makes it a good fit for a tiny service and for multi‑stage Docker builds later in the course. + +## Tradeoffs + +- **Pros:** fast compile/run, simple deployment, good concurrency model, no runtime dependency chain. +- **Cons:** less dynamic than Python for quick iteration, and JSON struct definitions add some boilerplate. diff --git a/app_go/docs/LAB01.md b/app_go/docs/LAB01.md new file mode 100644 index 0000000000..d80e7b00b9 --- /dev/null +++ b/app_go/docs/LAB01.md @@ -0,0 +1,42 @@ +# LAB01 — DevOps Info Service (Go) + +## Implementation Overview + +This Go version mirrors the Python service and exposes the same two endpoints using the standard `net/http` package. + +### Endpoints + +- `GET /` returns service, system, runtime, request info, and a list of endpoints. +- `GET /health` returns a health status, timestamp, and uptime in seconds. + +### Runtime Behavior + +- **Uptime:** computed from a `startTime` set at process start. +- **System info:** hostname via `os.Hostname`, OS/arch via `runtime`. +- **Request info:** client IP from `X-Forwarded-For` or `RemoteAddr`. +- **Errors:** JSON 404 for unknown paths and JSON 500 on panics (recovery middleware). + +## Build & Run + +```bash +go build -o devops-info-service.out . +./devops-info-service.out +# Custom config +HOST=127.0.0.1 PORT=8080 ./devops-info-service.out +``` + +## API Examples + +```bash +curl -sS http://127.0.0.1:5000/ | jq +curl -sS http://127.0.0.1:5000/health | jq +``` + +## Notes + +- `python_version` in the JSON is populated with the Go runtime version to keep the output shape identical to the Python app. +- The advertised endpoint list is a static slice to match the Python output. + +## Screenshot + +![Screenshot](img/lab01go.png) \ No newline at end of file diff --git a/app_go/docs/img/lab01go.png b/app_go/docs/img/lab01go.png new file mode 100644 index 0000000000000000000000000000000000000000..42652a163c8696676fea868e21f708372ed8a02b GIT binary patch literal 278577 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

~+K<}37~89?1!Vl}B6S%& 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

sI_$lDU%YsEw`h7+Xzkt0779LbG5 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

Xsmul-H^b=tl3W}`YK z|GmDE4P0R&5|O@jY!MYj6`}bN9Bwq$KX2bQI8AIF4sOrifg00&<}nzcb_uwqb-6c; z8f|>_2cWMzG?Gfl`c)9p+zf~V&s(Ji*4Js$Y4T%=8qFGOjmVB#+lBg36F$jxi09Lf z_L_oNHhn7#3QCth?7HnYrjz6>E?s*kk-0@oQ82zZEWMFHvoLK+$K2zw2SFkNDhSAsMiQG=C`oju>LO?^dz$E0{A~%7_qS4mc&BqHm zyOz>*cE1q1jZ0#oDpl+cH^RQb4hvy#$|U35z!#qtcRR0+L^0JcYoXrh(|v-~sCZGq zpofPR+Sa5_O@c75NP7zA1xc`x&}(xVjeLU%iDZ>@Xl<E{5>qO zEao^cg9+-#$T%&H=m$s~X2tNtY)zz^+#1ZOnK|;_m*~tnf7f+LU0+*MF!@SB?7T7( zgv>M5BW#U=AxJVTRcM1Ti-{qCx8c6Mql>J0-i0Ci4omE3O8=STQ}E_9y}!HtCi2hcopW?&W!9(jb(S&C zIhq>S4tjoG6g8m-DSXbGT7nLK?WTZIcrW5Epc00&0wbs^t~n?5Sy)M{5PB~ zPnZ}XeE$RfLYugSyx?UH5!Mr2zgTZ!LBRsm+1fuFhROPK+nVQUpAX^Cm;Cesu|xN# zcxJiKESq~D`FJ!cE-Pe`S;Li&ZC>}c7oJlX){)PjFDU%jV|Mr2_xSJi6%%(EbVoTX z`|hssH-7j$Sl_h_dCLOiHOu-Z2MwV%ab6ytDr*I5F03!5!)Zb}?{WFomw@W^cp1>Y&0lwEuNl5B0CT7C*%1MzB3}mvVk#QSd zH1Z(1K1GV;@mdqsgn?udCvS;Pon6W2T08=pl@5^Bc(GhHG6%r-xhjh&sVSi_yLUgh z&BV?hjO}jRA7@18Yd0eO_~)r8zTRR76EX6&aDVh5nA8?t@j7uB6DXdT4!=(Nc5p)UD&613lwIY1*2k?IP(2Oi)l zq(s*zr374R+619=GohZS0{W`>wvlGa!sRq_RK?shC3tfc`qaFBbQ;ke#A3WCiIbwDb%A@cV>tEG>G@Pa0}9PEq(VnWD4(aJd$rjm{MLK}%v9?hNImLWrE!Y_h#A-ZTU7o=5g%+4f-YIO) zRM6e`{0W~=5r68h-v|H5iKLI1ex65jZ@A-35uOmwLljW_B8Vc0DmJ)OM z(*6#dsQ)qLj#1@+%%to$EAZMKO&i{`$M|K8bpx~gg}k&)#TOS>VW&z4Snmr1+&M(q z80^Y#!vL+W94}RVFAx3fO$H9G=4`WPRZ31|%)OW(H(eY2L~O}Lmi{!lxI<6Jb)RN!O_P?U z@rvmJ0eeT}`r*S8c%s;{{?)^2es>L@yniK~)0itHz4^2rSC9G7*Y%F(;S7p)Yk?T=aEg2z z@bXe1LO2se2pQLinv?$c;|V8CsX_{WymS=RV1Xtgg$G`62_im~Rm1A{PaJjtfMhm@ zu{-Gz;QgsE$nLs3eybL%Eara_VcRDe2=u-~?}xPo=<7+eiQ92B7x}81tFTWZ5X|LH z_pj)J^RnCM3EIw|!bemH(|JXtSid`3u%@Z!`kp^tkcn&m`tt?c23z#?dn5;t{MYap zVSjPc)#r>Rf@?njv)g3(w}?e`ivVR*tr($`TkJM=<*UzBZt*GA7Mj(jj>OxcOsBsH z36*>`Qz})R?`K(-VYqH*26H#iO>ykPBa--53!)tTB?*hft*H&v)j@hS*%tOV7Y|nb zuMOHyXNWc$%jlNhur#1KtYwtdT+m8OyBhx5jvr>W6CI5*Ty^cr(1Ew!tIU03adFeI zaBFz)#e5OYyK$;R#CP_b@;+5nNx+bg(Dw)qWK3FI(j1lQ2 z&iwUq^vR-DGD_UPs_|vuDqAXhL8b25kE*!n<7Or^NUNWFB956q5nsCdT~^b*t?!`V z#L=;9y_pJ9cJcoBQPI02*nQ90kBUXJ1H<22cw4F}M==t5YT7*v6npk6AR@#zRn8Ra zw_8Pm0OVlHXZJyJ;c z_KI(TbE^ETHOtKFYwxT?O@K=!E~|DY^7)Tc&k)vGK1EC)G)1=Tyieo5kZ^I2gLLtS z-r(Z8z0Pbc?B)|@#e+269wMhjMPx~jN>#{3ZX*pw`!-b+M zo;?W&&=a`q&3PMVnj>urg3bi!v7ALIt%PW)MDxoN_z93Cz^*E)NNh%J+t+qAU: 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 literal 0 HcmV?d00001 diff --git a/app_go/go.mod b/app_go/go.mod new file mode 100644 index 0000000000..ed5d7b4f3e --- /dev/null +++ b/app_go/go.mod @@ -0,0 +1,3 @@ +module example.com/devops-info-service + +go 1.25 diff --git a/app_go/main.go b/app_go/main.go new file mode 100644 index 0000000000..194aa657fc --- /dev/null +++ b/app_go/main.go @@ -0,0 +1,286 @@ +// DevOps Info Service in Go. +package main + +import ( + "encoding/json" + "fmt" + "log" + "net" + "net/http" + "os" + "runtime" + "strings" + "time" +) + +const ( + serviceName = "devops-info-service" + serviceVersion = "1.0.0" + serviceDescription = "DevOps course info service" + serviceFramework = "Go net/http" +) + +type ServiceInfo struct { + Name string `json:"name"` + Version string `json:"version"` + Description string `json:"description"` + Framework string `json:"framework"` +} + +type SystemInfo struct { + Hostname string `json:"hostname"` + Platform string `json:"platform"` + PlatformVersion string `json:"platform_version"` + Architecture string `json:"architecture"` + CPUCount int `json:"cpu_count"` + PythonVersion string `json:"python_version"` +} + +type UptimeInfo struct { + Seconds int64 `json:"seconds"` + Human string `json:"human"` +} + +type RequestInfo struct { + ClientIP string `json:"client_ip"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` + Path string `json:"path"` +} + +type EndpointInfo struct { + Path string `json:"path"` + Method string `json:"method"` + Description string `json:"description"` +} + +type RootResponse struct { + Service ServiceInfo `json:"service"` + System SystemInfo `json:"system"` + Runtime UptimeInfo `json:"runtime"` + Request RequestInfo `json:"request"` + Endpoints []EndpointInfo `json:"endpoints"` +} + +type HealthResponse struct { + Status string `json:"status"` + Timestamp string `json:"timestamp"` + UptimeSeconds int64 `json:"uptime_seconds"` +} + +var ( + // startTime is used for uptime calculations. + startTime = time.Now().UTC() + // endpoints is a static list used to mirror the Python app output. + endpoints = []EndpointInfo{ + {Path: "/", Method: http.MethodGet, Description: "Service information."}, + {Path: "/health", Method: http.MethodGet, Description: "Health check endpoint."}, + } +) + +// getServiceInfo returns static service metadata. +func getServiceInfo() ServiceInfo { + return ServiceInfo{ + Name: serviceName, + Version: serviceVersion, + Description: serviceDescription, + Framework: serviceFramework, + } +} + +// getSystemInfo returns host and runtime information. +func getSystemInfo() SystemInfo { + hostname, err := os.Hostname() + if err != nil { + hostname = "unknown" + } + + return SystemInfo{ + Hostname: hostname, + Platform: platformName(), + PlatformVersion: platformVersion(), + Architecture: runtime.GOARCH, + CPUCount: runtime.NumCPU(), + PythonVersion: runtime.Version(), + } +} + +// platformName maps GOOS to a human-readable name. +func platformName() string { + switch runtime.GOOS { + case "linux": + return "Linux" + case "windows": + return "Windows" + case "darwin": + return "Darwin" + default: + return runtime.GOOS + } +} + +// platformVersion attempts to return a friendly OS version. +func platformVersion() string { + switch runtime.GOOS { + case "linux": + if pretty := linuxPrettyName(); pretty != "" { + return pretty + } + case "windows": + if osName := os.Getenv("OS"); osName != "" { + return osName + } + } + + return runtime.GOOS +} + +// linuxPrettyName reads PRETTY_NAME from /etc/os-release if available. +func linuxPrettyName() string { + data, err := os.ReadFile("/etc/os-release") + if err != nil { + return "" + } + + for _, line := range strings.Split(string(data), "\n") { + line = strings.TrimSpace(line) + if strings.HasPrefix(line, "PRETTY_NAME=") { + value := strings.TrimPrefix(line, "PRETTY_NAME=") + return strings.Trim(value, "\"") + } + } + + return "" +} + +// getUptime returns elapsed time since startTime. +func getUptime() UptimeInfo { + seconds := int64(time.Since(startTime).Seconds()) + hours := seconds / 3600 + minutes := (seconds % 3600) / 60 + + return UptimeInfo{ + Seconds: seconds, + Human: fmt.Sprintf("%d hours, %d minutes", hours, minutes), + } +} + +// getRequestInfo captures minimal request metadata. +func getRequestInfo(r *http.Request) RequestInfo { + return RequestInfo{ + ClientIP: clientIP(r), + UserAgent: r.Header.Get("User-Agent"), + Method: r.Method, + Path: r.URL.Path, + } +} + +// clientIP attempts to derive the client IP from proxy headers or RemoteAddr. +func clientIP(r *http.Request) string { + if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" { + parts := strings.Split(forwarded, ",") + return strings.TrimSpace(parts[0]) + } + + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err == nil { + return host + } + + return r.RemoteAddr +} + +// listEndpoints returns the advertised endpoints for the root response. +func listEndpoints() []EndpointInfo { + return endpoints +} + +// mainHandler serves GET /. +func mainHandler(w http.ResponseWriter, r *http.Request) { + payload := RootResponse{ + Service: getServiceInfo(), + System: getSystemInfo(), + Runtime: getUptime(), + Request: getRequestInfo(r), + Endpoints: listEndpoints(), + } + + writeJSON(w, http.StatusOK, payload) +} + +// healthHandler serves GET /health. +func healthHandler(w http.ResponseWriter, r *http.Request) { + payload := HealthResponse{ + Status: "healthy", + Timestamp: time.Now().UTC().Format("2006-01-02T15:04:05.000000-07:00"), + UptimeSeconds: getUptime().Seconds, + } + + writeJSON(w, http.StatusOK, payload) +} + +// notFound returns a JSON 404. +func notFound(w http.ResponseWriter, r *http.Request) { + writeJSON(w, http.StatusNotFound, map[string]string{ + "error": "Not Found", + "message": "Endpoint does not exist", + }) +} + +// router dispatches requests to handlers. +func router(w http.ResponseWriter, r *http.Request) { + switch { + case r.URL.Path == "/" && r.Method == http.MethodGet: + mainHandler(w, r) + case r.URL.Path == "/health" && r.Method == http.MethodGet: + healthHandler(w, r) + default: + notFound(w, r) + } +} + +// recoverMiddleware converts panics into JSON 500 responses. +func recoverMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if err := recover(); err != nil { + log.Printf("panic: %v", err) + writeJSON(w, http.StatusInternalServerError, map[string]string{ + "error": "Internal Server Error", + "message": "An unexpected error occurred", + }) + } + }() + log.Printf("Request: %s %s", r.Method, r.URL.Path) + next.ServeHTTP(w, r) + }) +} + +// writeJSON serializes a payload with the given status code. +func writeJSON(w http.ResponseWriter, status int, payload any) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + if err := json.NewEncoder(w).Encode(payload); err != nil { + log.Printf("encode error: %v", err) + } +} + +func main() { + host := os.Getenv("HOST") + if host == "" { + host = "0.0.0.0" + } + + port := os.Getenv("PORT") + if port == "" { + port = "5000" + } + + addr := net.JoinHostPort(host, port) + log.Printf("Application starting on %s", addr) + + handler := recoverMiddleware(http.HandlerFunc(router)) + if err := http.ListenAndServe(addr, handler); err != nil { + log.Fatalf("server error: %v", err) + } +} diff --git a/app_python/.gitattributes b/app_python/.gitattributes new file mode 100644 index 0000000000..e48505a0fe --- /dev/null +++ b/app_python/.gitattributes @@ -0,0 +1,30 @@ +# https://github.com/gitattributes/gitattributes/blob/fddc586cf0f10ec4485028d0d2dd6f73197a4258/Python.gitattributes +# Basic .gitattributes for a python repo. + +# Source files +# ============ +*.pxd text diff=python +*.py text diff=python +*.py3 text diff=python +*.pyw text diff=python +*.pyx text diff=python +*.pyz text diff=python +*.pyi text diff=python + +# Binary files +# ============ +*.db binary +*.p binary +*.pkl binary +*.pickle binary +*.pyc binary export-ignore +*.pyo binary export-ignore +*.pyd binary + +# Jupyter notebook +*.ipynb text eol=lf + +# Note: .db, .p, and .pkl files are associated +# with the python modules ``pickle``, ``dbm.*``, +# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` +# (among others). diff --git a/app_python/.gitignore b/app_python/.gitignore new file mode 100644 index 0000000000..c33866fe47 --- /dev/null +++ b/app_python/.gitignore @@ -0,0 +1,217 @@ +# https://github.com/github/gitignore/blob/53fee13f20a05efc93ef4edcad0c62863520e268/Python.gitignore +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +.vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml \ No newline at end of file diff --git a/app_python/README.md b/app_python/README.md new file mode 100644 index 0000000000..8c2642e984 --- /dev/null +++ b/app_python/README.md @@ -0,0 +1,39 @@ +# DevOps Info Service + +## Overview + +Small Flask web service that reports service metadata, system information, runtime uptime, and basic request details. Includes a simple health check endpoint for monitoring. + +## Prerequisites + +- Python 3.14 +- Dependencies from `requirements.txt` + +## Installation + +```bash +python -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +``` + +## Running the Application + +```bash +python app.py +# Or with custom config +PORT=8080 HOST=127.0.0.1 python app.py +``` + +## API Endpoints + +- `GET /` - Service and system information +- `GET /health` - Health check + +## Configuration + +| Variable | Default | Description | +| -------- | --------- | ---------------------------------------- | +| `HOST` | `0.0.0.0` | Bind address for the server | +| `PORT` | `5000` | Port to listen on | +| `DEBUG` | `False` | Enable Flask debug mode (`true`/`false`) | diff --git a/app_python/app.py b/app_python/app.py new file mode 100644 index 0000000000..ffce15ef58 --- /dev/null +++ b/app_python/app.py @@ -0,0 +1,184 @@ +""" +DevOps Info Service +Main application module +""" + +__version__ = "1.0.0" + +# Basics +import os +from datetime import datetime, timezone +import logging + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger(__name__) + +# Metadata gathering +from multiprocessing import cpu_count +import platform +import inspect + +# Web +import socket + +from flask import Flask, jsonify, request + +# Configuration +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", 5000)) +DEBUG = os.getenv("DEBUG", "False").lower() == "true" + +app = Flask(__name__) + + +def get_service_info() -> dict[str, str]: + """Collect info about service""" + return { + "name": "devops-info-service", + "version": __version__, + "description": "DevOps course info service", + "framework": "Flask", + } + + +def get_platform_info() -> dict[str, str | int]: + """Collect system information""" + + def _platform_version() -> str: + """Return a human-friendly OS version string.""" + match (platform.system().lower()): + case "linux": + return platform.freedesktop_os_release()["PRETTY_NAME"] + case "windows": + return f"{platform.system()} {platform.win32_ver()[1]}" + case _: + return platform.version() + + return { + "hostname": socket.gethostname(), + "platform": platform.system(), + "platform_version": _platform_version(), + "architecture": platform.machine(), + "cpu_count": cpu_count(), + "python_version": platform.python_version(), + } + + +def get_uptime(): + """Return uptime in seconds and a simple human string.""" + delta = datetime.now(tz=timezone.utc) - START_TIME + up_seconds = int(delta.total_seconds()) + up_hours = up_seconds // 3600 + up_minutes = (up_seconds % 3600) // 60 + return { + "seconds": up_seconds, + "human": f"{up_hours} hours, {up_minutes} minutes", + } + + +def get_runtime(): + """Return current runtime metadata (uptime + UTC timestamp).""" + up = get_uptime() + return { + "uptime_seconds": up["seconds"], + "uptime_human": up["human"], + "current_time": datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "timezone": "UTC", + } + + +def get_request_info(request): + """Return basic request metadata for debugging/telemetry.""" + return { + "client_ip": request.remote_addr, + "user_agent": request.headers.get("User-Agent"), + "method": request.method, + "path": request.path, + } + + +def list_routes() -> list[dict[str, str]]: + """Return a flat list of route + method + description.""" + out: list[dict[str, str]] = [] + + for rule in sorted(app.url_map.iter_rules(), key=lambda r: (r.rule, r.endpoint)): + # Skip Flask's built-in static handler + if rule.endpoint == "static": + continue + + view = app.view_functions.get(rule.endpoint) + + # Description is pulled from docstring's brief (first line) + desc = "" + if view is not None: + desc = inspect.getdoc(view) or "" + desc = desc.splitlines()[0].strip() or "" + + for method in sorted(rule.methods - {"HEAD", "OPTIONS"}): + out.append( + { + "path": rule.rule, + "method": method, + "description": desc, + } + ) + return out + + +@app.route("/") +def index(): + """Service information""" + logger.debug(f"Request: {request.method} {request.path}") + return jsonify( + { + "service": get_service_info(), + "system": get_platform_info(), + "runtime": get_uptime(), + "request": get_request_info(request), + "endpoints": list_routes(), + } + ) + + +@app.route("/health") +def health(): + """Health check""" + logger.debug(f"Request: {request.method} {request.path}") + return jsonify( + { + "status": "healthy", + "timestamp": datetime.now(timezone.utc).isoformat(), + "uptime_seconds": get_uptime()["seconds"], + } + ) + + +@app.errorhandler(404) +def not_found(error): + """Return a JSON 404 payload.""" + logger.debug(f"Request: {request.method} {request.path}") + return jsonify({"error": "Not Found", "message": "Endpoint does not exist"}), 404 + + +@app.errorhandler(500) +def internal_error(error): + """Return a JSON 500 payload.""" + return ( + jsonify( + { + "error": "Internal Server Error", + "message": "An unexpected error occurred", + } + ), + 500, + ) + + +START_TIME = datetime.now(timezone.utc) # Application start time (UTC). +logger.info("Application starting...") + +# TODO use WSGI in production. +if __name__ == "__main__": + app.run(host=HOST, port=PORT, debug=DEBUG) diff --git a/app_python/docs/LAB01.md b/app_python/docs/LAB01.md new file mode 100644 index 0000000000..07894b7146 --- /dev/null +++ b/app_python/docs/LAB01.md @@ -0,0 +1,191 @@ +# LAB01 - DevOps Info Service (Python) + +## Framework Selection + +**Choice:** Flask +**Why:** I did not know any Python web framework for APIs, and Flask felt simplest to start with. Most lab examples were in Flask, so it reduced friction. + +**Comparison (concise):** + +| Framework | Pros | Cons | Fit for this lab | +| -------------- | ------------------------------------ | ------------------------------ | ----------------------------------------- | +| Flask (chosen) | Minimal, easy to learn, flexible | Fewer batteries included | Best for a small info service | +| FastAPI | Great typing, auto docs, async ready | Slightly more concepts upfront | Good, but extra overhead for a simple lab | +| Django | Full stack, ORM, auth | Heavy for a tiny API | Overkill here | + +## Best Practices Applied + +Below are concrete examples from `app.py` and why they matter. + +1. **Configuration via env vars** - makes the service configurable without code changes. + +```python +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", 5000)) +DEBUG = os.getenv("DEBUG", "False").lower() == "true" +``` + +2. **Clear separation into helper functions** - keeps endpoints small and readable. + +```python +def get_system_info() -> dict[str, str | int]: + ... + +def get_uptime(): + ... +``` + +3. **Logging** - provides startup and request diagnostics. + +```python +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger.info("Application starting...") +``` + +4. **Error handling** - consistent JSON errors for clients. + +```python +@app.errorhandler(404) +def not_found(error): + return jsonify({"error": "Not Found", "message": "Endpoint does not exist"}), 404 +``` + +## API Documentation + +### Endpoints + +- `GET /` - service + system + runtime + request info +- `GET /health` - health check + +### Example Requests + +```bash +curl -sS http://127.0.0.1:5000/ | jq +curl -sS http://127.0.0.1:5000/health | jq +``` + +### Example Responses + +`GET /`: + +```json +{ + "endpoints": [ + { + "description": "Service information", + "method": "GET", + "path": "/" + }, + { + "description": "Health check", + "method": "GET", + "path": "/health" + } + ], + "request": { + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/", + "user_agent": "curl/8.18.0" + }, + "runtime": { + "human": "0 hours, 6 minutes", + "seconds": 418 + }, + "service": { + "description": "DevOps course info service", + "framework": "Flask", + "name": "devops-info-service", + "version": "1.0.0" + }, + "system": { + "architecture": "x86_64", + "cpu_count": 8, + "hostname": "aSUS-sTUFf-arch", + "platform": "Linux", + "platform_version": "Arch Linux", + "python_version": "3.14.2" + } +} +``` + +`GET /health`: + +```json +{ + "status": "healthy", + "timestamp": "2026-01-28T20:04:59.234201+00:00", + "uptime_seconds": 426 +} +``` + +## Testing Evidence + +### Screenshot + +![Screenshot of a terminal](img/lab01.png) + +### Output + +```js +$ curl -sS 127.0.0.1:3926 | jq +{ + "endpoints": [ + { + "description": "Service information", + "method": "GET", + "path": "/" + }, + { + "description": "Health check", + "method": "GET", + "path": "/health" + } + ], + "request": { + "client_ip": "127.0.0.1", + "method": "GET", + "path": "/", + "user_agent": "curl/8.18.0" + }, + "runtime": { + "human": "0 hours, 6 minutes", + "seconds": 418 + }, + "service": { + "description": "DevOps course info service", + "framework": "Flask", + "name": "devops-info-service", + "version": "1.0.0" + }, + "system": { + "architecture": "x86_64", + "cpu_count": 8, + "hostname": "aSUS-sTUFf-arch", + "platform": "Linux", + "platform_version": "Arch Linux", + "python_version": "3.14.2" + } +} +``` + +```js +$ curl -sS 127.0.0.1:3926/health | jq +{ + "status": "healthy", + "timestamp": "2026-01-28T20:04:59.234201+00:00", + "uptime_seconds": 426 +} +``` + +## Challenges & Solutions + +1. **Framework choice** - I went with Flask because I did not know any Python API framework and Flask looked simplest; the lab examples were already in Flask. +2. **Listing endpoints dynamically** - I struggled with Flask's routing introspection; a StackOverflow snippet didn't work, and ChatGPT helped me craft a working approach. + +## GitHub Community + +Starring repositories helps me bookmark useful projects and signal appreciation, which improves visibility in open source. Following developers keeps me aware of what classmates and maintainers are doing, supporting collaboration and professional growth. diff --git a/app_python/docs/img/lab01.png b/app_python/docs/img/lab01.png new file mode 100644 index 0000000000000000000000000000000000000000..5316f2f18a193778827f153dc23e0f42cc64cd4d GIT binary patch literal 353760 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

yx8ng@JWQ}vPa$4zpJDCsLs7A4-msethu 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 z%0AW2Q$AQ4*z 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 O-f*(tXIEhBbN(;o$*%SQ literal 0 HcmV?d00001 diff --git a/app_python/requirements.txt b/app_python/requirements.txt new file mode 100644 index 0000000000..91714b4eb2 --- /dev/null +++ b/app_python/requirements.txt @@ -0,0 +1,12 @@ +blinker==1.9.0 +certifi==2026.1.4 +charset-normalizer==3.4.4 +click==8.3.1 +Flask==3.1.2 +idna==3.11 +itsdangerous==2.2.0 +Jinja2==3.1.6 +MarkupSafe==3.0.3 +requests==2.32.5 +urllib3==2.6.3 +Werkzeug==3.1.5 diff --git a/app_python/tests/__init__.py b/app_python/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 819f292a34eab57def07f1f141eface5eff09fba Mon Sep 17 00:00:00 2001 From: LocalT0aster Dan <90502400+LocalT0aster@users.noreply.github.com> Date: Tue, 10 Feb 2026 23:09:07 +0300 Subject: [PATCH 02/16] Lab02 Completed (#2) * lab02 Dockerfile * fix: small adjustments * upd: lab02 docker docs * upd: Dockerized app_go * upd: app_go/LAB02.md --- app_go/.dockerignore | 4 + app_go/Dockerfile | 13 ++ app_go/docs/LAB02.md | 300 +++++++++++++++++++++++++++++++++++++++ app_python/.dockerignore | 4 + app_python/Dockerfile | 13 ++ app_python/README.md | 18 +++ app_python/docs/LAB02.md | 288 +++++++++++++++++++++++++++++++++++++ 7 files changed, 640 insertions(+) create mode 100644 app_go/.dockerignore create mode 100644 app_go/Dockerfile create mode 100644 app_go/docs/LAB02.md create mode 100644 app_python/.dockerignore create mode 100644 app_python/Dockerfile create mode 100644 app_python/docs/LAB02.md diff --git a/app_go/.dockerignore b/app_go/.dockerignore new file mode 100644 index 0000000000..6f1931b7cd --- /dev/null +++ b/app_go/.dockerignore @@ -0,0 +1,4 @@ +* +!go.mod +!go.sum +!*.go diff --git a/app_go/Dockerfile b/app_go/Dockerfile new file mode 100644 index 0000000000..aa269d06e2 --- /dev/null +++ b/app_go/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.25-alpine AS build +WORKDIR /app +# Uncomment for dependency installation +# COPY go.mod go.sum ./ +# RUN go mod download +COPY go.mod *.go ./ +RUN CGO_ENABLED=0 GOOS=linux go build -o devops-info-service.out + +FROM scratch +COPY --from=build /app/devops-info-service.out / +# Use UID:GID to avoid copying user info (/etc/passwd) +USER 10001:10001 +CMD ["/devops-info-service.out"] diff --git a/app_go/docs/LAB02.md b/app_go/docs/LAB02.md new file mode 100644 index 0000000000..d906ab57fb --- /dev/null +++ b/app_go/docs/LAB02.md @@ -0,0 +1,300 @@ +# LAB02 — Multi-Stage Docker Build (Go) + +## Multi-Stage Build Strategy + +The Go service is built with a two-stage Dockerfile: + +1. **Build stage (`golang:1.25-alpine`)** +- Compiles the application binary with `CGO_ENABLED=0 GOOS=linux`. +- Keeps compiler/toolchain in the build environment only. + +2. **Runtime stage (`scratch`)** +- Copies only `devops-info-service.out` from the build stage. +- Runs as non-root with `USER 10001:10001`. +- Contains no package manager, shell, or compiler. + +Dockerfile used: `app_go/Dockerfile` + +```dockerfile +FROM golang:1.25-alpine AS build +WORKDIR /app +COPY go.mod *.go ./ +RUN CGO_ENABLED=0 GOOS=linux go build -o devops-info-service.out + +FROM scratch +COPY --from=build /app/devops-info-service.out / +USER 10001:10001 +CMD ["/devops-info-service.out"] +``` + +Also, `.dockerignore` keeps context minimal: + +```dockerignore +* +!go.mod +!go.sum +!*.go +``` + +## Technical Explanation of Each Stage + +- **`FROM golang:1.25-alpine AS build`** + Provides Go toolchain and Alpine userspace needed to compile. +- **`WORKDIR /app` + `COPY go.mod *.go ./`** + Copies only build inputs (module file and source files). +- **`RUN CGO_ENABLED=0 GOOS=linux go build ...`** + Produces a Linux static binary suitable for `scratch` runtime. +- **`FROM scratch`** + Starts an empty runtime image. +- **`COPY --from=build ...`** + Transfers only the compiled artifact, not compilers or source. +- **`USER 10001:10001`** + Drops root privileges in runtime. + +## Build Process (Terminal Output) + +

+🔨 Build target + +```log +$ docker build --no-cache --progress=plain --target build -t lab02-go:builder . +#0 building with "default" instance using docker driver + +#1 [internal] load build definition from Dockerfile +#1 transferring dockerfile: 424B 0.0s done +#1 DONE 0.1s + +#2 [internal] load metadata for docker.io/library/golang:1.25-alpine +#2 DONE 1.0s + +#3 [internal] load .dockerignore +#3 transferring context: 64B 0.0s done +#3 DONE 0.0s + +#4 [internal] load build context +#4 DONE 0.0s + +#5 [build 1/4] FROM docker.io/library/golang:1.25-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced +#5 resolve docker.io/library/golang:1.25-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced 0.0s done +#5 DONE 0.1s + +#6 [build 2/4] WORKDIR /app +#6 CACHED + +#4 [internal] load build context +#4 transferring context: 54B done +#4 DONE 0.0s + +#7 [build 3/4] COPY go.mod *.go ./ +#7 DONE 0.1s + +#8 [build 4/4] RUN CGO_ENABLED=0 GOOS=linux go build -o devops-info-service.out +#8 DONE 62.8s + +#9 exporting to image +#9 exporting layers +#9 exporting layers 7.4s done +#9 exporting manifest sha256:f3e73461dd53d9f346f612d14a5d7db25b865b7aab912ba8d3cb89a098da0546 +#9 exporting manifest sha256:f3e73461dd53d9f346f612d14a5d7db25b865b7aab912ba8d3cb89a098da0546 0.0s done +#9 exporting config sha256:06ba3662b02750d25c0817c4d26a4d0f77805f722bb6d60fa2b8c04b4308e480 0.0s done +#9 exporting attestation manifest sha256:844a56a9b83102a634becbc82128fa16fd1c41bba4fd9f5c56cf7ed84ec0b2ad 0.0s done +#9 exporting manifest list sha256:f2f7690814f0d4b01954394858a41285da9b7a2a425a2525c36f4f7dfe1577aa done +#9 naming to docker.io/library/lab02-go:builder 0.0s done +#9 unpacking to docker.io/library/lab02-go:builder +#9 unpacking to docker.io/library/lab02-go:builder 1.7s done +#9 DONE 9.4 +``` + +
+ +
+🔨 Final multi-stage target + +```log +$ docker build --no-cache --progress=plain -t lab02-go:final . +#0 building with "default" instance using docker driver + +#1 [internal] load build definition from Dockerfile +#1 transferring dockerfile: 424B 0.0s done +#1 DONE 0.0s + +#2 [internal] load metadata for docker.io/library/golang:1.25-alpine +#2 DONE 0.9s + +#3 [internal] load .dockerignore +#3 transferring context: 64B done +#3 DONE 0.0s + +#4 [internal] load build context +#4 DONE 0.0s + +#5 [build 1/4] FROM docker.io/library/golang:1.25-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced +#5 resolve docker.io/library/golang:1.25-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced 0.0s done +#5 DONE 0.0s + +#6 [build 2/4] WORKDIR /app +#6 CACHED + +#4 [internal] load build context +#4 transferring context: 54B done +#4 DONE 0.0s + +#7 [build 3/4] COPY go.mod *.go ./ +#7 DONE 0.1s + +#8 [build 4/4] RUN CGO_ENABLED=0 GOOS=linux go build -o devops-info-service.out +#8 DONE 67.4s + +#9 [stage-1 1/1] COPY --from=build /app/devops-info-service.out / +#9 DONE 0.1s + +#10 exporting to image +#10 exporting layers +#10 exporting layers 1.0s done +#10 exporting manifest sha256:b3ddddd75de1b8fe87ecf287b479ae5804ae9b73e3c8c88b58553ae1e949d209 +#10 exporting manifest sha256:b3ddddd75de1b8fe87ecf287b479ae5804ae9b73e3c8c88b58553ae1e949d209 0.0s done +#10 exporting config sha256:65c1bd7c8937841b2bb1e5d455bd1ec37dab85a4e0ac4eab15bf50d1fb61d19a done +#10 exporting attestation manifest sha256:2c7f952e05e64da351b651ceb30a12d35c0304ef9fb21d7dd5089b365862464e 0.0s done +#10 exporting manifest list sha256:2d3f56459e956a745bfe802d54a7f652677a6a993406ec23d7d0334f9ec99af5 0.0s done +#10 naming to docker.io/library/lab02-go:final done +#10 unpacking to docker.io/library/lab02-go:final +#10 unpacking to docker.io/library/lab02-go:final 0.2s done +#10 DONE 1.4s +``` + +
+ +## Working Containerized Application (Terminal Output) + +
+Server + +```bash +$ docker run --rm -p 5000:5000 lab02-go:final +2026/02/10 20:02:11 Application starting on 0.0.0.0:5000 +2026/02/10 20:02:27 Request: GET / +2026/02/10 20:03:55 Request: GET /health +``` + +
+ +
+Client + +```json +$ curl -sS 127.0.0.1:5000 | jq +{ + "service": { + "name": "devops-info-service", + "version": "1.0.0", + "description": "DevOps course info service", + "framework": "Go net/http" + }, + "system": { + "hostname": "1208319f6a92", + "platform": "Linux", + "platform_version": "linux", + "architecture": "amd64", + "cpu_count": 1, + "python_version": "go1.25.7" + }, + "runtime": { + "seconds": 15, + "human": "0 hours, 0 minutes" + }, + "request": { + "client_ip": "172.17.0.1", + "user_agent": "curl/8.14.1", + "method": "GET", + "path": "/" + }, + "endpoints": [ + { + "path": "/", + "method": "GET", + "description": "Service information." + }, + { + "path": "/health", + "method": "GET", + "description": "Health check endpoint." + } + ] +} +``` + +```json +$ curl -sS 127.0.0.1:5000/health | jq +{ + "status": "healthy", + "timestamp": "2026-02-10T20:03:55.538319+00:00", + "uptime_seconds": 104 +} +``` + +
+ +## Image Size Comparison and Analysis + + +| Image | Image size | +| ------------------------------------ | ------------ | +| Builder (`lab02-go:builder`) | **85.50MiB** | +| Final multi-stage (`lab02-go:final`) | **4.41MiB** | + +
+⚖️ Measuring command + +```bash +docker inspect -f "{{ .Size }}" | numfmt --to=iec-i --format="%.2f" +``` +
+ +Reduction from builder to final: +- **94.84%** smaller +- **19.39x** smaller runtime image + +These metrics come from the same `docker inspect` size source, so they are directly comparable. + +## Why Multi-Stage Builds Matter for Compiled Languages + +For Go (and similarly Rust/C/C++), the compiler and build toolchain are large and needed only at build time. Multi-stage builds let us: + +- Keep full SDK only in builder stage. +- Ship only the compiled binary in runtime. +- Reduce registry transfer and startup pull time. +- Reduce operational footprint and patch surface in production. + +Without multi-stage, runtime image carries unnecessary build dependencies, increasing size and risk. + +## Security Implications (Smaller Attack Surface) + +Security improvements in this implementation: + +- `scratch` runtime has no shell/package manager/toolchain. +- Non-root runtime user via `USER 10001:10001`. +- Fewer filesystem artifacts (only binary), reducing exposure. + +Practical impact: + +- Fewer components to scan/patch. +- Lower chance of post-exploitation tooling availability inside container. +- Simpler SBOM/runtime dependency graph. + +## Trade-Offs and Decisions + +### Decisions made + +- **Chose `scratch`** for maximal size/security reduction. +- **Used static build (`CGO_ENABLED=0`)** so binary runs in empty base image. +- **Used numeric UID:GID (`10001:10001`)** because `scratch` has no user-management tools. + +### Trade-offs + +- `scratch` is harder to debug (no shell utilities). +- No bundled CA certs/timezone data by default (important if app adds outbound TLS or timezone-sensitive logic later). +- Builder-stage caching is currently simple; if dependencies grow, splitting module download and source copy can improve cache efficiency further. + +## Summary + +The multi-stage approach in `app_go/Dockerfile` produces a working, non-root runtime image and achieves major size reduction compared with keeping the full Go toolchain in the final image. The result is a materially smaller and safer production artifact while preserving application functionality. diff --git a/app_python/.dockerignore b/app_python/.dockerignore new file mode 100644 index 0000000000..2944c29a24 --- /dev/null +++ b/app_python/.dockerignore @@ -0,0 +1,4 @@ +* +!app.py +!requirements.txt +!tests/* diff --git a/app_python/Dockerfile b/app_python/Dockerfile new file mode 100644 index 0000000000..5b1a868024 --- /dev/null +++ b/app_python/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.14-alpine +RUN addgroup appgroup && adduser --disabled-password --gecos "" --no-create-home -s /bin/sh appuser -G appgroup +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +RUN rm requirements.txt + +ENV PORT=5000 +ENV HOST="0.0.0.0" + +USER appuser +CMD ["python", "app.py"] diff --git a/app_python/README.md b/app_python/README.md index 8c2642e984..4258b0b0ee 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -17,6 +17,17 @@ source .venv/bin/activate pip install -r requirements.txt ``` +### Docker + +- Pull the container: + ```bash + docker pull localt0aster/devops-app-py + ``` +- OR build the container yourself: + ```bash + docker build -t localt0aster/devops-app-py . + ``` + ## Running the Application ```bash @@ -25,6 +36,13 @@ python app.py PORT=8080 HOST=127.0.0.1 python app.py ``` +### Docker + +- Run the container: + ```bash + docker run -p 5000:5000 -e HOST="0.0.0.0" -d localt0aster/devops-app-py + ``` + ## API Endpoints - `GET /` - Service and system information diff --git a/app_python/docs/LAB02.md b/app_python/docs/LAB02.md new file mode 100644 index 0000000000..e650b5a669 --- /dev/null +++ b/app_python/docs/LAB02.md @@ -0,0 +1,288 @@ +# LAB02 - Docker Containerization (Python) + +## Docker Best Practices Applied + +1. **Pinned base image version** - guarantees repeatable builds and avoids unexpected upstream changes. + +```Dockerfile +FROM python:3.14-alpine +``` + +2. **Non-root user** - reduces blast radius if the app is compromised. + +```Dockerfile +RUN addgroup appgroup && adduser --disabled-password --gecos "" --no-create-home -s /bin/sh appuser -G appgroup +USER appuser +``` + +3. **Layer caching for dependencies** - installing requirements before copying the full app keeps rebuilds fast when only code changes. + +```Dockerfile +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +``` + +4. **Minimal build context via .dockerignore** - avoids sending unrelated files (venv, git, docs) to the build context. + +```dockerignore +* +!app.py +!requirements.txt +!tests/* +``` + +5. **No pip cache** - prevents leaving package download caches in the image. + +```Dockerfile +RUN pip install --no-cache-dir -r requirements.txt +``` + +6. **Explicit workdir** - ensures all app files live under a single predictable path. + +```Dockerfile +WORKDIR /app +``` + +## Image Information & Decisions + +**Base image chosen:** `python:3.14-alpine` + +**Why:** + +- Pinned Python version for reproducibility. +- Alpine variant keeps the runtime small and reduces attack surface. +- The app is pure-Python, so musl vs glibc compatibility is not an issue here. + +**Final image size:** + +```bash +$ docker inspect -f "{{ .Size }}" localt0aster/devops-app-py:lab.2 | numfmt --to=iec-i --format="%.2f" +22.82Mi +``` + +**Layer structure (top to bottom):** + +- Base image: Python runtime on Alpine. +- User/group creation: creates `appuser` and drops root privileges. +- Workdir: standardizes file locations. +- Dependency layer: copy `requirements.txt`, then install dependencies. +- App layer: copy remaining files into `/app`. +- Cleanup: remove `requirements.txt` (runtime tidiness). +- Runtime config: set `HOST` and `PORT` env vars. +- Switch to non-root user and start app. + +**Optimization choices:** + +- Used Alpine for smaller base image. +- Copied `requirements.txt` separately to maximize build cache hits. +- Used `pip --no-cache-dir` to avoid cached wheel files. +- `.dockerignore` reduces context size and speeds up builds. +- Note: `RUN rm requirements.txt` in a separate layer does not reduce image size; it only removes it from the final filesystem view. + +## Build & Run Process + +
+🔨 Build output + +```log +$ docker build --no-cache --progress=plain -t localt0aster/devops-app-py . +#0 building with "default" instance using docker driver + +#1 [internal] load build definition from Dockerfile +#1 transferring dockerfile: 369B done +#1 DONE 0.0s + +#2 [internal] load metadata for docker.io/library/python:3.14-alpine +#2 DONE 0.5s + +#3 [internal] load .dockerignore +#3 transferring context: 77B done +#3 DONE 0.0s + +#4 [1/7] FROM docker.io/library/python:3.14-alpine@sha256:faee120f7885a06fcc9677922331391fa690d911c020abb9e8025ff3d908e510 +#4 resolve docker.io/library/python:3.14-alpine@sha256:faee120f7885a06fcc9677922331391fa690d911c020abb9e8025ff3d908e510 0.0s done +#4 CACHED + +#5 [internal] load build context +#5 transferring context: 123B done +#5 DONE 0.0s + +#6 [2/7] RUN addgroup appgroup && adduser --disabled-password --gecos "" --no-create-home -s /bin/sh appuser -G appgroup +#6 DONE 0.3s + +#7 [3/7] WORKDIR /app +#7 DONE 0.1s + +#8 [4/7] COPY requirements.txt . +#8 DONE 0.1s + +#9 [5/7] RUN pip install --no-cache-dir -r requirements.txt +#9 4.545 Collecting blinker==1.9.0 (from -r requirements.txt (line 1)) +#9 4.736 Downloading blinker-1.9.0-py3-none-any.whl.metadata (1.6 kB) +#9 4.814 Collecting certifi==2026.1.4 (from -r requirements.txt (line 2)) +#9 4.855 Downloading certifi-2026.1.4-py3-none-any.whl.metadata (2.5 kB) +#9 5.098 Collecting charset-normalizer==3.4.4 (from -r requirements.txt (line 3)) +#9 5.140 Downloading charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl.metadata (37 kB) +#9 5.229 Collecting click==8.3.1 (from -r requirements.txt (line 4)) +#9 5.270 Downloading click-8.3.1-py3-none-any.whl.metadata (2.6 kB) +#9 5.417 Collecting Flask==3.1.2 (from -r requirements.txt (line 5)) +#9 5.458 Downloading flask-3.1.2-py3-none-any.whl.metadata (3.2 kB) +#9 5.517 Collecting idna==3.11 (from -r requirements.txt (line 6)) +#9 5.560 Downloading idna-3.11-py3-none-any.whl.metadata (8.4 kB) +#9 5.608 Collecting itsdangerous==2.2.0 (from -r requirements.txt (line 7)) +#9 5.648 Downloading itsdangerous-2.2.0-py3-none-any.whl.metadata (1.9 kB) +#9 5.711 Collecting Jinja2==3.1.6 (from -r requirements.txt (line 8)) +#9 5.752 Downloading jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB) +#9 5.877 Collecting MarkupSafe==3.0.3 (from -r requirements.txt (line 9)) +#9 5.928 Downloading markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl.metadata (2.7 kB) +#9 6.003 Collecting requests==2.32.5 (from -r requirements.txt (line 10)) +#9 6.048 Downloading requests-2.32.5-py3-none-any.whl.metadata (4.9 kB) +#9 6.120 Collecting urllib3==2.6.3 (from -r requirements.txt (line 11)) +#9 6.160 Downloading urllib3-2.6.3-py3-none-any.whl.metadata (6.9 kB) +#9 6.251 Collecting Werkzeug==3.1.5 (from -r requirements.txt (line 12)) +#9 6.296 Downloading werkzeug-3.1.5-py3-none-any.whl.metadata (4.0 kB) +#9 6.399 Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB) +#9 6.440 Downloading certifi-2026.1.4-py3-none-any.whl (152 kB) +#9 6.530 Downloading charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl (154 kB) +#9 6.577 Downloading click-8.3.1-py3-none-any.whl (108 kB) +#9 6.620 Downloading flask-3.1.2-py3-none-any.whl (103 kB) +#9 6.662 Downloading idna-3.11-py3-none-any.whl (71 kB) +#9 6.704 Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB) +#9 6.743 Downloading jinja2-3.1.6-py3-none-any.whl (134 kB) +#9 6.792 Downloading markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl (23 kB) +#9 6.831 Downloading requests-2.32.5-py3-none-any.whl (64 kB) +#9 6.871 Downloading urllib3-2.6.3-py3-none-any.whl (131 kB) +#9 6.915 Downloading werkzeug-3.1.5-py3-none-any.whl (225 kB) +#9 6.985 Installing collected packages: urllib3, MarkupSafe, itsdangerous, idna, click, charset-normalizer, certifi, blinker, Werkzeug, requests, Jinja2, Flask +#9 8.701 +#9 8.709 Successfully installed Flask-3.1.2 Jinja2-3.1.6 MarkupSafe-3.0.3 Werkzeug-3.1.5 blinker-1.9.0 certifi-2026.1.4 charset-normalizer-3.4.4 click-8.3.1 idna-3.11 itsdangerous-2.2.0 requests-2.32.5 urllib3-2.6.3 +#9 8.710 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning. +#9 9.000 +#9 9.000 [notice] A new release of pip is available: 25.3 -> 26.0.1 +#9 9.000 [notice] To update, run: pip install --upgrade pip +#9 DONE 9.4s + +#10 [6/7] COPY . . +#10 DONE 0.1s + +#11 [7/7] RUN rm requirements.txt +#11 DONE 0.3s + +#12 exporting to image +#12 exporting layers +#12 exporting layers 1.4s done +#12 exporting manifest sha256:0e08d9c814e82ba9bfc64ab9bffca15d59c52f63d1b9db264e10723bf23c2daf +#12 exporting manifest sha256:0e08d9c814e82ba9bfc64ab9bffca15d59c52f63d1b9db264e10723bf23c2daf 0.0s done +#12 exporting config sha256:89b3883bbcb401b8bc8aa815aef1cde31083c25f245921185ce4acae286a51fb 0.0s done +#12 exporting attestation manifest sha256:fbcf722602c9bb0c149874e7052029e55cebf067e88f7448a0282f3b3fb1b926 0.0s done +#12 exporting manifest list sha256:24ce3d2f1f6270cedba6257c73fd1b5105b821025b9e38f87798ca75fba493d7 +#12 exporting manifest list sha256:24ce3d2f1f6270cedba6257c73fd1b5105b821025b9e38f87798ca75fba493d7 0.0s done +#12 naming to docker.io/localt0aster/devops-app-py:latest done +#12 unpacking to docker.io/localt0aster/devops-app-py:latest +#12 unpacking to docker.io/localt0aster/devops-app-py:latest 0.5s done +#12 DONE 2.1s + + 1 warning found (use docker --debug to expand): + - CopyIgnoredFile: Attempting to Copy file "." that is excluded by .dockerignore (line 6) +``` + +
+ +
+🏃 Run output + +```log +$ docker run -p 5000:5000 --rm localt0aster/devops-app-py +2026-02-10 16:52:32,232 - __main__ - INFO - Application starting... + * Serving Flask app 'app' + * Debug mode: off +2026-02-10 16:52:32,238 - werkzeug - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on all addresses (0.0.0.0) + * Running on http://127.0.0.1:5000 + * Running on http://172.17.0.2:5000 +2026-02-10 16:52:32,239 - werkzeug - INFO - Press CTRL+C to quit +2026-02-10 16:53:49,498 - werkzeug - INFO - 172.17.0.1 - - [10/Feb/2026 16:53:49] "GET / HTTP/1.1" 200 - +``` + +
+ +
+🛰️ Endpoint test output + +```json +$ curl -Ss 127.0.0.1:5000 | jq +{ + "endpoints": [ + { + "description": "Service information", + "method": "GET", + "path": "/" + }, + { + "description": "Health check", + "method": "GET", + "path": "/health" + } + ], + "request": { + "client_ip": "172.17.0.1", + "method": "GET", + "path": "/", + "user_agent": "curl/8.14.1" + }, + "runtime": { + "human": "0 hours, 1 minutes", + "seconds": 86 + }, + "service": { + "description": "DevOps course info service", + "framework": "Flask", + "name": "devops-info-service", + "version": "1.0.0" + }, + "system": { + "architecture": "x86_64", + "cpu_count": 1, + "hostname": "bd45062076fd", + "platform": "Linux", + "platform_version": "Alpine Linux v3.23", + "python_version": "3.14.3" + } +} +``` + +
+ +Docker Hub repository URL: + +## Technical Analysis + +**Why this Dockerfile works:** + +- Dependencies are installed before application code, enabling Docker cache reuse. +- Environment variables set defaults that match the Flask app’s config. +- The `CMD` runs the app with `python app.py`, which is the same startup command as local development. +- `USER appuser` prevents the Flask process from running as root. + +**What happens if you change the layer order:** + +- If `COPY . .` comes before `pip install`, any code change will invalidate the cache and force a full dependency reinstall. +- If you install dependencies after copying everything, small edits trigger slower rebuilds. + +**Security considerations implemented:** + +- Non-root user for runtime. +- Minimal base image reduces available tooling and attack surface. +- Pinned base image version reduces supply-chain drift. + +**How .dockerignore improves the build:** + +- Less data sent to the Docker daemon means faster builds. +- Prevents accidental inclusion of venvs, git history, and local artifacts. + +## Challenges & Solutions + +- **Debian to Alpine command differences.** + - Issue: `python:3.14-slim` (Debian) lab examples use `useradd/groupadd`, which don’t exist in `python:3.14-alpine`. + - Fix: use `addgroup` & `adduser` From 21f00dc79b5f35ea9fe2623658d849666d507948 Mon Sep 17 00:00:00 2001 From: LocalT0aster Dan <90502400+LocalT0aster@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:26:18 +0300 Subject: [PATCH 03/16] Lab03 Completed (#3) * feat: switch to poetry * feat: add gunicorn as prod. ready server * feat: actions * Testing * fix: the actions * snyk * fix: disable snyk skip message * docker build every push * upd: docs --- .github/actions/python-setup/action.yml | 57 ++ .github/workflows/python-ci.yml | 56 ++ .github/workflows/python-docker.yml | 82 +++ .github/workflows/python-snyk.yml | 37 ++ app_python/.dockerignore | 6 +- app_python/.flake8 | 4 + app_python/Dockerfile | 22 +- app_python/README.md | 42 +- app_python/docs/LAB03.md | 124 ++++ app_python/poetry.lock | 714 ++++++++++++++++++++++++ app_python/pyproject.toml | 25 + app_python/requirements.txt | 12 - app_python/src/flask_instance.py | 16 + app_python/src/main.py | 27 + app_python/{app.py => src/router.py} | 75 +-- app_python/tests/conftest.py | 14 + app_python/tests/test_endpoints.py | 118 ++++ app_python/tests/test_unit_helpers.py | 93 +++ 18 files changed, 1446 insertions(+), 78 deletions(-) create mode 100644 .github/actions/python-setup/action.yml create mode 100644 .github/workflows/python-ci.yml create mode 100644 .github/workflows/python-docker.yml create mode 100644 .github/workflows/python-snyk.yml create mode 100644 app_python/.flake8 create mode 100644 app_python/docs/LAB03.md create mode 100644 app_python/poetry.lock create mode 100644 app_python/pyproject.toml delete mode 100644 app_python/requirements.txt create mode 100644 app_python/src/flask_instance.py create mode 100644 app_python/src/main.py rename app_python/{app.py => src/router.py} (71%) create mode 100644 app_python/tests/conftest.py create mode 100644 app_python/tests/test_endpoints.py create mode 100644 app_python/tests/test_unit_helpers.py diff --git a/.github/actions/python-setup/action.yml b/.github/actions/python-setup/action.yml new file mode 100644 index 0000000000..25c87fa7c7 --- /dev/null +++ b/.github/actions/python-setup/action.yml @@ -0,0 +1,57 @@ +name: Python Poetry Setup +description: Set up Python + Poetry, cache dependencies, and install project deps + +inputs: + python-version: + description: Python version to install + required: false + default: "3.14" + poetry-version: + description: Poetry version to install + required: false + default: "2.3.2" + working-directory: + description: Project directory containing pyproject.toml + required: false + default: "app_python" + lockfile-path: + description: Path to poetry.lock for cache key invalidation + required: false + default: "app_python/poetry.lock" + install-args: + description: Extra arguments passed to poetry install + required: false + default: "--with dev --no-interaction --no-ansi" + +runs: + using: composite + steps: + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python-version }} + + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + version: ${{ inputs.poetry-version }} + + - name: Configure Poetry virtualenv location + shell: bash + working-directory: ${{ inputs.working-directory }} + run: poetry config virtualenvs.in-project true + + - name: Cache Poetry dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cache/pypoetry + ${{ inputs.working-directory }}/.venv + key: ${{ runner.os }}-py${{ inputs.python-version }}-poetry${{ inputs.poetry-version }}-${{ hashFiles(inputs.lockfile-path) }} + restore-keys: | + ${{ runner.os }}-py${{ inputs.python-version }}-poetry${{ inputs.poetry-version }}- + + - name: Install dependencies + shell: bash + working-directory: ${{ inputs.working-directory }} + run: poetry install ${{ inputs.install-args }} diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000000..712fe39c42 --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,56 @@ +name: Python CI + +on: + push: + paths: + - app_python/** + - .github/actions/python-setup/** + - .github/workflows/python-ci.yml + pull_request: + branches: + - master + paths: + - app_python/** + - .github/actions/python-setup/** + - .github/workflows/python-ci.yml + +jobs: + test: + strategy: + fail-fast: false + matrix: + python-version: [3.14] + poetry-version: [2.3.2] + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: ./app_python + steps: + - uses: actions/checkout@v2 + - name: Setup Python tooling and dependencies + uses: ./.github/actions/python-setup + with: + python-version: ${{ matrix.python-version }} + poetry-version: ${{ matrix.poetry-version }} + working-directory: app_python + lockfile-path: app_python/poetry.lock + install-args: --with dev --no-interaction --no-ansi + - name: Lint with flake8 + run: poetry run flake8 src tests + - name: Test using pytest with coverage report + run: | + mkdir -p test-results + poetry run pytest \ + --junitxml=test-results/pytest-report.xml \ + --cov=src \ + --cov-report=term-missing \ + --cov-report=xml:test-results/coverage.xml + - name: Upload pytest and coverage reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: python-test-reports + path: | + app_python/test-results/pytest-report.xml + app_python/test-results/coverage.xml diff --git a/.github/workflows/python-docker.yml b/.github/workflows/python-docker.yml new file mode 100644 index 0000000000..dde175a645 --- /dev/null +++ b/.github/workflows/python-docker.yml @@ -0,0 +1,82 @@ +name: Python Docker Publish + +on: + push: + branches: + - "lab*" + paths: + - app_python/** + - .github/workflows/python-docker.yml + pull_request: + branches: + - master + types: + - closed + paths: + - app_python/** + - .github/workflows/python-docker.yml + +jobs: + build-and-push-branch: + if: github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Derive lab+sha tag from branch + id: version + run: | + source_branch="${{ github.ref_name }}" + if [[ "$source_branch" =~ ([0-9]+) ]]; then + lab_number="${BASH_REMATCH[1]}" + lab_number=$((10#$lab_number)) + short_sha="${GITHUB_SHA::7}" + echo "branch_tag=1.${lab_number}.${short_sha}" >> "$GITHUB_OUTPUT" + else + echo "Failed to extract lab number from branch: $source_branch" >&2 + exit 1 + fi + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push Docker image (branch) + uses: docker/build-push-action@v6 + with: + context: ./app_python + file: ./app_python/Dockerfile + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/devops-app-py:${{ steps.version.outputs.branch_tag }} + + build-and-push: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Derive lab version tag from merged branch + id: version + run: | + source_branch="${{ github.event.pull_request.head.ref }}" + if [[ "$source_branch" =~ ([0-9]+) ]]; then + lab_number="${BASH_REMATCH[1]}" + lab_number=$((10#$lab_number)) + echo "version_tag=1.${lab_number}" >> "$GITHUB_OUTPUT" + else + echo "Failed to extract lab number from merged branch: $source_branch" >&2 + exit 1 + fi + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: ./app_python + file: ./app_python/Dockerfile + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/devops-app-py:${{ steps.version.outputs.version_tag }} + ${{ secrets.DOCKERHUB_USERNAME }}/devops-app-py:latest diff --git a/.github/workflows/python-snyk.yml b/.github/workflows/python-snyk.yml new file mode 100644 index 0000000000..c3297eccc1 --- /dev/null +++ b/.github/workflows/python-snyk.yml @@ -0,0 +1,37 @@ +name: Python Snyk Scan + +on: + push: + paths: + - app_python/** + - .github/actions/python-setup/** + - .github/workflows/python-snyk.yml + pull_request: + branches: + - master + paths: + - app_python/** + - .github/actions/python-setup/** + - .github/workflows/python-snyk.yml + +jobs: + snyk: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./app_python + steps: + - uses: actions/checkout@v4 + - name: Setup Python tooling and dependencies + uses: ./.github/actions/python-setup + - name: Setup Snyk CLI + uses: snyk/actions/setup@master + - name: Run Snyk dependency scan (or skip) + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: | + if [ -z "${SNYK_TOKEN:-}" ]; then + echo "SNYK_TOKEN secret not set; skipping Snyk dependency scan." + exit 0 + fi + snyk test --severity-threshold=high diff --git a/app_python/.dockerignore b/app_python/.dockerignore index 2944c29a24..511a810855 100644 --- a/app_python/.dockerignore +++ b/app_python/.dockerignore @@ -1,4 +1,4 @@ * -!app.py -!requirements.txt -!tests/* +!src/** +!pyproject.toml +!poetry.lock diff --git a/app_python/.flake8 b/app_python/.flake8 new file mode 100644 index 0000000000..63c477b455 --- /dev/null +++ b/app_python/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 100 +max-complexity = 10 +exclude = .*,docs,*/__pycache__ diff --git a/app_python/Dockerfile b/app_python/Dockerfile index 5b1a868024..e9b02ed024 100644 --- a/app_python/Dockerfile +++ b/app_python/Dockerfile @@ -1,13 +1,23 @@ FROM python:3.14-alpine -RUN addgroup appgroup && adduser --disabled-password --gecos "" --no-create-home -s /bin/sh appuser -G appgroup + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +ENV POETRY_VERSION=2.3.2 + +RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" \ + && addgroup appgroup \ + && adduser --disabled-password --gecos "" --no-create-home -s /bin/sh appuser -G appgroup + WORKDIR /app -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt -COPY . . -RUN rm requirements.txt + +COPY pyproject.toml poetry.lock ./ +RUN poetry config virtualenvs.create false \ + && poetry install --only main --no-interaction --no-ansi --no-root + +COPY src ./src ENV PORT=5000 ENV HOST="0.0.0.0" USER appuser -CMD ["python", "app.py"] +CMD ["sh", "-c", "gunicorn --bind ${HOST:-0.0.0.0}:${PORT:-5000} src.flask_instance:app"] diff --git a/app_python/README.md b/app_python/README.md index 4258b0b0ee..1979c45e82 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,20 +1,20 @@ # DevOps Info Service +[![Python CI](https://github.com/LocalT0aster/DevOps-Core-S26/actions/workflows/python-ci.yml/badge.svg)](https://github.com/LocalT0aster/DevOps-Core-S26/actions/workflows/python-ci.yml) + ## Overview Small Flask web service that reports service metadata, system information, runtime uptime, and basic request details. Includes a simple health check endpoint for monitoring. ## Prerequisites -- Python 3.14 -- Dependencies from `requirements.txt` +- Python 3.13+ +- Poetry ## Installation ```bash -python -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt +poetry install ``` ### Docker @@ -27,13 +27,19 @@ pip install -r requirements.txt ```bash docker build -t localt0aster/devops-app-py . ``` + The Docker build installs dependencies with: + ```bash + poetry install --only main --no-root + ``` ## Running the Application +Production-style local run with Gunicorn: + ```bash -python app.py +poetry run gunicorn --bind 0.0.0.0:5000 src.flask_instance:app # Or with custom config -PORT=8080 HOST=127.0.0.1 python app.py +HOST=127.0.0.1 PORT=8080 poetry run gunicorn --bind 127.0.0.1:8080 src.flask_instance:app ``` ### Docker @@ -55,3 +61,25 @@ PORT=8080 HOST=127.0.0.1 python app.py | `HOST` | `0.0.0.0` | Bind address for the server | | `PORT` | `5000` | Port to listen on | | `DEBUG` | `False` | Enable Flask debug mode (`true`/`false`) | + +## Testing + +The project uses `pytest` for unit tests. + +```bash +poetry install --with dev +poetry run pytest --cov=src --cov-report=term-missing +``` + +## Linting + +```bash +poetry run flake8 src tests +``` + +Current test coverage includes: + +- `GET /` successful response schema and types +- `GET /health` successful response schema and types +- `404` JSON error handling for unknown routes +- `500` JSON error handling for simulated internal failures diff --git a/app_python/docs/LAB03.md b/app_python/docs/LAB03.md new file mode 100644 index 0000000000..5f12e800e1 --- /dev/null +++ b/app_python/docs/LAB03.md @@ -0,0 +1,124 @@ +# LAB03 - Continuous Integration (Python) + +## 1. Overview + +**Testing framework used:** `pytest` + +**Why this choice:** + +- concise assertions and clear failure output +- fixtures simplify Flask test-client setup +- `monkeypatch` enables controlled error-path testing + +**What is covered by tests:** + +- endpoint tests for `GET /` and `GET /health` (success + error behavior) +- JSON schema/type assertions +- helper/unit tests for runtime/platform/request metadata +- entrypoint behavior test for `main.run()` argument wiring + +**Current CI trigger configuration:** + +- workflow files: + - `.github/workflows/python-ci.yml` (lint + tests + coverage reports) + - `.github/workflows/python-snyk.yml` (security scan) + - `.github/workflows/python-docker.yml` (container publish) +- note: Docker login/build/push is intentionally separated into `python-docker.yml` rather than embedded in `python-ci.yml`. +- triggers: + - CI/Snyk: `push` + `pull_request` with path filters + - Docker publish: + - branch pushes to `lab*` publish `1..` + - merged PRs to `master` publish `1.` + `latest` + +**Versioning strategy (SemVer/CalVer):** + +- SemVer-style lab release tags: `1.` + `latest` +- lab number is extracted from merged branch name (example: `lab03` -> `1.3`) + +## 2. Workflow Evidence + +Provide links/terminal output for: + +- Tests passing locally (terminal output below) +- Successful workflow run links (GitHub Actions): + - Python CI: + - Python Docker Publish: + - Python Snyk Scan: +- Docker image on Docker Hub (links): + - Tags page: + - Example pushed tag (`1.3.d4ae1ce`): +- Status badge in `app_python/README.md`: + - + +
+pytest output log + +```log +$ poetry run pytest --cov=src --cov-report=term-missing +========================= test session starts ========================= +platform linux -- Python 3.14.2, pytest-9.0.2, pluggy-1.6.0 +rootdir: /home/t0ast/Repos/DevOps-Core-S26/app_python +configfile: pyproject.toml +plugins: anyio-4.12.1, mock-3.15.1, cov-7.0.0 +collected 10 items + +tests/test_endpoints.py ..... [ 50%] +tests/test_unit_helpers.py ..... [100%] + +=========================== tests coverage ============================ +___________ coverage: platform linux, python 3.14.2-final-0 ___________ + +Name Stmts Miss Cover Missing +----------------------------------------------------- +src/flask_instance.py 7 0 100% +src/main.py 10 0 100% +src/router.py 60 0 100% +----------------------------------------------------- +TOTAL 77 0 100% +========================= 10 passed in 0.06s ========================== +``` + +
+ +## 3. Best Practices Implemented + +- **Practice 1: Path-based trigger filtering**: avoids running Python CI when unrelated folders change. +- **Practice 2: Lint + test stages in CI**: catches style and functional issues early. +- **Practice 3: Coverage reporting in CI command**: makes test quality visible, not just pass/fail. +- **Practice 4: Pipeline separation by concern**: test, security, and deploy concerns run independently for clearer failure diagnosis. +- **Practice 5: Reusable setup action**: shared Python/Poetry setup is centralized in `.github/actions/python-setup/action.yml` to avoid duplication. +- **Caching**: `actions/cache` stores `~/.cache/pypoetry` and `app_python/.venv` using a `poetry.lock`-based key. +- **Snyk**: integrated via `snyk/actions/setup` + `snyk test --severity-threshold=high`. +- **Snyk token handling**: workflow skips Snyk step if `SNYK_TOKEN` secret is missing. + +
+Snyk result (run #21961075835) + +``` +Testing /home/runner/work/DevOps-Core-S26/DevOps-Core-S26/app_python... + +Organization: localt0aster +Package manager: poetry +Target file: pyproject.toml +Project name: devops-info-service +Open source: no +Project path: /home/runner/work/DevOps-Core-S26/DevOps-Core-S26/app_python +Licenses: enabled + +✔ Tested 15 dependencies for known issues, no vulnerable paths found. +``` + +
+ +## 4. Key Decisions + +- **Versioning Strategy:** SemVer-style `1.` because releases happen once per lab and are easy to map back to coursework milestones. +- **Docker Tags:** branch builds publish `1..`; merged lab releases publish `1.` and `latest`. +- **Workflow Triggers:** path-filtered pushes/PRs for CI and Snyk, with container publishing gated on merged PRs to `master`. +- **Test Coverage:** endpoint and helper logic are covered; launcher-only code is excluded with pragma. +- **Snyk policy:** CI fails only for vulnerabilities at `high` severity or above. + +## 5. Challenges (Optional) + +- Moving from endpoint-only tests to helper-level unit tests increased meaningful coverage. +- Local and CI environments may have different tool availability; Poetry-based commands are used for reproducibility. diff --git a/app_python/poetry.lock b/app_python/poetry.lock new file mode 100644 index 0000000000..e4918ed237 --- /dev/null +++ b/app_python/poetry.lock @@ -0,0 +1,714 @@ +# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. + +[[package]] +name = "blinker" +version = "1.9.0" +description = "Fast, simple object-to-object and broadcast signaling" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"}, + {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"}, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, +] + +[[package]] +name = "click" +version = "8.3.1" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, + {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +markers = {main = "platform_system == \"Windows\"", dev = "sys_platform == \"win32\""} + +[[package]] +name = "coverage" +version = "7.13.4" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"}, + {file = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"}, + {file = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"}, + {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"}, + {file = "coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"}, + {file = "coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"}, + {file = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"}, + {file = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"}, + {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"}, + {file = "coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"}, + {file = "coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"}, + {file = "coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"}, + {file = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"}, + {file = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"}, + {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"}, + {file = "coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"}, + {file = "coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"}, + {file = "coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"}, + {file = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"}, + {file = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"}, + {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"}, + {file = "coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"}, + {file = "coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"}, + {file = "coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"}, + {file = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"}, + {file = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"}, + {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"}, + {file = "coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"}, + {file = "coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"}, + {file = "coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"}, + {file = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"}, + {file = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"}, + {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"}, + {file = "coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"}, + {file = "coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"}, + {file = "coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"}, + {file = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"}, + {file = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"}, + {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"}, + {file = "coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"}, + {file = "coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"}, + {file = "coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"}, + {file = "coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"}, + {file = "coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"}, +] + +[package.extras] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] + +[[package]] +name = "flake8" +version = "7.3.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e"}, + {file = "flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.14.0,<2.15.0" +pyflakes = ">=3.4.0,<3.5.0" + +[[package]] +name = "flask" +version = "3.1.2" +description = "A simple framework for building complex web applications." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c"}, + {file = "flask-3.1.2.tar.gz", hash = "sha256:bf656c15c80190ed628ad08cdfd3aaa35beb087855e2f494910aa3774cc4fd87"}, +] + +[package.dependencies] +blinker = ">=1.9.0" +click = ">=8.1.3" +itsdangerous = ">=2.2.0" +jinja2 = ">=3.1.2" +markupsafe = ">=2.1.1" +werkzeug = ">=3.1.0" + +[package.extras] +async = ["asgiref (>=3.2)"] +dotenv = ["python-dotenv"] + +[[package]] +name = "gunicorn" +version = "25.0.3" +description = "WSGI HTTP Server for UNIX" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "gunicorn-25.0.3-py3-none-any.whl", hash = "sha256:aca364c096c81ca11acd4cede0aaeea91ba76ca74e2c0d7f879154db9d890f35"}, + {file = "gunicorn-25.0.3.tar.gz", hash = "sha256:b53a7fff1a07b825b962af320554de44ae77a26abfa373711ff3f83d57d3506d"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +eventlet = ["eventlet (>=0.40.3)"] +gevent = ["gevent (>=24.10.1)"] +http2 = ["h2 (>=4.1.0)"] +setproctitle = ["setproctitle"] +testing = ["coverage", "eventlet (>=0.40.3)", "gevent (>=24.10.1)", "h2 (>=4.1.0)", "httpx[http2]", "pytest", "pytest-asyncio", "pytest-cov", "uvloop (>=0.19.0)"] +tornado = ["tornado (>=6.5.0)"] + +[[package]] +name = "idna" +version = "3.11" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "iniconfig" +version = "2.3.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, +] + +[[package]] +name = "itsdangerous" +version = "2.2.0" +description = "Safely pass data to untrusted environments and back." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, + {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "markupsafe" +version = "3.0.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, + {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, + {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, + {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, + {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, + {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, + {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, + {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, + {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "packaging" +version = "26.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, +] + +[[package]] +name = "pep8-naming" +version = "0.15.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pep8_naming-0.15.1-py3-none-any.whl", hash = "sha256:eb63925e7fd9e028c7f7ee7b1e413ec03d1ee5de0e627012102ee0222c273c86"}, + {file = "pep8_naming-0.15.1.tar.gz", hash = "sha256:f6f4a499aba2deeda93c1f26ccc02f3da32b035c8b2db9696b730ef2c9639d29"}, +] + +[package.dependencies] +flake8 = ">=5.0.0" + +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +description = "Python style guide checker" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d"}, + {file = "pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783"}, +] + +[[package]] +name = "pyflakes" +version = "3.4.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f"}, + {file = "pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58"}, +] + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pytest" +version = "9.0.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}, + {file = "pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "7.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"}, + {file = "pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"}, +] + +[package.dependencies] +coverage = {version = ">=7.10.6", extras = ["toml"]} +pluggy = ">=1.2" +pytest = ">=7" + +[package.extras] +testing = ["process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "requests" +version = "2.32.5" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, + {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "urllib3" +version = "2.6.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, +] + +[package.extras] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] + +[[package]] +name = "werkzeug" +version = "3.1.5" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "werkzeug-3.1.5-py3-none-any.whl", hash = "sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc"}, + {file = "werkzeug-3.1.5.tar.gz", hash = "sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67"}, +] + +[package.dependencies] +markupsafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[metadata] +lock-version = "2.1" +python-versions = ">=3.13" +content-hash = "5bcb333e951818ca4706d50bae307ab22a95462b6e393691b1a6d0992e4ffc41" diff --git a/app_python/pyproject.toml b/app_python/pyproject.toml new file mode 100644 index 0000000000..1e8b7fba15 --- /dev/null +++ b/app_python/pyproject.toml @@ -0,0 +1,25 @@ +[tool.poetry] +name = "devops-info-service" +version = "0.1.0" +description = "" +authors = ["LocalT0aster"] +readme = "README.md" +packages = [{ include = "src" }] + +[tool.poetry.dependencies] +python = ">=3.13" +flask = ">=3.1.2,<4.0.0" +requests = ">=2.32.5,<3.0.0" +gunicorn = "^25.0.3" + +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" + +[dependency-groups] +dev = [ + "pytest (>=9.0.2,<10.0.0)", + "pytest-cov (>=7.0.0,<8.0.0)", + "flake8 (>=7.3.0,<8.0.0)", + "pep8-naming (>=0.15.1,<0.16.0)" +] diff --git a/app_python/requirements.txt b/app_python/requirements.txt deleted file mode 100644 index 91714b4eb2..0000000000 --- a/app_python/requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -blinker==1.9.0 -certifi==2026.1.4 -charset-normalizer==3.4.4 -click==8.3.1 -Flask==3.1.2 -idna==3.11 -itsdangerous==2.2.0 -Jinja2==3.1.6 -MarkupSafe==3.0.3 -requests==2.32.5 -urllib3==2.6.3 -Werkzeug==3.1.5 diff --git a/app_python/src/flask_instance.py b/app_python/src/flask_instance.py new file mode 100644 index 0000000000..7f3267ba03 --- /dev/null +++ b/app_python/src/flask_instance.py @@ -0,0 +1,16 @@ +""" +Flask app instance and shared process-level state. +""" + +from datetime import datetime, timezone +import logging + +from flask import Flask + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger(__name__) + +app = Flask("DevOps Info Service") +START_TIME = datetime.now(timezone.utc) # Application start time (UTC). diff --git a/app_python/src/main.py b/app_python/src/main.py new file mode 100644 index 0000000000..d2d7356067 --- /dev/null +++ b/app_python/src/main.py @@ -0,0 +1,27 @@ +""" +DevOps Info Service +Application runtime entrypoint. +""" + +import os + +try: + from .flask_instance import app, logger + from . import router # noqa: F401 +except ImportError: # pragma: no cover - allows `python src/main.py` + from flask_instance import app, logger + import router # noqa: F401 + +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", 5000)) +DEBUG = os.getenv("DEBUG", "False").lower() == "true" + + +def run() -> None: + """Run development server.""" + logger.info("Application starting...") + app.run(host=HOST, port=PORT, debug=DEBUG) + + +if __name__ == "__main__": # pragma: no cover + run() diff --git a/app_python/app.py b/app_python/src/router.py similarity index 71% rename from app_python/app.py rename to app_python/src/router.py index ffce15ef58..994b1340e4 100644 --- a/app_python/app.py +++ b/app_python/src/router.py @@ -1,40 +1,25 @@ """ -DevOps Info Service -Main application module +Route handlers and response helpers. """ -__version__ = "1.0.0" - -# Basics -import os from datetime import datetime, timezone -import logging - -logging.basicConfig( - level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" -) -logger = logging.getLogger(__name__) - -# Metadata gathering +import inspect from multiprocessing import cpu_count import platform -import inspect - -# Web import socket -from flask import Flask, jsonify, request +from flask import jsonify, request -# Configuration -HOST = os.getenv("HOST", "0.0.0.0") -PORT = int(os.getenv("PORT", 5000)) -DEBUG = os.getenv("DEBUG", "False").lower() == "true" +try: + from .flask_instance import START_TIME, app, logger +except ImportError: # pragma: no cover - allows `python src/main.py` + from flask_instance import START_TIME, app, logger -app = Flask(__name__) +__version__ = "1.0.0" def get_service_info() -> dict[str, str]: - """Collect info about service""" + """Collect info about service.""" return { "name": "devops-info-service", "version": __version__, @@ -44,11 +29,11 @@ def get_service_info() -> dict[str, str]: def get_platform_info() -> dict[str, str | int]: - """Collect system information""" + """Collect system information.""" def _platform_version() -> str: """Return a human-friendly OS version string.""" - match (platform.system().lower()): + match platform.system().lower(): case "linux": return platform.freedesktop_os_release()["PRETTY_NAME"] case "windows": @@ -66,7 +51,7 @@ def _platform_version() -> str: } -def get_uptime(): +def get_uptime() -> dict[str, str | int]: """Return uptime in seconds and a simple human string.""" delta = datetime.now(tz=timezone.utc) - START_TIME up_seconds = int(delta.total_seconds()) @@ -78,7 +63,7 @@ def get_uptime(): } -def get_runtime(): +def get_runtime() -> dict[str, str | int]: """Return current runtime metadata (uptime + UTC timestamp).""" up = get_uptime() return { @@ -89,13 +74,13 @@ def get_runtime(): } -def get_request_info(request): +def get_request_info(req) -> dict[str, str | None]: """Return basic request metadata for debugging/telemetry.""" return { - "client_ip": request.remote_addr, - "user_agent": request.headers.get("User-Agent"), - "method": request.method, - "path": request.path, + "client_ip": req.remote_addr, + "user_agent": req.headers.get("User-Agent"), + "method": req.method, + "path": req.path, } @@ -104,13 +89,11 @@ def list_routes() -> list[dict[str, str]]: out: list[dict[str, str]] = [] for rule in sorted(app.url_map.iter_rules(), key=lambda r: (r.rule, r.endpoint)): - # Skip Flask's built-in static handler if rule.endpoint == "static": continue view = app.view_functions.get(rule.endpoint) - # Description is pulled from docstring's brief (first line) desc = "" if view is not None: desc = inspect.getdoc(view) or "" @@ -129,8 +112,8 @@ def list_routes() -> list[dict[str, str]]: @app.route("/") def index(): - """Service information""" - logger.debug(f"Request: {request.method} {request.path}") + """Service information.""" + logger.debug("Request: %s %s", request.method, request.path) return jsonify( { "service": get_service_info(), @@ -144,8 +127,8 @@ def index(): @app.route("/health") def health(): - """Health check""" - logger.debug(f"Request: {request.method} {request.path}") + """Health check.""" + logger.debug("Request: %s %s", request.method, request.path) return jsonify( { "status": "healthy", @@ -156,14 +139,14 @@ def health(): @app.errorhandler(404) -def not_found(error): +def not_found(error): # noqa: ARG001 """Return a JSON 404 payload.""" - logger.debug(f"Request: {request.method} {request.path}") + logger.debug("Request: %s %s", request.method, request.path) return jsonify({"error": "Not Found", "message": "Endpoint does not exist"}), 404 @app.errorhandler(500) -def internal_error(error): +def internal_error(error): # noqa: ARG001 """Return a JSON 500 payload.""" return ( jsonify( @@ -174,11 +157,3 @@ def internal_error(error): ), 500, ) - - -START_TIME = datetime.now(timezone.utc) # Application start time (UTC). -logger.info("Application starting...") - -# TODO use WSGI in production. -if __name__ == "__main__": - app.run(host=HOST, port=PORT, debug=DEBUG) diff --git a/app_python/tests/conftest.py b/app_python/tests/conftest.py new file mode 100644 index 0000000000..eef52e6a63 --- /dev/null +++ b/app_python/tests/conftest.py @@ -0,0 +1,14 @@ +"""Shared pytest fixtures for app endpoint tests.""" + +import pytest + +from src.flask_instance import app +import src.router # noqa: F401 # Ensure route decorators are loaded. + + +@pytest.fixture() +def client(): + """Return a Flask test client without starting a real HTTP server.""" + app.config.update(TESTING=True, PROPAGATE_EXCEPTIONS=False) + with app.test_client() as test_client: + yield test_client diff --git a/app_python/tests/test_endpoints.py b/app_python/tests/test_endpoints.py new file mode 100644 index 0000000000..d0aca40338 --- /dev/null +++ b/app_python/tests/test_endpoints.py @@ -0,0 +1,118 @@ +"""Unit tests for HTTP endpoints and error handling.""" + +from datetime import datetime + +import src.router as router + + +def _raise_runtime_error() -> None: + raise RuntimeError("simulated failure") + + +def test_index_returns_expected_json_structure_and_types(client): + """GET / should return the expected nested schema with stable field types.""" + response = client.get( + "/", + headers={"User-Agent": "pytest-suite/1.0"}, + environ_overrides={"REMOTE_ADDR": "203.0.113.7"}, + ) + + assert response.status_code == 200 + payload = response.get_json() + assert payload is not None + + assert {"service", "system", "runtime", "request", "endpoints"} <= payload.keys() + + service = payload["service"] + assert service["name"] == "devops-info-service" + assert service["framework"] == "Flask" + assert isinstance(service["version"], str) + assert isinstance(service["description"], str) + + system = payload["system"] + assert isinstance(system["hostname"], str) + assert system["hostname"] + assert isinstance(system["platform"], str) + assert isinstance(system["platform_version"], str) + assert isinstance(system["architecture"], str) + assert isinstance(system["cpu_count"], int) + assert system["cpu_count"] >= 1 + assert isinstance(system["python_version"], str) + + runtime = payload["runtime"] + assert isinstance(runtime["seconds"], int) + assert runtime["seconds"] >= 0 + assert isinstance(runtime["human"], str) + + request = payload["request"] + assert request["client_ip"] == "203.0.113.7" + assert request["user_agent"] == "pytest-suite/1.0" + assert request["method"] == "GET" + assert request["path"] == "/" + + endpoints = payload["endpoints"] + assert isinstance(endpoints, list) + assert endpoints + for endpoint in endpoints: + assert {"path", "method", "description"} <= endpoint.keys() + assert isinstance(endpoint["path"], str) + assert isinstance(endpoint["method"], str) + assert isinstance(endpoint["description"], str) + + route_index = {(endpoint["method"], endpoint["path"]) for endpoint in endpoints} + assert ("GET", "/") in route_index + assert ("GET", "/health") in route_index + + +def test_health_returns_expected_json_structure_and_types(client): + """GET /health should report healthy status and typed runtime metadata.""" + response = client.get("/health") + + assert response.status_code == 200 + payload = response.get_json() + assert payload is not None + + assert {"status", "timestamp", "uptime_seconds"} <= payload.keys() + assert payload["status"] == "healthy" + assert isinstance(payload["uptime_seconds"], int) + assert payload["uptime_seconds"] >= 0 + + parsed_timestamp = datetime.fromisoformat(payload["timestamp"]) + assert parsed_timestamp.tzinfo is not None + + +def test_unknown_endpoint_returns_json_404(client): + """Unknown routes should be handled by JSON 404 error handler.""" + response = client.get("/definitely-does-not-exist") + + assert response.status_code == 404 + assert response.get_json() == { + "error": "Not Found", + "message": "Endpoint does not exist", + } + + +def test_index_returns_json_500_when_platform_probe_fails(client, monkeypatch): + """GET / should return JSON 500 when an internal helper crashes.""" + monkeypatch.setattr(router, "get_platform_info", _raise_runtime_error) + + response = client.get("/") + + assert response.status_code == 500 + assert response.get_json() == { + "error": "Internal Server Error", + "message": "An unexpected error occurred", + } + + +def test_health_returns_json_500_when_uptime_probe_fails(client, monkeypatch): + """GET /health should return JSON 500 when uptime collection crashes.""" + monkeypatch.setattr(router, "get_uptime", _raise_runtime_error) + + response = client.get("/health") + + assert response.status_code == 500 + assert response.get_json() == { + "error": "Internal Server Error", + "message": "An unexpected error occurred", + } diff --git a/app_python/tests/test_unit_helpers.py b/app_python/tests/test_unit_helpers.py new file mode 100644 index 0000000000..a17f071a61 --- /dev/null +++ b/app_python/tests/test_unit_helpers.py @@ -0,0 +1,93 @@ +"""Unit tests for helper functions and app entrypoint behavior.""" + +from datetime import datetime +from unittest.mock import Mock + +from flask import request + +from src.flask_instance import app +import src.main as main +import src.router as router + + +def test_run_calls_flask_app_with_configured_host_port_debug(monkeypatch): + """main.run should log startup and pass module config into app.run.""" + run_mock = Mock() + info_mock = Mock() + + monkeypatch.setattr(main, "HOST", "127.0.0.1") + monkeypatch.setattr(main, "PORT", 5050) + monkeypatch.setattr(main, "DEBUG", True) + monkeypatch.setattr(main.app, "run", run_mock) + monkeypatch.setattr(main.logger, "info", info_mock) + + main.run() + + info_mock.assert_called_once_with("Application starting...") + run_mock.assert_called_once_with(host="127.0.0.1", port=5050, debug=True) + + +def test_get_runtime_maps_uptime_payload(monkeypatch): + """get_runtime should map uptime fields and produce UTC timestamp text.""" + monkeypatch.setattr( + router, + "get_uptime", + lambda: {"seconds": 42, "human": "0 hours, 0 minutes"}, + ) + + runtime = router.get_runtime() + + assert runtime["uptime_seconds"] == 42 + assert runtime["uptime_human"] == "0 hours, 0 minutes" + assert runtime["timezone"] == "UTC" + assert runtime["current_time"].endswith("Z") + datetime.strptime(runtime["current_time"], "%Y-%m-%dT%H:%M:%SZ") + + +def test_get_platform_info_windows_platform_version_branch(monkeypatch): + """Windows branch should format platform_version from win32 metadata.""" + monkeypatch.setattr(router.platform, "system", lambda: "Windows") + monkeypatch.setattr(router.platform, "win32_ver", lambda: ("", "11", "", "")) + monkeypatch.setattr(router.platform, "machine", lambda: "AMD64") + monkeypatch.setattr(router.platform, "python_version", lambda: "3.14.2") + monkeypatch.setattr(router.socket, "gethostname", lambda: "test-host") + monkeypatch.setattr(router, "cpu_count", lambda: 8) + + payload = router.get_platform_info() + + assert payload["platform"] == "Windows" + assert payload["platform_version"] == "Windows 11" + assert payload["hostname"] == "test-host" + assert payload["cpu_count"] == 8 + + +def test_get_platform_info_default_platform_version_branch(monkeypatch): + """Non-Linux and non-Windows branch should use platform.version().""" + monkeypatch.setattr(router.platform, "system", lambda: "Darwin") + monkeypatch.setattr(router.platform, "version", lambda: "Darwin Kernel 25.0") + monkeypatch.setattr(router.platform, "machine", lambda: "arm64") + monkeypatch.setattr(router.platform, "python_version", lambda: "3.14.2") + monkeypatch.setattr(router.socket, "gethostname", lambda: "mac-host") + monkeypatch.setattr(router, "cpu_count", lambda: 10) + + payload = router.get_platform_info() + + assert payload["platform"] == "Darwin" + assert payload["platform_version"] == "Darwin Kernel 25.0" + + +def test_get_request_info_returns_none_when_user_agent_missing(): + """Missing User-Agent header should map to None without crashing.""" + with app.test_request_context( + "/diagnostic", + method="POST", + environ_base={"REMOTE_ADDR": "198.51.100.9"}, + ): + info = router.get_request_info(request) + + assert info == { + "client_ip": "198.51.100.9", + "user_agent": None, + "method": "POST", + "path": "/diagnostic", + } From 5f4006edae5b5b9e608699ab40ea36cf4d466fdf Mon Sep 17 00:00:00 2001 From: LocalT0aster Dan <90502400+LocalT0aster@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:05:03 +0300 Subject: [PATCH 04/16] Lab04 (#4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * waiting for images to pull, lol * I wish that I had more than 96K internet speed on my pc * Lab04 completed yay🎉 --- .gitignore | 32 +- docker/provision_vm.sh | 30 ++ docs/LAB04.md | 657 +++++++++++++++++++++++++++++ pulumi/.gitignore | 2 + pulumi/Pulumi.dev.yaml.example | 10 + pulumi/Pulumi.yaml | 11 + pulumi/__main__.py | 82 ++++ pulumi/requirements.txt | 2 + terraform/README.md | 45 ++ terraform/main.tf | 82 ++++ terraform/outputs.tf | 39 ++ terraform/terraform.tfvars.example | 13 + terraform/variables.tf | 80 ++++ terraform/versions.tf | 10 + 14 files changed, 1094 insertions(+), 1 deletion(-) create mode 100755 docker/provision_vm.sh create mode 100644 docs/LAB04.md create mode 100644 pulumi/.gitignore create mode 100644 pulumi/Pulumi.dev.yaml.example create mode 100644 pulumi/Pulumi.yaml create mode 100644 pulumi/__main__.py create mode 100644 pulumi/requirements.txt create mode 100644 terraform/README.md create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/terraform.tfvars.example create mode 100644 terraform/variables.tf create mode 100644 terraform/versions.tf diff --git a/.gitignore b/.gitignore index 30d74d2584..67e6b52b28 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,31 @@ -test \ No newline at end of file +test + +# Terraform +**/.terraform/* +*.tfstate +*.tfstate.* +*.tfplan +tfplan +*.tfvars +*.tfvars.json +crash.log +override.tf +override.tf.json +*_override.tf +*_override.tf.json +.terraform.lock.hcl + +# Pulumi +.pulumi/ +pulumi/.venv/ +pulumi/venv/ +pulumi/Pulumi.*.yaml + +# Python caches +__pycache__/ +*.py[cod] +.pytest_cache/ +.mypy_cache/ + +# IDE +.vscode/ diff --git a/docker/provision_vm.sh b/docker/provision_vm.sh new file mode 100755 index 0000000000..b79bfd3c4d --- /dev/null +++ b/docker/provision_vm.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -euo pipefail + +: "${VM_USER:?VM_USER must be set}" +: "${SSH_PUBLIC_KEY:?SSH_PUBLIC_KEY must be set}" + +export DEBIAN_FRONTEND=noninteractive + +if ! command -v sshd >/dev/null 2>&1; then + apt-get update + apt-get install -y --no-install-recommends openssh-server ca-certificates +fi + +id -u "${VM_USER}" >/dev/null 2>&1 || useradd -m -s /bin/bash "${VM_USER}" +install -d -m 700 -o "${VM_USER}" -g "${VM_USER}" "/home/${VM_USER}/.ssh" +printf '%s\n' "${SSH_PUBLIC_KEY}" >"/home/${VM_USER}/.ssh/authorized_keys" +chown "${VM_USER}:${VM_USER}" "/home/${VM_USER}/.ssh/authorized_keys" +chmod 600 "/home/${VM_USER}/.ssh/authorized_keys" + +mkdir -p /run/sshd +cat >/etc/ssh/sshd_config.d/lab04.conf < container `22` + - HTTP: host `0.0.0.0:80` -> container `80` + - App: host `0.0.0.0:5000` -> container `5000` +- Public IP equivalent: `127.0.0.1`. +- Cost: `$0`. + +## 2. Terraform (OpenTofu) Implementation + +- CLI used: OpenTofu `v1.10.9` (Terraform-compatible HCL). +- Project path: `terraform/`. +- Main files: + - `versions.tf`: provider + required version. + - `main.tf`: network + Ubuntu VM container + startup bootstrap for SSH service + published ports. + - `variables.tf`: bind IPs, host ports, labels. + - `outputs.tf`: endpoints and connection commands. +- Project structure: split into `versions.tf` (providers), `variables.tf` (inputs), `main.tf` (resources), and `outputs.tf` (connection/output values) for readability and predictable diffs. + +### Key Decisions + +- Used Ubuntu image directly to keep `apply` simple and avoid local custom image build failures. +- Used startup bootstrap in a separate shell script (`docker/provision_vm.sh`) to avoid duplicated provisioning logic across Terraform and Pulumi. +- Kept `80` and `5000` port mappings defined in IaC, but did not run mock HTTP services in the container. +- Bound SSH to `127.0.0.1` by default to reduce exposure. + +### Challenges + +- Provider download from registry/GitHub release assets may timeout on slow links. +- Workaround: local plugin mirror (`~/.terraform.d/plugins`) if direct provider install fails. + +### Command Output + +
+`tofu plan` + +``` +$ tofu plan + +OpenTofu used the selected providers to generate the following execution plan. Resource +actions are indicated with the following symbols: + + create + +OpenTofu will perform the following actions: + + # docker_container.vm will be created + + resource "docker_container" "vm" { + + attach = false + + bridge = (known after apply) + + command = [ + + "/bin/bash", + + "-lc", + + <<-EOT + #!/usr/bin/env bash + + set -euo pipefail + + : "${VM_USER:?VM_USER must be set}" + : "${SSH_PUBLIC_KEY:?SSH_PUBLIC_KEY must be set}" + + export DEBIAN_FRONTEND=noninteractive + + if ! command -v sshd >/dev/null 2>&1; then + apt-get update + apt-get install -y --no-install-recommends openssh-server ca-certificates + fi + + id -u "${VM_USER}" >/dev/null 2>&1 || useradd -m -s /bin/bash "${VM_USER}" + install -d -m 700 -o "${VM_USER}" -g "${VM_USER}" "/home/${VM_USER}/.ssh" + printf '%s\n' "${SSH_PUBLIC_KEY}" >"/home/${VM_USER}/.ssh/authorized_keys" + chown "${VM_USER}:${VM_USER}" "/home/${VM_USER}/.ssh/authorized_keys" + chmod 600 "/home/${VM_USER}/.ssh/authorized_keys" + + mkdir -p /run/sshd + cat >/etc/ssh/sshd_config.d/lab04.conf < + +
+`tofu apply` + +``` +$ tofu apply + +OpenTofu used the selected providers to generate the following execution plan. Resource +actions are indicated with the following symbols: + + create + +OpenTofu will perform the following actions: + + # docker_container.vm will be created + + resource "docker_container" "vm" { + + attach = false + + bridge = (known after apply) + + command = [ + + "/bin/bash", + + "-lc", + + <<-EOT + #!/usr/bin/env bash + + set -euo pipefail + + : "${VM_USER:?VM_USER must be set}" + : "${SSH_PUBLIC_KEY:?SSH_PUBLIC_KEY must be set}" + + export DEBIAN_FRONTEND=noninteractive + + if ! command -v sshd >/dev/null 2>&1; then + apt-get update + apt-get install -y --no-install-recommends openssh-server ca-certificates + fi + + id -u "${VM_USER}" >/dev/null 2>&1 || useradd -m -s /bin/bash "${VM_USER}" + install -d -m 700 -o "${VM_USER}" -g "${VM_USER}" "/home/${VM_USER}/.ssh" + printf '%s\n' "${SSH_PUBLIC_KEY}" >"/home/${VM_USER}/.ssh/authorized_keys" + chown "${VM_USER}:${VM_USER}" "/home/${VM_USER}/.ssh/authorized_keys" + chmod 600 "/home/${VM_USER}/.ssh/authorized_keys" + + mkdir -p /run/sshd + cat >/etc/ssh/sshd_config.d/lab04.conf < + +
+SSH test + +``` +$ ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1 echo "SSH available" +The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established. +ED25519 key fingerprint is: SHA256:shGIrzMssSaR8sB9yuUyId7BYrKHyfi/OQSvGJq5gkk +This key is not known by any other names. +Are you sure you want to continue connecting (yes/no/[fingerprint])? yes +Warning: Permanently added '[127.0.0.1]:2222' (ED25519) to the list of known hosts. +SSH available +``` + +
+ +Teardown command (Terraform resources): + +```bash +cd terraform +tofu destroy -auto-approve +``` + +## 3. Pulumi Implementation + +- Pulumi CLI: `v3.192.0` +- Language: Python +- Project path: `pulumi/` +- Resources: + - Docker network + - Docker `RemoteImage` (`ubuntu:24.04`) + - Docker container with same ports as Terraform setup + +### Code Differences vs Terraform + +- Terraform uses declarative HCL resources and variable blocks. +- Pulumi uses Python (`__main__.py`) and typed constructor args (`docker.ContainerPortArgs`, `docker.ContainerLabelArgs`). +- The shared provisioning logic is loaded from `docker/provision_vm.sh` in both implementations, but Pulumi reads it via `Path(...).read_text()`, while Terraform uses `file(...)`. + +### Advantages Discovered + +- Strong typing and native language constructs in Python made refactoring (for example, shared provisioning script usage) easier. +- Pulumi outputs and resource objects map naturally to normal programming workflows. +- For this lab size, Pulumi and Terraform were both fast enough; Pulumi felt better when logic started to grow. + +### Challenges + +- Pulumi passphrase prompts can interrupt command flow if `PULUMI_CONFIG_PASSPHRASE` is not set. +- On Nix/Home-Manager-based setups, `pulumi-language-python` may be missing from `PATH`, which blocks `preview/up` until fixed. +- Docker provider behavior is similar across tools, but plugin/setup issues differ and require separate troubleshooting steps. + +### Command Output + +`tofu destroy` before Pulumi migration: + +```bash +$ tofu destroy -auto-approve +``` + +
+`pulumi preview` + +``` +$ pulumi preview +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing update (dev): + Type Name Plan Info + + pulumi:pulumi:Stack lab04-local-docker-dev create 1 warning + + ├─ docker:index:Network lab04-net create + + ├─ docker:index:RemoteImage lab04-vm-image create + + └─ docker:index:Container lab04-vm create + +Diagnostics: + pulumi:pulumi:Stack (lab04-local-docker-dev): + warning: using pulumi-language-python from $PATH at /etc/profiles/per-user/t0ast/bin/pulumi-language-python + +Outputs: + appUrl : "http://127.0.0.1:5000" + containerShellCommand: "docker exec -it lab04-local-vm /bin/bash" + httpUrl : "http://127.0.0.1:80" + networkName : "lab04-local-net" + publicIpEquivalent : "127.0.0.1" + sshCommand : "ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1" + vmName : "lab04-local-vm" + +Resources: + + 4 to create +``` + +
+ +
+`pulumi up` + +``` +$ pulumi up +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing update (dev): + Type Name Plan Info + + pulumi:pulumi:Stack lab04-local-docker-dev create 1 warning + + ├─ docker:index:RemoteImage lab04-vm-image create + + ├─ docker:index:Network lab04-net create + + └─ docker:index:Container lab04-vm create + +Diagnostics: + pulumi:pulumi:Stack (lab04-local-docker-dev): + warning: using pulumi-language-python from $PATH at /etc/profiles/per-user/t0ast/bin/pulumi-language-python + +Outputs: + appUrl : "http://127.0.0.1:5000" + containerShellCommand: "docker exec -it lab04-local-vm /bin/bash" + httpUrl : "http://127.0.0.1:80" + networkName : "lab04-local-net" + publicIpEquivalent : "127.0.0.1" + sshCommand : "ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1" + vmName : "lab04-local-vm" + +Resources: + + 4 to create + +Do you want to perform this update? yes +Updating (dev): + Type Name Status Info + + pulumi:pulumi:Stack lab04-local-docker-dev created (2s) 1 warning + + ├─ docker:index:RemoteImage lab04-vm-image created (0.01s) + + ├─ docker:index:Network lab04-net created (2s) + + └─ docker:index:Container lab04-vm created (0.38s) + +Diagnostics: + pulumi:pulumi:Stack (lab04-local-docker-dev): + warning: using pulumi-language-python from $PATH at /etc/profiles/per-user/t0ast/bin/pulumi-language-python + +Outputs: + appUrl : "http://127.0.0.1:5000" + containerShellCommand: "docker exec -it lab04-local-vm /bin/bash" + httpUrl : "http://127.0.0.1:80" + networkName : "lab04-local-net" + publicIpEquivalent : "127.0.0.1" + sshCommand : "ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1" + vmName : "lab04-local-vm" + +Resources: + + 4 created + +Duration: 3s +``` + +
+ +
+SSH test + +``` +$ ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1 echo "SSH works" +The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established. +ED25519 key fingerprint is: SHA256:spW/AgFoqrVqpf1i7ZWEUqYGXJ8rZM6wGU5+S4WheVI +This key is not known by any other names. +Are you sure you want to continue connecting (yes/no/[fingerprint])? yes +Warning: Permanently added '[127.0.0.1]:2222' (ED25519) to the list of known hosts. +SSH works +``` + +
+ +Teardown command (Pulumi resources): + +```bash +pulumi destroy --yes +``` + +## 4. Terraform vs Pulumi (Local Docker Case) + +### Ease of Learning + +Terraform/OpenTofu was faster to start because the resource graph is explicit in HCL and examples are abundant. I needed less scaffolding to get a first working run with `tofu init/plan/apply`. Pulumi required understanding stack config and language-plugin behavior in addition to infrastructure code. + +### Code Readability + +For small infrastructure, Terraform is shorter and easier to scan in one file. Pulumi is more verbose, but the Python structure becomes clearer when the project grows and you need reusable helpers. In this lab, Terraform is more concise, while Pulumi is more flexible. + +### Debugging + +Terraform plan/apply diffs are straightforward and helped quickly validate expected port mappings and resource creation. Pulumi diagnostics were helpful when runtime issues occurred, but setup-level failures (passphrase/plugin) were less obvious initially. Once setup was correct, both were manageable to debug. + +### Documentation + +Terraform has broader community examples and more copy-paste-ready snippets for common patterns. Pulumi official docs are good and practical, but there are fewer examples for some edge workflows. For this lab, Terraform documentation felt easier to navigate quickly. + +### Use Case + +I would choose Terraform/OpenTofu for straightforward declarative infrastructure with predictable patterns. I would choose Pulumi when infrastructure logic needs stronger abstraction, conditional behavior, or shared code with application teams. For this local Docker lab, either works, but Terraform was simpler and Pulumi was more programmable. + +## 5. Lab 5 Preparation & Cleanup + +### VM for Lab 5 + +- Are you keeping your VM for Lab 5? **No**. +- What will you use for Lab 5? A local VM via libvirt, or a fresh Linux VPS. + +### Cleanup Status + +- Decision: destroy both Terraform and Pulumi-managed resources after verification. +- Teardown commands used: + +```bash +cd terraform +tofu destroy -auto-approve + +cd ../pulumi +pulumi destroy --yes +``` + +- Verification commands: + +```bash +docker ps --format '{{.Names}}' | rg 'lab04-local' || echo "No lab04 containers" +docker network ls --format '{{.Name}}' | rg 'lab04-local' || echo "No lab04 networks" +``` + +## Notes + +- This is a local Docker-provider adaptation of a cloud-VM lab. +- Suggestion: this lab could also use `localstack/localstack` (or forks) to emulate parts of AWS locally for free. + - + - + - The developer recently stated the end of support for this community image, but there will most probably be forks. diff --git a/pulumi/.gitignore b/pulumi/.gitignore new file mode 100644 index 0000000000..a3807e5bdb --- /dev/null +++ b/pulumi/.gitignore @@ -0,0 +1,2 @@ +*.pyc +venv/ diff --git a/pulumi/Pulumi.dev.yaml.example b/pulumi/Pulumi.dev.yaml.example new file mode 100644 index 0000000000..aaf637b3de --- /dev/null +++ b/pulumi/Pulumi.dev.yaml.example @@ -0,0 +1,10 @@ +config: + lab04-local-docker:projectName: lab04-local + lab04-local-docker:vmUser: devops + lab04-local-docker:sshPublicKey: "ssh-ed25519 AAAA... your-user@host" + lab04-local-docker:sshPrivateKeyPath: "~/.ssh/id_ed25519" + lab04-local-docker:sshBindIp: 127.0.0.1 + lab04-local-docker:publicBindIp: 0.0.0.0 + lab04-local-docker:sshHostPort: "2222" + lab04-local-docker:httpHostPort: "80" + lab04-local-docker:appHostPort: "5000" diff --git a/pulumi/Pulumi.yaml b/pulumi/Pulumi.yaml new file mode 100644 index 0000000000..a4a92ce5d1 --- /dev/null +++ b/pulumi/Pulumi.yaml @@ -0,0 +1,11 @@ +name: lab04-local-docker +description: IaC using Pulumi with local Docker provider. +runtime: + name: python + options: + toolchain: pip + virtualenv: venv +config: + pulumi:tags: + value: + pulumi:template: python diff --git a/pulumi/__main__.py b/pulumi/__main__.py new file mode 100644 index 0000000000..a26adf200d --- /dev/null +++ b/pulumi/__main__.py @@ -0,0 +1,82 @@ +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path + +import pulumi +import pulumi_docker as docker + + +@dataclass(frozen=True) +class HostPorts: + ssh: int + http: int + app: int + + +config = pulumi.Config() + +project_name: str = config.get("projectName") or "lab04-local" +vm_user: str = config.get("vmUser") or "devops" +ssh_public_key: str = config.require("sshPublicKey") +ssh_private_key_path: str = config.get("sshPrivateKeyPath") or "~/.ssh/id_ed25519" +ssh_bind_ip: str = config.get("sshBindIp") or "127.0.0.1" +public_bind_ip: str = config.get("publicBindIp") or "0.0.0.0" + +ports = HostPorts( + ssh=config.get_int("sshHostPort") or 2222, + http=config.get_int("httpHostPort") or 80, + app=config.get_int("appHostPort") or 5000, +) + +labels: dict[str, str] = { + "lab": "04", + "managed-by": "pulumi", + "project": project_name, +} + +bootstrap_script = (Path(__file__).resolve().parent.parent / "docker" / "provision_vm.sh").read_text( + encoding="utf-8" +) + +network = docker.Network( + "lab04-net", + name=f"{project_name}-net", + labels=[docker.NetworkLabelArgs(label=k, value=v) for k, v in labels.items()], +) + +image = docker.RemoteImage( + "lab04-vm-image", + name="ubuntu:24.04", + keep_locally=True, +) + +container = docker.Container( + "lab04-vm", + name=f"{project_name}-vm", + image=image.repo_digest, + hostname=f"{project_name}-vm", + restart="unless-stopped", + command=["/bin/bash", "-lc", bootstrap_script], + envs=[f"VM_USER={vm_user}", f"SSH_PUBLIC_KEY={ssh_public_key}"], + ports=[ + docker.ContainerPortArgs(internal=22, external=ports.ssh, ip=ssh_bind_ip, protocol="tcp"), + docker.ContainerPortArgs(internal=80, external=ports.http, ip=public_bind_ip, protocol="tcp"), + docker.ContainerPortArgs(internal=5000, external=ports.app, ip=public_bind_ip, protocol="tcp"), + ], + labels=[docker.ContainerLabelArgs(label=k, value=v) for k, v in labels.items()], + networks_advanced=[ + docker.ContainerNetworksAdvancedArgs( + name=network.name, + aliases=[f"{project_name}-vm"], + ) + ], +) + +pulumi.export("vmName", container.name) +pulumi.export("networkName", network.name) +pulumi.export("publicIpEquivalent", "127.0.0.1") +pulumi.export("sshCommand", f"ssh -i {ssh_private_key_path} -p {ports.ssh} {vm_user}@127.0.0.1") +pulumi.export("containerShellCommand", f"docker exec -it {project_name}-vm /bin/bash") +pulumi.export("httpUrl", f"http://127.0.0.1:{ports.http}") +pulumi.export("appUrl", f"http://127.0.0.1:{ports.app}") diff --git a/pulumi/requirements.txt b/pulumi/requirements.txt new file mode 100644 index 0000000000..f5a5f5ebd4 --- /dev/null +++ b/pulumi/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4.0.0 +pulumi_docker>=4.0.0,<5.0.0 diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000000..7097fc4b2c --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,45 @@ +# Lab04 Terraform (Local Docker Provider) + +This Terraform project implements Lab04 with the local Docker provider instead of a cloud VM. + +## What It Creates + +- Docker network (`network/VPC` equivalent) +- Ubuntu 24.04 container (`VM/compute` equivalent) with startup bootstrap + - installs and starts `openssh-server` + - configures SSH authorized key + - starts simple HTTP endpoints on ports `80` and `5000` +- Port mappings as firewall equivalents: + - SSH: container `22` -> host `2222` (bound to `127.0.0.1`) + - HTTP: container `80` -> host `8080` + - App: container `5000` -> host `5000` + +## Local Prerequisites + +- Docker daemon running +- OpenTofu or Terraform CLI + +## Quick Start (OpenTofu) + +```bash +cp terraform/terraform.tfvars.example terraform/terraform.tfvars +# edit terraform.tfvars and set ssh_public_key + +cd terraform +tofu init -plugin-dir="$HOME/.terraform.d/plugins" +tofu plan +tofu apply -auto-approve + +# verify SSH +ssh -i ~/.ssh/id_ed25519 -p 2222 devops@127.0.0.1 'echo SSH_OK' +``` + +If provider download is blocked, manually place provider binaries under: +`~/.terraform.d/plugins/registry.terraform.io////linux_amd64/` + +## Destroy + +```bash +cd terraform +tofu destroy -auto-approve +``` diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000000..e5fc12074c --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,82 @@ +provider "docker" { + host = var.docker_host +} + +locals { + vm_name = "${var.project_name}-vm" + bootstrap_script = file("${path.module}/../docker/provision_vm.sh") + + default_labels = { + lab = "04" + managed-by = "terraform" + project = var.project_name + } + + resource_labels = merge(local.default_labels, var.extra_labels) +} + +resource "docker_network" "lab04" { + name = "${var.project_name}-net" + + dynamic "labels" { + for_each = local.resource_labels + + content { + label = labels.key + value = labels.value + } + } +} + +resource "docker_image" "vm_image" { + name = "ubuntu:24.04" + keep_locally = true +} + +resource "docker_container" "vm" { + name = local.vm_name + image = docker_image.vm_image.image_id + hostname = local.vm_name + restart = "unless-stopped" + command = ["/bin/bash", "-lc", local.bootstrap_script] + + env = [ + "VM_USER=${var.vm_user}", + "SSH_PUBLIC_KEY=${var.ssh_public_key}", + ] + + networks_advanced { + name = docker_network.lab04.name + aliases = [local.vm_name] + } + + ports { + internal = 22 + external = var.ssh_host_port + ip = var.ssh_bind_ip + protocol = "tcp" + } + + ports { + internal = 80 + external = var.http_host_port + ip = var.public_bind_ip + protocol = "tcp" + } + + ports { + internal = 5000 + external = var.app_host_port + ip = var.public_bind_ip + protocol = "tcp" + } + + dynamic "labels" { + for_each = local.resource_labels + + content { + label = labels.key + value = labels.value + } + } +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000000..d8130abbce --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,39 @@ +output "vm_name" { + description = "Name of the VM-like Docker container." + value = docker_container.vm.name +} + +output "network_name" { + description = "Name of the Docker network (VPC equivalent)." + value = docker_network.lab04.name +} + +output "container_ip" { + description = "Container IP inside the Docker network." + value = one(docker_container.vm.network_data).ip_address +} + +output "public_ip_equivalent" { + description = "Host endpoint used as public access in the local provider setup." + value = "127.0.0.1" +} + +output "ssh_command" { + description = "SSH command for the VM-like container." + value = "ssh -i ${var.ssh_private_key_path} -p ${var.ssh_host_port} ${var.vm_user}@127.0.0.1" +} + +output "container_shell_command" { + description = "Direct shell access without SSH." + value = "docker exec -it ${docker_container.vm.name} /bin/bash" +} + +output "http_url" { + description = "HTTP endpoint (port 80 equivalent)." + value = "http://127.0.0.1:${var.http_host_port}" +} + +output "app_url" { + description = "Application endpoint (port 5000 equivalent)." + value = "http://127.0.0.1:${var.app_host_port}" +} diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example new file mode 100644 index 0000000000..2642161e51 --- /dev/null +++ b/terraform/terraform.tfvars.example @@ -0,0 +1,13 @@ +ssh_public_key = "ssh-ed25519 AAAA... your-user@host" + +# Optional overrides: +# vm_user = "devops" +# ssh_private_key_path = "~/.ssh/id_ed25519" +# ssh_host_port = 2222 +# http_host_port = 80 +# app_host_port = 5000 +# ssh_bind_ip = "127.0.0.1" +# public_bind_ip = "0.0.0.0" +# extra_labels = { +# owner = "your-name" +# } diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000000..d6ae2bfd65 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,80 @@ +variable "docker_host" { + description = "Docker daemon socket." + type = string + default = "unix:///var/run/docker.sock" +} + +variable "project_name" { + description = "Prefix used for Docker resource names." + type = string + default = "lab04-local" +} + +variable "vm_user" { + description = "Linux username created inside the VM-like container for SSH access." + type = string + default = "devops" +} + +variable "ssh_public_key" { + description = "SSH public key allowed to access the VM-like container." + type = string + sensitive = true +} + +variable "ssh_private_key_path" { + description = "Private key path used in the rendered SSH command output." + type = string + default = "~/.ssh/id_ed25519" +} + +variable "ssh_bind_ip" { + description = "Host IP used for SSH binding. Keep 127.0.0.1 to restrict access." + type = string + default = "127.0.0.1" +} + +variable "public_bind_ip" { + description = "Host IP used for HTTP and app ports." + type = string + default = "0.0.0.0" +} + +variable "ssh_host_port" { + description = "Host port mapped to container port 22." + type = number + default = 2222 + + validation { + condition = var.ssh_host_port >= 1 && var.ssh_host_port <= 65535 + error_message = "ssh_host_port must be between 1 and 65535." + } +} + +variable "http_host_port" { + description = "Host port mapped to container port 80." + type = number + default = 80 + + validation { + condition = var.http_host_port >= 1 && var.http_host_port <= 65535 + error_message = "http_host_port must be between 1 and 65535." + } +} + +variable "app_host_port" { + description = "Host port mapped to container port 5000." + type = number + default = 5000 + + validation { + condition = var.app_host_port >= 1 && var.app_host_port <= 65535 + error_message = "app_host_port must be between 1 and 65535." + } +} + +variable "extra_labels" { + description = "Additional Docker labels to attach to resources." + type = map(string) + default = {} +} diff --git a/terraform/versions.tf b/terraform/versions.tf new file mode 100644 index 0000000000..db6d92cec4 --- /dev/null +++ b/terraform/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.9.0" + + required_providers { + docker = { + source = "registry.terraform.io/kreuzwerker/docker" + version = "~> 3.6" + } + } +} From 43081ff09ced2a367125bdcb9dced9e056c0ba88 Mon Sep 17 00:00:00 2001 From: LocalT0aster Dan <90502400+LocalT0aster@users.noreply.github.com> Date: Thu, 5 Mar 2026 23:57:13 +0300 Subject: [PATCH 05/16] Lab05 Completed (#5) * Vagrant VM * fix: Vagrant provisioning * Lab 5 done --- ansible/.gitignore | 3 + ansible/ansible.cfg | 13 + ansible/docs/LAB05.md | 319 ++++++++++++++++++ ansible/group_vars/all.yml | 22 ++ ansible/inventory/hosts.ini | 6 + ansible/playbooks/deploy.yml | 14 + ansible/playbooks/provision.yml | 18 + ansible/playbooks/site.yml | 3 + ansible/requirements.yml | 3 + .../defaults/app_deploy_defaults.yml | 22 ++ .../handlers/app_deploy_handlers.yml | 6 + .../app_deploy/tasks/app_deploy_tasks.yml | 88 +++++ .../roles/common/defaults/common_defaults.yml | 13 + ansible/roles/common/tasks/common_tasks.yml | 27 ++ .../roles/docker/defaults/docker_defaults.yml | 18 + .../roles/docker/handlers/docker_handlers.yml | 5 + ansible/roles/docker/tasks/docker_tasks.yml | 56 +++ vagrant/.gitignore | 9 + vagrant/README.md | 67 ++++ vagrant/Vagrantfile | 56 +++ vagrant/shared/provision-post-kernel.sh | 7 + vagrant/shared/provision.sh | 11 + 22 files changed, 786 insertions(+) create mode 100644 ansible/.gitignore create mode 100644 ansible/ansible.cfg create mode 100644 ansible/docs/LAB05.md create mode 100644 ansible/group_vars/all.yml create mode 100644 ansible/inventory/hosts.ini create mode 100644 ansible/playbooks/deploy.yml create mode 100644 ansible/playbooks/provision.yml create mode 100644 ansible/playbooks/site.yml create mode 100644 ansible/requirements.yml create mode 100644 ansible/roles/app_deploy/defaults/app_deploy_defaults.yml create mode 100644 ansible/roles/app_deploy/handlers/app_deploy_handlers.yml create mode 100644 ansible/roles/app_deploy/tasks/app_deploy_tasks.yml create mode 100644 ansible/roles/common/defaults/common_defaults.yml create mode 100644 ansible/roles/common/tasks/common_tasks.yml create mode 100644 ansible/roles/docker/defaults/docker_defaults.yml create mode 100644 ansible/roles/docker/handlers/docker_handlers.yml create mode 100644 ansible/roles/docker/tasks/docker_tasks.yml create mode 100644 vagrant/.gitignore create mode 100644 vagrant/README.md create mode 100644 vagrant/Vagrantfile create mode 100755 vagrant/shared/provision-post-kernel.sh create mode 100755 vagrant/shared/provision.sh diff --git a/ansible/.gitignore b/ansible/.gitignore new file mode 100644 index 0000000000..bd991b335c --- /dev/null +++ b/ansible/.gitignore @@ -0,0 +1,3 @@ +*.retry +.ansible/ +.vault_pass diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000000..a9c4a0b6a7 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,13 @@ +[defaults] +inventory = inventory/hosts.ini +roles_path = roles +host_key_checking = False +remote_user = ubuntu +retry_files_enabled = False +inject_facts_as_vars = False +vault_password_file = .vault_pass + +[privilege_escalation] +become = True +become_method = sudo +become_user = root diff --git a/ansible/docs/LAB05.md b/ansible/docs/LAB05.md new file mode 100644 index 0000000000..fedb8571b1 --- /dev/null +++ b/ansible/docs/LAB05.md @@ -0,0 +1,319 @@ +# LAB05 - Ansible Fundamentals + +## 1. Architecture Overview + +- Ansible version: `ansible [core 2.20.0]` +- Target VM OS/version: Ubuntu `24.04` +- Project layout: + +```text +ansible/ +├── inventory/hosts.ini +├── roles/ +│ ├── common/ +│ │ ├── tasks/common_tasks.yml +│ │ └── defaults/common_defaults.yml +│ ├── docker/ +│ │ ├── tasks/docker_tasks.yml +│ │ ├── defaults/docker_defaults.yml +│ │ └── handlers/docker_handlers.yml +│ └── app_deploy/ +│ ├── tasks/app_deploy_tasks.yml +│ ├── defaults/app_deploy_defaults.yml +│ └── handlers/app_deploy_handlers.yml +├── playbooks/ +│ ├── provision.yml +│ ├── deploy.yml +│ └── site.yml +├── group_vars/all.yml # encrypted with Ansible Vault +├── ansible.cfg +└── docs/LAB05.md +``` + +- Why roles instead of monolithic playbooks: + - Roles isolate concern-specific logic (base OS, Docker, app deploy). + - Reuse is easier across hosts/projects with role defaults. + - Testing and maintenance are simpler because responsibilities are separated. + - `include_role` with `tasks_from/defaults_from/handlers_from` keeps file names descriptive. + +## 2. Roles Documentation + +### `common` + +- Purpose: Baseline host configuration (APT cache, common tools, timezone). +- Key variables: + - `common_packages` + - `common_manage_timezone` + - `common_timezone` +- Handlers: none. +- Dependencies: none. + +### `docker` + +- Purpose: Install Docker CE from official Docker repository and prepare host for Docker Ansible modules. +- Key variables: + - `docker_packages` + - `docker_user` + - `docker_install_python_sdk` +- Handlers: + - `restart docker` +- Dependencies: + - Requires Ubuntu host and internet access. + +### `app_deploy` + +- Purpose: Authenticate to Docker Hub, pull image, replace container when needed, and verify app health. +- Key variables: + - `dockerhub_username` + - `dockerhub_password` (vaulted) + - `docker_image`, `docker_image_tag` + - `app_container_name`, `app_port` +- Handlers: + - `restart app container` +- Dependencies: + - Docker engine installed/running on target host. + +## 3. Idempotency Demonstration + +
+First run (`provision.yml`) +
+ +``` +$ ansible-playbook playbooks/provision.yml + +PLAY [Provision web servers] **************************************************************************** + +TASK [Gathering Facts] ********************************************************************************** +ok: [vagrant] + +TASK [Run common role tasks/defaults] ******************************************************************* +included: common for vagrant + +TASK [common : Update apt cache] ************************************************************************ +changed: [vagrant] + +TASK [common : Install common packages] ***************************************************************** +ok: [vagrant] + +TASK [common : Set /etc/timezone] *********************************************************************** +ok: [vagrant] + +TASK [common : Point /etc/localtime to selected timezone] *********************************************** +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ********************************************************** +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] ************************************************************ +changed: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************************************** +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************************************** +changed: [vagrant] + +TASK [docker : Add Docker apt repository] *************************************************************** +changed: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************************************** +changed: [vagrant] + +TASK [docker : Install Docker Python SDK package] ******************************************************* +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************************************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] ***************************************************** +changed: [vagrant] + +RUNNING HANDLER [docker : restart docker] *************************************************************** +changed: [vagrant] + +PLAY RECAP ********************************************************************************************** +vagrant : ok=16 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +
+Second run (`provision.yml`) + +``` +$ ansible-playbook playbooks/provision.yml + +PLAY [Provision web servers] *********************************************************************************************************** + +TASK [Gathering Facts] ***************************************************************************************************************** +ok: [vagrant] + +TASK [Run common role tasks/defaults] ************************************************************************************************** +included: common for vagrant + +TASK [common : Update apt cache] ******************************************************************************************************* +ok: [vagrant] + +TASK [common : Install common packages] ************************************************************************************************ +ok: [vagrant] + +TASK [common : Set /etc/timezone] ****************************************************************************************************** +ok: [vagrant] + +TASK [common : Point /etc/localtime to selected timezone] ****************************************************************************** +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ***************************************************************************************** +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] ******************************************************************************************* +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ********************************************************************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ***************************************************************************************************** +ok: [vagrant] + +TASK [docker : Add Docker apt repository] ********************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ***************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ************************************************************************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] *************************************************************************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] ************************************************************************************ +ok: [vagrant] + +PLAY RECAP ***************************************************************************************************************************** +vagrant : ok=15 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 +``` + +
+ +### Analysis + +- First run: package/repository/service tasks report `changed`. +- Second run: all `ok` with `changed=0`. +- Idempotency is achieved by declarative module states (`state: present`, `state: started`, etc.). + +## 4. Ansible Vault Usage + +- Secrets are stored in `group_vars/all.yml`. +- File is encrypted with: + +```bash +ansible-vault encrypt group_vars/all.yml +``` + +- Why Vault matters: + - Protects credentials in VCS. + - Prevents accidental secret leakage in plaintext config files. + +## 5. Deployment Verification + +
+Deploy output + +``` +$ ansible-playbook playbooks/deploy.yml + +PLAY [Deploy application] ************************************************************************* + +TASK [Gathering Facts] **************************************************************************** +ok: [vagrant] + +TASK [Run app deploy role tasks/defaults/handlers] ************************************************ +included: app_deploy for vagrant + +TASK [app_deploy : Resolve Docker Hub auth secret] ************************************************ +ok: [vagrant] + +TASK [app_deploy : Validate required Docker Hub credentials] ************************************** +ok: [vagrant] => { + "changed": false, + "msg": "All assertions passed" +} + +TASK [app_deploy : Log in to Docker Hub] ********************************************************** +ok: [vagrant] + +TASK [app_deploy : Pull application image] ******************************************************** +ok: [vagrant] + +TASK [app_deploy : Check whether application container already exists] **************************** +ok: [vagrant] + +TASK [app_deploy : Stop existing container before replacement] ************************************ +skipping: [vagrant] + +TASK [app_deploy : Remove old container before replacement] *************************************** +skipping: [vagrant] + +TASK [app_deploy : Run application container] ***************************************************** +ok: [vagrant] + +TASK [app_deploy : Wait for application port] ***************************************************** +ok: [vagrant -> localhost] + +TASK [app_deploy : Verify application health endpoint] ******************************************** +ok: [vagrant -> localhost] + +PLAY RECAP **************************************************************************************** +vagrant : ok=10 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0 +``` + +
+ + +
+Container status + + +``` +$ ansible webservers -a "docker ps" +vagrant | CHANGED | rc=0 >> +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +6051f50e3f87 localt0aster/devops-app-py:latest "gunicorn --bind 0.0…" 8 minutes ago Up 8 minutes 0.0.0.0:5000->5000/tcp devops-app +``` + +
+ +### Health checks + +```bash +$ curl -fSsL 192.168.121.50:5000/health | jq +{ + "status": "healthy", + "timestamp": "2026-03-05T20:55:15.731873+00:00", + "uptime_seconds": 816 +} +``` + +## 6. Key Decisions + +- Why use roles instead of plain playbooks? + - Roles reduce duplication and keep each domain-focused (OS, Docker, app). + +- How do roles improve reusability? + - Defaults/handlers/tasks are reusable by attaching the same role to new host groups. + +- What makes a task idempotent? + - The task declares target state and changes only when current state differs. + +- How do handlers improve efficiency? + - Handlers execute only when notified by changed tasks, so restarts are conditional. + +- Why is Ansible Vault necessary? + - It allows storing sensitive values in the repository without exposing plaintext secrets. + +## 7. Challenges + +- Initial deploy attempt failed with 404 on `/health`. +- Root cause: container command ran `src.flask_instance:app` (routes not imported there). +- Fix: override container command to `src.main:app`, and run delegated health checks with `become: false` while using inventory host (`ansible_host`). +- After fix, deploy rerun completed with `failed=0` and healthy status. diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml new file mode 100644 index 0000000000..8750d6b89b --- /dev/null +++ b/ansible/group_vars/all.yml @@ -0,0 +1,22 @@ +$ANSIBLE_VAULT;1.1;AES256 +39666562623135653036646261306635633634636232343333323866353531663931323438303138 +6633626630373139366232303730333766313330396266350a306530353938393263613230653865 +36316564363836633665366665363761333165373333303537353163376330376131636534636337 +6334623331643265330a373134326364376662643939396262313932326564316637666463633533 +63653666326265303566306331633165313161323130303962303734636638663832613039636361 +33666165613732336435376430396662613864363766303764353934333038636564316637656337 +32396261633039343635346439323532386665343065626438666265336335313433626562616261 +65663136613337326662643433316336346163643235303861613835366635623363396632643365 +65326466313366343530633163633434633365653462643438343730376339646363636239316139 +39306234353863666563393239343337396662383764333038386230363838353766626465616561 +35353262396465643135666436653938643836623862356539653463306434313862393435336535 +65346661316261363063623364356433663031626631386336636137353262653462636132626266 +33626530393235343039316139376339396366396135643864646236353365336536663264386534 +62653931396464636264333034373336666636643636653236356432663133633263656535386137 +32666362313331356532313963393230343332373931346638353463356333383963373131356537 +31633736363531366238346166336639303864376461313933303033306230623765633238633561 +32626463373235633461343365643135613561376634383536323131393932396362666430653633 +65336466323438636232386132653535623862333336666163346334303965376365353263663861 +33396363656361313134323063336638633639313038643636623631663336303632303462346235 +64626634653062663039393930316532326565663434633132306231306465336333633062396439 +6162 diff --git a/ansible/inventory/hosts.ini b/ansible/inventory/hosts.ini new file mode 100644 index 0000000000..da56b99798 --- /dev/null +++ b/ansible/inventory/hosts.ini @@ -0,0 +1,6 @@ +[webservers] +# Update host/user/key for your VM from Lab 4 +vagrant ansible_host=192.168.121.50 ansible_user=vagrant ansible_port=22 ansible_ssh_private_key_file=~/.ssh/vagrant + +[webservers:vars] +ansible_python_interpreter=/usr/bin/python3 diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml new file mode 100644 index 0000000000..0710726c35 --- /dev/null +++ b/ansible/playbooks/deploy.yml @@ -0,0 +1,14 @@ +--- +- name: Deploy application + hosts: webservers + become: true + vars_files: + - ../group_vars/all.yml + + tasks: + - name: Run app deploy role tasks/defaults/handlers + ansible.builtin.include_role: + name: app_deploy + tasks_from: app_deploy_tasks + defaults_from: app_deploy_defaults + handlers_from: app_deploy_handlers diff --git a/ansible/playbooks/provision.yml b/ansible/playbooks/provision.yml new file mode 100644 index 0000000000..77ccedc3a1 --- /dev/null +++ b/ansible/playbooks/provision.yml @@ -0,0 +1,18 @@ +--- +- name: Provision web servers + hosts: webservers + become: true + + tasks: + - name: Run common role tasks/defaults + ansible.builtin.include_role: + name: common + tasks_from: common_tasks + defaults_from: common_defaults + + - name: Run docker role tasks/defaults/handlers + ansible.builtin.include_role: + name: docker + tasks_from: docker_tasks + defaults_from: docker_defaults + handlers_from: docker_handlers diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml new file mode 100644 index 0000000000..139c08f693 --- /dev/null +++ b/ansible/playbooks/site.yml @@ -0,0 +1,3 @@ +--- +- import_playbook: provision.yml +- import_playbook: deploy.yml diff --git a/ansible/requirements.yml b/ansible/requirements.yml new file mode 100644 index 0000000000..660f775816 --- /dev/null +++ b/ansible/requirements.yml @@ -0,0 +1,3 @@ +--- +collections: + - name: community.docker diff --git a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml new file mode 100644 index 0000000000..b98b9d0b27 --- /dev/null +++ b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml @@ -0,0 +1,22 @@ +--- +app_name: devops-app-py +docker_image: "{{ dockerhub_username }}/{{ app_name }}" +docker_image_tag: latest + +app_port: 5000 +app_container_name: devops-app +app_container_internal_port: 5000 +app_restart_policy: unless-stopped + +app_environment: + HOST: "0.0.0.0" + PORT: "{{ app_container_internal_port | string }}" +app_container_command: "gunicorn --bind 0.0.0.0:{{ app_container_internal_port }} src.main:app" + +app_healthcheck_path: /health +app_healthcheck_retries: 20 +app_healthcheck_delay: 3 +app_healthcheck_timeout: 3 +app_recreate_on_pull: true +app_healthcheck_host: "{{ ansible_host | default(inventory_hostname) }}" +app_healthcheck_delegate_to: localhost diff --git a/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml b/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml new file mode 100644 index 0000000000..1fc3fba48b --- /dev/null +++ b/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml @@ -0,0 +1,6 @@ +--- +- name: restart app container + community.docker.docker_container: + name: "{{ app_container_name }}" + state: started + restart: true diff --git a/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml b/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml new file mode 100644 index 0000000000..4bab455012 --- /dev/null +++ b/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml @@ -0,0 +1,88 @@ +--- +- name: Resolve Docker Hub auth secret + ansible.builtin.set_fact: + dockerhub_auth_secret: "{{ dockerhub_password | default(docker_api_token | default('')) }}" + no_log: true + +- name: Validate required Docker Hub credentials + ansible.builtin.assert: + that: + - dockerhub_username is defined + - dockerhub_username | string | length > 0 + - dockerhub_auth_secret | string | length > 0 + fail_msg: >- + Missing Docker Hub credentials. Define dockerhub_username and one of: + dockerhub_password or docker_api_token in ansible/group_vars/all.yml (vaulted). + +- name: Log in to Docker Hub + community.docker.docker_login: + registry_url: https://index.docker.io/v1/ + username: "{{ dockerhub_username }}" + password: "{{ dockerhub_auth_secret }}" + no_log: true + +- name: Pull application image + community.docker.docker_image: + name: "{{ docker_image }}:{{ docker_image_tag }}" + source: pull + register: app_image_pull + notify: restart app container + +- name: Check whether application container already exists + community.docker.docker_container_info: + name: "{{ app_container_name }}" + register: app_container_info + +- name: Stop existing container before replacement + community.docker.docker_container: + name: "{{ app_container_name }}" + state: stopped + when: + - app_container_info.exists | bool + - app_recreate_on_pull | bool + - app_image_pull.changed + - app_container_info.container is defined and app_container_info.container.State.Running | default(false) + +- name: Remove old container before replacement + community.docker.docker_container: + name: "{{ app_container_name }}" + state: absent + when: + - app_container_info.exists | bool + - app_recreate_on_pull | bool + - app_image_pull.changed + +- name: Run application container + community.docker.docker_container: + name: "{{ app_container_name }}" + image: "{{ docker_image }}:{{ docker_image_tag }}" + command: "{{ app_container_command | default(omit) }}" + state: started + restart_policy: "{{ app_restart_policy }}" + ports: + - "{{ app_port }}:{{ app_container_internal_port }}" + env: "{{ app_environment }}" + +- name: Wait for application port + ansible.builtin.wait_for: + host: "{{ app_healthcheck_host }}" + port: "{{ app_port | int }}" + timeout: 60 + delay: 1 + delegate_to: "{{ app_healthcheck_delegate_to }}" + become: false + +- name: Verify application health endpoint + ansible.builtin.uri: + url: "http://{{ app_healthcheck_host }}:{{ app_port }}{{ app_healthcheck_path }}" + method: GET + status_code: 200 + return_content: true + timeout: "{{ app_healthcheck_timeout | int }}" + register: app_healthcheck + retries: "{{ app_healthcheck_retries | int }}" + delay: "{{ app_healthcheck_delay | int }}" + until: app_healthcheck.status == 200 + failed_when: app_healthcheck.json.status | default("") != "healthy" + delegate_to: "{{ app_healthcheck_delegate_to }}" + become: false diff --git a/ansible/roles/common/defaults/common_defaults.yml b/ansible/roles/common/defaults/common_defaults.yml new file mode 100644 index 0000000000..65d0c186ad --- /dev/null +++ b/ansible/roles/common/defaults/common_defaults.yml @@ -0,0 +1,13 @@ +--- +common_packages: + - ca-certificates + - curl + - git + - htop + - vim + - python3-pip + - python3-apt + - tzdata + +common_manage_timezone: true +common_timezone: "Etc/UTC" diff --git a/ansible/roles/common/tasks/common_tasks.yml b/ansible/roles/common/tasks/common_tasks.yml new file mode 100644 index 0000000000..fbfff7a160 --- /dev/null +++ b/ansible/roles/common/tasks/common_tasks.yml @@ -0,0 +1,27 @@ +--- +- name: Update apt cache + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: Install common packages + ansible.builtin.apt: + name: "{{ common_packages }}" + state: present + +- name: Set /etc/timezone + ansible.builtin.copy: + dest: /etc/timezone + content: "{{ common_timezone }}\n" + owner: root + group: root + mode: "0644" + when: common_manage_timezone | bool + +- name: Point /etc/localtime to selected timezone + ansible.builtin.file: + src: "/usr/share/zoneinfo/{{ common_timezone }}" + dest: /etc/localtime + state: link + force: true + when: common_manage_timezone | bool diff --git a/ansible/roles/docker/defaults/docker_defaults.yml b/ansible/roles/docker/defaults/docker_defaults.yml new file mode 100644 index 0000000000..b6fee5c18c --- /dev/null +++ b/ansible/roles/docker/defaults/docker_defaults.yml @@ -0,0 +1,18 @@ +--- +docker_apt_arch_map: + x86_64: amd64 + aarch64: arm64 + armv7l: armhf + ppc64le: ppc64el + +docker_apt_arch: "{{ docker_apt_arch_map.get(ansible_facts['architecture'], ansible_facts['architecture']) }}" + +docker_packages: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + +docker_user: "{{ ansible_user | default('ubuntu') }}" +docker_install_python_sdk: true diff --git a/ansible/roles/docker/handlers/docker_handlers.yml b/ansible/roles/docker/handlers/docker_handlers.yml new file mode 100644 index 0000000000..1a5058da5e --- /dev/null +++ b/ansible/roles/docker/handlers/docker_handlers.yml @@ -0,0 +1,5 @@ +--- +- name: restart docker + ansible.builtin.service: + name: docker + state: restarted diff --git a/ansible/roles/docker/tasks/docker_tasks.yml b/ansible/roles/docker/tasks/docker_tasks.yml new file mode 100644 index 0000000000..e856b97cda --- /dev/null +++ b/ansible/roles/docker/tasks/docker_tasks.yml @@ -0,0 +1,56 @@ +--- +- name: Install Docker prerequisites + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - software-properties-common + state: present + update_cache: true + +- name: Ensure Docker keyring directory exists + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: "0755" + +- name: Add Docker GPG key + ansible.builtin.get_url: + url: https://download.docker.com/linux/ubuntu/gpg + dest: /etc/apt/keyrings/docker.asc + mode: "0644" + force: true + +- name: Add Docker apt repository + ansible.builtin.apt_repository: + repo: "deb [arch={{ docker_apt_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable" + filename: docker + state: present + update_cache: true + +- name: Install Docker engine packages + ansible.builtin.apt: + name: "{{ docker_packages }}" + state: present + notify: restart docker + +- name: Install Docker Python SDK package + ansible.builtin.apt: + name: python3-docker + state: present + when: docker_install_python_sdk | bool + +- name: Ensure Docker service is enabled and running + ansible.builtin.service: + name: docker + state: started + enabled: true + +- name: Add deployment user to docker group + ansible.builtin.user: + name: "{{ docker_user }}" + groups: docker + append: true + when: docker_user | length > 0 diff --git a/vagrant/.gitignore b/vagrant/.gitignore new file mode 100644 index 0000000000..09fd60c6cc --- /dev/null +++ b/vagrant/.gitignore @@ -0,0 +1,9 @@ + +# General +.vagrant/ + +# Log files (if you are creating logs in debug mode, uncomment this) +# *.log +shared/** +!shared/provision.sh +!shared/provision-post-kernel.sh diff --git a/vagrant/README.md b/vagrant/README.md new file mode 100644 index 0000000000..f7d3d056e3 --- /dev/null +++ b/vagrant/README.md @@ -0,0 +1,67 @@ +# Vagrant (libvirt) + +This VM is configured for the `libvirt` provider and uses: + +- Box: `alvistack/ubuntu-24.04` + +## Requirements + +- `vagrant` +- `libvirt` + `qemu`/`kvm` +- Vagrant plugin: `vagrant-libvirt` + +## Usage + +From repository root: + +```bash +cd vagrant +vagrant plugin install vagrant-libvirt +vagrant up +vagrant ssh +``` + +`vagrant up` automatically runs `shared/provision.sh` as root. +To re-run provisioning on an existing VM: + +```bash +vagrant provision +``` + +Provisioning is split into two stages: + +- `shared/provision.sh` (kernel/package update stage) +- automatic reboot between stages +- `shared/provision-post-kernel.sh` (post-kernel stage with ansible install) + +SSH key setup: + +- host private key path: `~/.ssh/vagrant` +- host public key path: `~/.ssh/vagrant.pub` +- public key is added to `/home/vagrant/.ssh/authorized_keys` during provisioning + +Static VM IP: + +- default: `192.168.121.50` +- override: `VM_IP=192.168.121.60 vagrant up` + +This setup uses: + +- management NIC (`eth0`, DHCP) for Vagrant internals +- static NIC (`eth1`, fixed IP above) for your direct SSH usage + +If the VM already existed before static IP was added, recreate it once: + +```bash +vagrant destroy -f +vagrant up --provider=libvirt +``` + +`~/.ssh/config` example: + +```sshconfig +Host vagrant + HostName 192.168.121.50 + User vagrant + IdentityFile ~/.ssh/vagrant +``` diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile new file mode 100644 index 0000000000..53e78574f2 --- /dev/null +++ b/vagrant/Vagrantfile @@ -0,0 +1,56 @@ +Vagrant.configure("2") do |config| + config.vm.box = "alvistack/ubuntu-24.04" + config.vm.box_check_update = false + config.vm.hostname = "devops-core-s26" + vm_ip = ENV.fetch("VM_IP", "192.168.121.50") + + host_ssh_key = File.expand_path("~/.ssh/vagrant") + host_ssh_pub = "#{host_ssh_key}.pub" + + # Prefer host key for SSH, but keep Vagrant's insecure key as a fallback. + config.ssh.insert_key = false + config.ssh.private_key_path = [ + host_ssh_key, + File.expand_path("~/.vagrant.d/insecure_private_key") + ] + + # Keep project root available in the guest for labs and tooling. + config.vm.synced_folder ".", "/vagrant", disabled: true + config.vm.synced_folder "./shared", "/shared" + config.vm.network "private_network", ip: vm_ip + + # Install host public key for `vagrant` user access. + if File.exist?(host_ssh_pub) + config.vm.provision "file", source: host_ssh_pub, destination: "/tmp/vagrant.pub" + config.vm.provision "shell", + name: "install-host-ssh-key", + inline: <<-SHELL + set -euo pipefail + if [ ! -f /tmp/vagrant.pub ]; then + echo "Skipping host SSH key install: /tmp/vagrant.pub not found." + exit 0 + fi + install -d -m 700 /home/vagrant/.ssh + touch /home/vagrant/.ssh/authorized_keys + pub_key="$(cat /tmp/vagrant.pub)" + grep -qxF "$pub_key" /home/vagrant/.ssh/authorized_keys || echo "$pub_key" >> /home/vagrant/.ssh/authorized_keys + chown -R vagrant:vagrant /home/vagrant/.ssh + chmod 700 /home/vagrant/.ssh + chmod 600 /home/vagrant/.ssh/authorized_keys + rm -f /tmp/vagrant.pub + SHELL + end + + # Stage 1: update/purge packages, including kernel changes. + config.vm.provision "shell", + name: "kernel-update", + path: "shared/provision.sh", + reboot: true + # Stage 2: post-reboot setup. + config.vm.provision "shell", name: "post-kernel", path: "shared/provision-post-kernel.sh" + + config.vm.provider :libvirt do |libvirt| + libvirt.cpus = ENV.fetch("VM_CPUS", "2").to_i + libvirt.memory = ENV.fetch("VM_MEMORY", "4096").to_i + end +end diff --git a/vagrant/shared/provision-post-kernel.sh b/vagrant/shared/provision-post-kernel.sh new file mode 100755 index 0000000000..e555d98cf2 --- /dev/null +++ b/vagrant/shared/provision-post-kernel.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +if [ "$(id -u)" -ne 0 ]; then + echo "Please run this script as root or using sudo!" + exit 13 +fi +apt-get autoremove -y --allow-change-held-packages +apt-get install -y ansible diff --git a/vagrant/shared/provision.sh b/vagrant/shared/provision.sh new file mode 100755 index 0000000000..7cab63fa18 --- /dev/null +++ b/vagrant/shared/provision.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +if [ $(id -u) -ne 0 ]; then + echo "Please run this script as root or using sudo!" + exit 13 +fi +rm /etc/apt/sources.list.d/cappelikan.sources /etc/apt/sources.list.d/home-alvistack.sources +apt-get update +apt-get purge -y --allow-change-held-packages ansible mainline sosreport +# upgrade kernel +apt-get autoremove -y --allow-change-held-packages +apt full-upgrade -y From 29d02fca228fd50c343e0f192109a8eb76bd7b86 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Thu, 5 Mar 2026 23:58:20 +0300 Subject: [PATCH 06/16] fix: app_python typo in Dockerfile --- ansible/.gitignore | 2 +- app_python/Dockerfile | 2 +- app_python/README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ansible/.gitignore b/ansible/.gitignore index bd991b335c..1a4929705e 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -1,3 +1,3 @@ *.retry .ansible/ -.vault_pass +.vault_pass \ No newline at end of file diff --git a/app_python/Dockerfile b/app_python/Dockerfile index e9b02ed024..f28f1d8a88 100644 --- a/app_python/Dockerfile +++ b/app_python/Dockerfile @@ -20,4 +20,4 @@ ENV PORT=5000 ENV HOST="0.0.0.0" USER appuser -CMD ["sh", "-c", "gunicorn --bind ${HOST:-0.0.0.0}:${PORT:-5000} src.flask_instance:app"] +CMD ["sh", "-c", "gunicorn --bind ${HOST:-0.0.0.0}:${PORT:-5000} src.main:app"] diff --git a/app_python/README.md b/app_python/README.md index 1979c45e82..ffbc05e2ba 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -37,9 +37,9 @@ poetry install Production-style local run with Gunicorn: ```bash -poetry run gunicorn --bind 0.0.0.0:5000 src.flask_instance:app +poetry run gunicorn --bind 0.0.0.0:5000 src.main:app # Or with custom config -HOST=127.0.0.1 PORT=8080 poetry run gunicorn --bind 127.0.0.1:8080 src.flask_instance:app +HOST=127.0.0.1 PORT=8080 poetry run gunicorn --bind 127.0.0.1:8080 src.main:app ``` ### Docker From d1b1b0c2b2b9fc10cb05ee8a76620a2b92e2316d Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 00:15:22 +0300 Subject: [PATCH 07/16] fix: remove the temp. fix from `ansible/` --- ansible/roles/app_deploy/defaults/app_deploy_defaults.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml index b98b9d0b27..b19a0a9d74 100644 --- a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml +++ b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml @@ -11,7 +11,6 @@ app_restart_policy: unless-stopped app_environment: HOST: "0.0.0.0" PORT: "{{ app_container_internal_port | string }}" -app_container_command: "gunicorn --bind 0.0.0.0:{{ app_container_internal_port }} src.main:app" app_healthcheck_path: /health app_healthcheck_retries: 20 From 8cf14ce6ed743d5d4a1484b48a2dcffd4c37d46c Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 04:56:15 +0300 Subject: [PATCH 08/16] ansible-lint config + tags --- .gitignore | 3 + ansible/.ansible-lint | 14 ++ ansible/.gitignore | 3 +- ansible/.yamllint.yml | 40 ++++ ansible/playbooks/provision.yml | 14 ++ ansible/playbooks/site.yml | 42 +++- ansible/requirements-lint.txt | 1 + .../defaults/app_deploy_defaults.yml | 39 ++-- .../handlers/app_deploy_handlers.yml | 4 +- .../app_deploy/tasks/app_deploy_tasks.yml | 77 ++++--- .../roles/common/defaults/common_defaults.yml | 6 + ansible/roles/common/tasks/common_tasks.yml | 78 ++++++- .../roles/docker/defaults/docker_defaults.yml | 1 + .../roles/docker/handlers/docker_handlers.yml | 2 +- ansible/roles/docker/tasks/docker_tasks.yml | 193 +++++++++++++----- 15 files changed, 390 insertions(+), 127 deletions(-) create mode 100644 ansible/.ansible-lint create mode 100644 ansible/.yamllint.yml create mode 100644 ansible/requirements-lint.txt diff --git a/.gitignore b/.gitignore index 67e6b52b28..6d94dd134e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ __pycache__/ # IDE .vscode/ + +# Ansible runtime/cache +.ansible/ diff --git a/ansible/.ansible-lint b/ansible/.ansible-lint new file mode 100644 index 0000000000..3a55c5e845 --- /dev/null +++ b/ansible/.ansible-lint @@ -0,0 +1,14 @@ +--- +profile: production +strict: true +use_default_rules: true +exclude_paths: + - .venv/ + - .ansible/ + - group_vars/all.yml + - docs/LAB05.md +enable_list: + - args + - empty-string-compare + - no-log-password + - no-prompting diff --git a/ansible/.gitignore b/ansible/.gitignore index 1a4929705e..5985dd6f4a 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -1,3 +1,4 @@ *.retry .ansible/ -.vault_pass \ No newline at end of file +.venv/ +.vault_pass diff --git a/ansible/.yamllint.yml b/ansible/.yamllint.yml new file mode 100644 index 0000000000..37734595da --- /dev/null +++ b/ansible/.yamllint.yml @@ -0,0 +1,40 @@ +--- +extends: default + +ignore: | + .venv/ + .ansible/ + group_vars/all.yml + docs/LAB05.md + +rules: + braces: + max-spaces-inside: 1 + comments: + min-spaces-from-content: 1 + comments-indentation: false + document-start: + present: true + empty-lines: + max: 1 + max-start: 0 + max-end: 0 + hyphens: + max-spaces-after: 1 + indentation: + spaces: 2 + indent-sequences: true + check-multi-line-strings: true + line-length: + max: 160 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: false + new-lines: + type: unix + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + trailing-spaces: enable + truthy: + allowed-values: ["true", "false"] + check-keys: true diff --git a/ansible/playbooks/provision.yml b/ansible/playbooks/provision.yml index 77ccedc3a1..4ba63ab0c0 100644 --- a/ansible/playbooks/provision.yml +++ b/ansible/playbooks/provision.yml @@ -9,6 +9,13 @@ name: common tasks_from: common_tasks defaults_from: common_defaults + apply: + tags: + - common + tags: + - common + - packages + - users - name: Run docker role tasks/defaults/handlers ansible.builtin.include_role: @@ -16,3 +23,10 @@ tasks_from: docker_tasks defaults_from: docker_defaults handlers_from: docker_handlers + apply: + tags: + - docker + tags: + - docker + - docker_install + - docker_config diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml index 139c08f693..29ea55585d 100644 --- a/ansible/playbooks/site.yml +++ b/ansible/playbooks/site.yml @@ -1,3 +1,41 @@ --- -- import_playbook: provision.yml -- import_playbook: deploy.yml +- name: Provision and deploy application + hosts: webservers + become: true + vars_files: + - ../group_vars/all.yml + + tasks: + - name: Run common role tasks/defaults + ansible.builtin.include_role: + name: common + tasks_from: common_tasks + defaults_from: common_defaults + apply: + tags: + - common + tags: + - common + - packages + - users + + - name: Run docker role tasks/defaults/handlers + ansible.builtin.include_role: + name: docker + tasks_from: docker_tasks + defaults_from: docker_defaults + handlers_from: docker_handlers + apply: + tags: + - docker + tags: + - docker + - docker_install + - docker_config + + - name: Run app deploy role tasks/defaults/handlers + ansible.builtin.include_role: + name: app_deploy + tasks_from: app_deploy_tasks + defaults_from: app_deploy_defaults + handlers_from: app_deploy_handlers diff --git a/ansible/requirements-lint.txt b/ansible/requirements-lint.txt new file mode 100644 index 0000000000..3a71006dca --- /dev/null +++ b/ansible/requirements-lint.txt @@ -0,0 +1 @@ +ansible-lint==26.3.0 diff --git a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml index b19a0a9d74..57afee1f0d 100644 --- a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml +++ b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml @@ -1,21 +1,26 @@ --- -app_name: devops-app-py -docker_image: "{{ dockerhub_username }}/{{ app_name }}" -docker_image_tag: latest +app_deploy_dockerhub_username: "{{ dockerhub_username | default('') }}" +app_deploy_dockerhub_password: "{{ dockerhub_password | default(docker_api_token | default('')) }}" -app_port: 5000 -app_container_name: devops-app -app_container_internal_port: 5000 -app_restart_policy: unless-stopped +app_deploy_name: "{{ app_name | default('devops-app-py') }}" +app_deploy_docker_image: >- + {{ docker_image | default((app_deploy_dockerhub_username ~ '/' ~ app_deploy_name) + if app_deploy_dockerhub_username | length > 0 else app_deploy_name) }} +app_deploy_docker_image_tag: "{{ docker_image_tag | default('latest') }}" -app_environment: - HOST: "0.0.0.0" - PORT: "{{ app_container_internal_port | string }}" +app_deploy_port: "{{ app_port | default(5000) }}" +app_deploy_container_name: "{{ app_container_name | default('devops-app') }}" +app_deploy_container_internal_port: "{{ app_container_internal_port | default(5000) }}" +app_deploy_restart_policy: "{{ app_restart_policy | default('unless-stopped') }}" -app_healthcheck_path: /health -app_healthcheck_retries: 20 -app_healthcheck_delay: 3 -app_healthcheck_timeout: 3 -app_recreate_on_pull: true -app_healthcheck_host: "{{ ansible_host | default(inventory_hostname) }}" -app_healthcheck_delegate_to: localhost +app_deploy_environment: >- + {{ app_environment | default({'HOST': '0.0.0.0', + 'PORT': (app_deploy_container_internal_port | string)}) }} + +app_deploy_healthcheck_path: "{{ app_healthcheck_path | default('/health') }}" +app_deploy_healthcheck_retries: "{{ app_healthcheck_retries | default(20) }}" +app_deploy_healthcheck_delay: "{{ app_healthcheck_delay | default(3) }}" +app_deploy_healthcheck_timeout: "{{ app_healthcheck_timeout | default(3) }}" +app_deploy_recreate_on_pull: "{{ app_recreate_on_pull | default(true) }}" +app_deploy_healthcheck_host: "{{ app_healthcheck_host | default(ansible_host | default(inventory_hostname)) }}" +app_deploy_healthcheck_delegate_to: "{{ app_healthcheck_delegate_to | default('localhost') }}" diff --git a/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml b/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml index 1fc3fba48b..3e2a7d6741 100644 --- a/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml +++ b/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml @@ -1,6 +1,6 @@ --- -- name: restart app container +- name: Restart App Container community.docker.docker_container: - name: "{{ app_container_name }}" + name: "{{ app_deploy_container_name }}" state: started restart: true diff --git a/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml b/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml index 4bab455012..96f90e5ef7 100644 --- a/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml +++ b/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml @@ -1,15 +1,9 @@ --- -- name: Resolve Docker Hub auth secret - ansible.builtin.set_fact: - dockerhub_auth_secret: "{{ dockerhub_password | default(docker_api_token | default('')) }}" - no_log: true - - name: Validate required Docker Hub credentials ansible.builtin.assert: that: - - dockerhub_username is defined - - dockerhub_username | string | length > 0 - - dockerhub_auth_secret | string | length > 0 + - app_deploy_dockerhub_username | string | length > 0 + - app_deploy_dockerhub_password | string | length > 0 fail_msg: >- Missing Docker Hub credentials. Define dockerhub_username and one of: dockerhub_password or docker_api_token in ansible/group_vars/all.yml (vaulted). @@ -17,72 +11,73 @@ - name: Log in to Docker Hub community.docker.docker_login: registry_url: https://index.docker.io/v1/ - username: "{{ dockerhub_username }}" - password: "{{ dockerhub_auth_secret }}" + username: "{{ app_deploy_dockerhub_username }}" + password: "{{ app_deploy_dockerhub_password }}" no_log: true - name: Pull application image community.docker.docker_image: - name: "{{ docker_image }}:{{ docker_image_tag }}" + name: "{{ app_deploy_docker_image }}:{{ app_deploy_docker_image_tag }}" source: pull - register: app_image_pull - notify: restart app container + register: app_deploy_image_pull + notify: Restart App Container - name: Check whether application container already exists community.docker.docker_container_info: - name: "{{ app_container_name }}" - register: app_container_info + name: "{{ app_deploy_container_name }}" + register: app_deploy_container_info - name: Stop existing container before replacement community.docker.docker_container: - name: "{{ app_container_name }}" + name: "{{ app_deploy_container_name }}" state: stopped when: - - app_container_info.exists | bool - - app_recreate_on_pull | bool - - app_image_pull.changed - - app_container_info.container is defined and app_container_info.container.State.Running | default(false) + - app_deploy_container_info.exists | bool + - app_deploy_recreate_on_pull | bool + - app_deploy_image_pull.changed + - app_deploy_container_info.container is defined + - app_deploy_container_info.container.State.Running | default(false) - name: Remove old container before replacement community.docker.docker_container: - name: "{{ app_container_name }}" + name: "{{ app_deploy_container_name }}" state: absent when: - - app_container_info.exists | bool - - app_recreate_on_pull | bool - - app_image_pull.changed + - app_deploy_container_info.exists | bool + - app_deploy_recreate_on_pull | bool + - app_deploy_image_pull.changed - name: Run application container community.docker.docker_container: - name: "{{ app_container_name }}" - image: "{{ docker_image }}:{{ docker_image_tag }}" - command: "{{ app_container_command | default(omit) }}" + name: "{{ app_deploy_container_name }}" + image: "{{ app_deploy_docker_image }}:{{ app_deploy_docker_image_tag }}" + command: "{{ app_deploy_container_command | default(omit) }}" state: started - restart_policy: "{{ app_restart_policy }}" + restart_policy: "{{ app_deploy_restart_policy }}" ports: - - "{{ app_port }}:{{ app_container_internal_port }}" - env: "{{ app_environment }}" + - "{{ app_deploy_port }}:{{ app_deploy_container_internal_port }}" + env: "{{ app_deploy_environment }}" - name: Wait for application port ansible.builtin.wait_for: - host: "{{ app_healthcheck_host }}" - port: "{{ app_port | int }}" + host: "{{ app_deploy_healthcheck_host }}" + port: "{{ app_deploy_port | int }}" timeout: 60 delay: 1 - delegate_to: "{{ app_healthcheck_delegate_to }}" + delegate_to: "{{ app_deploy_healthcheck_delegate_to }}" become: false - name: Verify application health endpoint ansible.builtin.uri: - url: "http://{{ app_healthcheck_host }}:{{ app_port }}{{ app_healthcheck_path }}" + url: "http://{{ app_deploy_healthcheck_host }}:{{ app_deploy_port }}{{ app_deploy_healthcheck_path }}" method: GET status_code: 200 return_content: true - timeout: "{{ app_healthcheck_timeout | int }}" - register: app_healthcheck - retries: "{{ app_healthcheck_retries | int }}" - delay: "{{ app_healthcheck_delay | int }}" - until: app_healthcheck.status == 200 - failed_when: app_healthcheck.json.status | default("") != "healthy" - delegate_to: "{{ app_healthcheck_delegate_to }}" + timeout: "{{ app_deploy_healthcheck_timeout | int }}" + register: app_deploy_healthcheck + retries: "{{ app_deploy_healthcheck_retries | int }}" + delay: "{{ app_deploy_healthcheck_delay | int }}" + until: app_deploy_healthcheck.status == 200 + failed_when: app_deploy_healthcheck.json.status | default("") != "healthy" + delegate_to: "{{ app_deploy_healthcheck_delegate_to }}" become: false diff --git a/ansible/roles/common/defaults/common_defaults.yml b/ansible/roles/common/defaults/common_defaults.yml index 65d0c186ad..c9f6d61424 100644 --- a/ansible/roles/common/defaults/common_defaults.yml +++ b/ansible/roles/common/defaults/common_defaults.yml @@ -11,3 +11,9 @@ common_packages: common_manage_timezone: true common_timezone: "Etc/UTC" +common_completion_log_path: "/tmp/ansible-common-role.log" + +common_managed_users: + - name: "{{ ansible_user | default('ubuntu') }}" + shell: "/bin/bash" + create_home: true diff --git a/ansible/roles/common/tasks/common_tasks.yml b/ansible/roles/common/tasks/common_tasks.yml index fbfff7a160..a0a740aa0b 100644 --- a/ansible/roles/common/tasks/common_tasks.yml +++ b/ansible/roles/common/tasks/common_tasks.yml @@ -1,13 +1,51 @@ --- -- name: Update apt cache - ansible.builtin.apt: - update_cache: true - cache_valid_time: 3600 +- name: Manage common packages + become: true + tags: + - packages + block: + - name: Update apt cache + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 -- name: Install common packages - ansible.builtin.apt: - name: "{{ common_packages }}" - state: present + - name: Install common packages + ansible.builtin.apt: + name: "{{ common_packages }}" + state: present + + rescue: + - name: Mark common package rescue as triggered + ansible.builtin.set_fact: + common_packages_rescue_triggered: true + + - name: Refresh apt cache with fix-missing + ansible.builtin.command: + argv: + - apt-get + - update + - --fix-missing + changed_when: false + + - name: Retry apt cache update + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + + - name: Retry common package installation + ansible.builtin.apt: + name: "{{ common_packages }}" + state: present + + always: + - name: Record common packages block completion + ansible.builtin.lineinfile: + path: "{{ common_completion_log_path }}" + line: >- + packages block completed + (rescue_triggered={{ common_packages_rescue_triggered | default(false) }}) + create: true + mode: "0644" - name: Set /etc/timezone ansible.builtin.copy: @@ -25,3 +63,27 @@ state: link force: true when: common_manage_timezone | bool + +- name: Manage common users + become: true + tags: + - users + block: + - name: Ensure managed users exist + ansible.builtin.user: + name: "{{ item.name }}" + state: "{{ item.state | default('present') }}" + shell: "{{ item.shell | default('/bin/bash') }}" + create_home: "{{ item.create_home | default(true) }}" + loop: "{{ common_managed_users }}" + loop_control: + label: "{{ item.name }}" + when: common_managed_users | length > 0 + + always: + - name: Record common users block completion + ansible.builtin.lineinfile: + path: "{{ common_completion_log_path }}" + line: users block completed + create: true + mode: "0644" diff --git a/ansible/roles/docker/defaults/docker_defaults.yml b/ansible/roles/docker/defaults/docker_defaults.yml index b6fee5c18c..ebc8ad6ac0 100644 --- a/ansible/roles/docker/defaults/docker_defaults.yml +++ b/ansible/roles/docker/defaults/docker_defaults.yml @@ -16,3 +16,4 @@ docker_packages: docker_user: "{{ ansible_user | default('ubuntu') }}" docker_install_python_sdk: true +docker_completion_log_path: "/tmp/ansible-docker-role.log" diff --git a/ansible/roles/docker/handlers/docker_handlers.yml b/ansible/roles/docker/handlers/docker_handlers.yml index 1a5058da5e..0162ba52da 100644 --- a/ansible/roles/docker/handlers/docker_handlers.yml +++ b/ansible/roles/docker/handlers/docker_handlers.yml @@ -1,5 +1,5 @@ --- -- name: restart docker +- name: Restart Docker ansible.builtin.service: name: docker state: restarted diff --git a/ansible/roles/docker/tasks/docker_tasks.yml b/ansible/roles/docker/tasks/docker_tasks.yml index e856b97cda..b9fa4f7013 100644 --- a/ansible/roles/docker/tasks/docker_tasks.yml +++ b/ansible/roles/docker/tasks/docker_tasks.yml @@ -1,56 +1,139 @@ --- -- name: Install Docker prerequisites - ansible.builtin.apt: - name: - - apt-transport-https - - ca-certificates - - curl - - gnupg - - software-properties-common - state: present - update_cache: true - -- name: Ensure Docker keyring directory exists - ansible.builtin.file: - path: /etc/apt/keyrings - state: directory - mode: "0755" - -- name: Add Docker GPG key - ansible.builtin.get_url: - url: https://download.docker.com/linux/ubuntu/gpg - dest: /etc/apt/keyrings/docker.asc - mode: "0644" - force: true - -- name: Add Docker apt repository - ansible.builtin.apt_repository: - repo: "deb [arch={{ docker_apt_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable" - filename: docker - state: present - update_cache: true - -- name: Install Docker engine packages - ansible.builtin.apt: - name: "{{ docker_packages }}" - state: present - notify: restart docker - -- name: Install Docker Python SDK package - ansible.builtin.apt: - name: python3-docker - state: present - when: docker_install_python_sdk | bool - -- name: Ensure Docker service is enabled and running - ansible.builtin.service: - name: docker - state: started - enabled: true - -- name: Add deployment user to docker group - ansible.builtin.user: - name: "{{ docker_user }}" - groups: docker - append: true - when: docker_user | length > 0 +- name: Manage Docker installation + become: true + tags: + - docker_install + block: + - name: Install Docker prerequisites + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - software-properties-common + state: present + update_cache: true + + - name: Ensure Docker keyring directory exists + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: "0755" + + - name: Add Docker GPG key + ansible.builtin.get_url: + url: https://download.docker.com/linux/ubuntu/gpg + dest: /etc/apt/keyrings/docker.asc + mode: "0644" + force: true + + - name: Add Docker apt repository + ansible.builtin.apt_repository: + repo: >- + deb [arch={{ docker_apt_arch }} signed-by=/etc/apt/keyrings/docker.asc] + https://download.docker.com/linux/ubuntu + {{ ansible_facts['distribution_release'] }} stable + filename: docker + state: present + update_cache: true + + - name: Install Docker engine packages + ansible.builtin.apt: + name: "{{ docker_packages }}" + state: present + notify: Restart Docker + + - name: Install Docker Python SDK package + ansible.builtin.apt: + name: python3-docker + state: present + when: docker_install_python_sdk | bool + + - name: Mark Docker service as ready + ansible.builtin.set_fact: + docker_service_ready: true + + rescue: + - name: Mark Docker install rescue as triggered + ansible.builtin.set_fact: + docker_install_rescue_triggered: true + + - name: Wait before retrying Docker apt setup + ansible.builtin.pause: + seconds: 10 + + - name: Refresh apt cache before Docker retry + ansible.builtin.apt: + update_cache: true + cache_valid_time: 0 + + - name: Retry adding Docker GPG key + ansible.builtin.get_url: + url: https://download.docker.com/linux/ubuntu/gpg + dest: /etc/apt/keyrings/docker.asc + mode: "0644" + force: true + + - name: Retry adding Docker apt repository + ansible.builtin.apt_repository: + repo: >- + deb [arch={{ docker_apt_arch }} signed-by=/etc/apt/keyrings/docker.asc] + https://download.docker.com/linux/ubuntu + {{ ansible_facts['distribution_release'] }} stable + filename: docker + state: present + update_cache: true + + - name: Retry installing Docker engine packages + ansible.builtin.apt: + name: "{{ docker_packages }}" + state: present + notify: Restart Docker + + - name: Retry installing Docker Python SDK package + ansible.builtin.apt: + name: python3-docker + state: present + when: docker_install_python_sdk | bool + + - name: Mark Docker service as ready after retry + ansible.builtin.set_fact: + docker_service_ready: true + + always: + - name: Ensure Docker service is enabled and running + ansible.builtin.service: + name: docker + state: started + enabled: true + when: docker_service_ready | default(false) + + - name: Record Docker installation block completion + ansible.builtin.lineinfile: + path: "{{ docker_completion_log_path }}" + line: >- + docker installation block completed + (rescue_triggered={{ docker_install_rescue_triggered | default(false) }}) + create: true + mode: "0644" + +- name: Manage Docker configuration + become: true + tags: + - docker_config + block: + - name: Add deployment user to docker group + ansible.builtin.user: + name: "{{ docker_user }}" + groups: docker + append: true + when: docker_user | length > 0 + + always: + - name: Record Docker configuration block completion + ansible.builtin.lineinfile: + path: "{{ docker_completion_log_path }}" + line: docker configuration block completed + create: true + mode: "0644" From 4ba77c1253127a691d988b5f3094559823c78c99 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 06:20:19 +0300 Subject: [PATCH 09/16] feat: tags + compose --- ansible/docs/LAB06.md | 639 ++++++++++++++++++ ansible/playbooks/deploy.yml | 16 +- ansible/playbooks/provision.yml | 2 - ansible/playbooks/site.yml | 24 +- .../defaults/app_deploy_defaults.yml | 26 - .../handlers/app_deploy_handlers.yml | 6 - .../app_deploy/tasks/app_deploy_tasks.yml | 83 --- .../{docker_handlers.yml => main.yml} | 0 .../tasks/{docker_tasks.yml => main.yml} | 6 + .../web_app/defaults/web_app_defaults.yml | 37 + ansible/roles/web_app/meta/main.yml | 10 + ansible/roles/web_app/tasks/web_app_tasks.yml | 107 +++ .../web_app/templates/docker-compose.yml.j2 | 21 + 13 files changed, 839 insertions(+), 138 deletions(-) create mode 100644 ansible/docs/LAB06.md delete mode 100644 ansible/roles/app_deploy/defaults/app_deploy_defaults.yml delete mode 100644 ansible/roles/app_deploy/handlers/app_deploy_handlers.yml delete mode 100644 ansible/roles/app_deploy/tasks/app_deploy_tasks.yml rename ansible/roles/docker/handlers/{docker_handlers.yml => main.yml} (100%) rename ansible/roles/docker/tasks/{docker_tasks.yml => main.yml} (96%) create mode 100644 ansible/roles/web_app/defaults/web_app_defaults.yml create mode 100644 ansible/roles/web_app/meta/main.yml create mode 100644 ansible/roles/web_app/tasks/web_app_tasks.yml create mode 100644 ansible/roles/web_app/templates/docker-compose.yml.j2 diff --git a/ansible/docs/LAB06.md b/ansible/docs/LAB06.md new file mode 100644 index 0000000000..0090aceb39 --- /dev/null +++ b/ansible/docs/LAB06.md @@ -0,0 +1,639 @@ +# LAB06 - Advanced Ansible & CI/CD + +## Task 1: Blocks & Tags (2 pts) + +### Overview + +For Task 1 I refactored the existing Ansible roles to use blocks, rescue handling, and tags without changing the repository's custom file naming convention. The lab sheet mentions `main.yml`, but this repository already uses descriptive files such as `common_tasks.yml` and `docker_tasks.yml`, so I kept that structure. + +### Implementation Details + +#### `common` role + +Changes made: + +- Grouped APT cache refresh and package installation into a `block` tagged `packages`. +- Added a `rescue` path that runs `apt-get update --fix-missing`, then retries the cache refresh and package installation. +- Added an `always` section that records block completion in `/tmp/ansible-common-role.log`. +- Added a separate `users` block that ensures managed users exist and also records completion. +- Kept timezone management outside the package block so `--tags packages` only runs package-related work. + +Practical result: + +- `--tags packages` runs only the package block. +- `--skip-tags common` skips the whole role because the playbook applies the `common` tag at role level. + +#### `docker` role + +Changes made: + +- Grouped Docker installation tasks into a `block` tagged `docker_install`. +- Added a `rescue` path that waits 10 seconds, refreshes APT metadata, and retries the Docker repository/key/package setup. +- Added an `always` section that ensures the Docker service is enabled and running after a successful install path. +- Grouped Docker configuration into a separate `block` tagged `docker_config`. +- Added completion logging to `/tmp/ansible-docker-role.log`. + +Practical result: + +- `--tags docker` runs the whole Docker role. +- `--tags docker_install` runs only installation-related work. +- Rescue behavior is visible in the collected logs. + +#### Playbook tag strategy + +Role-level tags are applied in the playbooks so the role can be selected as a whole, while block tags allow narrower execution. + +| Tag | Purpose | +| ---------------- | ---------------------------------------- | +| `common` | Entire common role | +| `packages` | Package install/update block in `common` | +| `users` | User-management block in `common` | +| `docker` | Entire docker role | +| `docker_install` | Docker installation and repository setup | +| `docker_config` | Docker host configuration | + +### Evidence + +The main evidence file is `task1.log`. + +#### 1. Selective execution with `--tags "docker"` + +This run exercised only the Docker role and also proved that the `rescue` section works: + +
+ansible-playbook playbooks/provision.yml --tags "docker" + +```text +$ ansible-playbook playbooks/provision.yml --tags "docker" + +PLAY [Provision web servers] **************************************************************************************************** + +TASK [Gathering Facts] ********************************************************************************************************** +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ********************************************************************************** +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] ************************************************************************************ +[WARNING]: Failed to update cache after 1 retries due to , retrying +[WARNING]: Sleeping for 2 seconds, before attempting to refresh the cache again +[WARNING]: Failed to update cache after 2 retries due to , retrying +[WARNING]: Sleeping for 3 seconds, before attempting to refresh the cache again +[WARNING]: Failed to update cache after 3 retries due to , retrying +[WARNING]: Sleeping for 5 seconds, before attempting to refresh the cache again +[WARNING]: Failed to update cache after 4 retries due to , retrying +[WARNING]: Sleeping for 9 seconds, before attempting to refresh the cache again +[WARNING]: Failed to update cache after 5 retries due to , retrying +[WARNING]: Sleeping for 13 seconds, before attempting to refresh the cache again +[ERROR]: Task failed: Module failed: Failed to update apt cache after 5 retries: +Origin: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/docker/tasks/docker_tasks.yml:7:7 + +5 - docker_install +6 block: +7 - name: Install Docker prerequisites + ^ column 7 + +fatal: [vagrant]: FAILED! => {"changed": false, "msg": "Failed to update apt cache after 5 retries: "} + +TASK [docker : Mark Docker install rescue as triggered] ************************************************************************* +ok: [vagrant] + +TASK [docker : Wait before retrying Docker apt setup] *************************************************************************** +Pausing for 10 seconds +(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort) +ok: [vagrant] + +TASK [docker : Refresh apt cache before Docker retry] *************************************************************************** +changed: [vagrant] + +TASK [docker : Retry adding Docker GPG key] ************************************************************************************* +ok: [vagrant] + +TASK [docker : Retry adding Docker apt repository] ****************************************************************************** +ok: [vagrant] + +TASK [docker : Retry installing Docker engine packages] ************************************************************************* +ok: [vagrant] + +TASK [docker : Retry installing Docker Python SDK package] ********************************************************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready after retry] ************************************************************************ +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ********************************************************************* +changed: [vagrant] + +TASK [docker : Add deployment user to docker group] ***************************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************************************************************** +ok: [vagrant] + +PLAY RECAP ********************************************************************************************************************** +vagrant : ok=14 changed=2 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0 + +``` + +
+ +This is the strongest proof for Task 1 because it shows: + +- only the Docker role was selected, +- the block failed, +- the `rescue` path recovered successfully, +- the play still finished with `failed=0` and `rescued=1`. + +#### 2. Skipping the `common` role + +
+ansible-playbook playbooks/provision.yml --skip-tags "common" + +```text +$ ansible-playbook playbooks/provision.yml --skip-tags "common" +PLAY [Provision web servers] *************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ********************************* +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************* +ok: [vagrant] + +TASK [docker : Add Docker apt repository] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************* +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ****************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************* +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ******************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] **************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************* +ok: [vagrant] + +PLAY RECAP ********************************************************************* +vagrant : ok=13 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +``` + +
+ +No `common` tasks ran, which confirms the role-level `common` tag is working. + +#### 3. Running package tasks only + +
+ansible-playbook playbooks/provision.yml --tags "packages" + +```text +$ ansible-playbook playbooks/provision.yml --tags "packages" +PLAY [Provision web servers] *************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run common role tasks/defaults] ****************************************** +included: common for vagrant + +TASK [common : Update apt cache] *********************************************** +ok: [vagrant] + +TASK [common : Install common packages] **************************************** +ok: [vagrant] + +TASK [common : Record common packages block completion] ************************ +ok: [vagrant] + +PLAY RECAP ********************************************************************* +vagrant : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +``` + +
+ +This shows the `packages` tag is narrow enough to avoid unrelated common-role tasks. + +#### 4. Check mode for Docker tasks + +
+ansible-playbook playbooks/provision.yml --tags "docker" --check + +```text +$ ansible-playbook playbooks/provision.yml --tags "docker" --check +PLAY [Provision web servers] *************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ********************************* +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************* +changed: [vagrant] + +TASK [docker : Add Docker apt repository] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************* +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ****************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************* +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ******************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] **************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************* +ok: [vagrant] + +PLAY RECAP ********************************************************************* +vagrant : ok=13 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +``` + +
+ +Check mode completed without errors. One task reported `changed`, which is not surprising for repository/key download style tasks; check mode is useful, but not perfect, for external-resource operations. + +#### 5. Running only Docker installation tasks + +
+ansible-playbook playbooks/provision.yml --tags "docker_install" + +```text +$ ansible-playbook playbooks/provision.yml --tags "docker_install" +PLAY [Provision web servers] *************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run docker role tasks/defaults/handlers] ********************************* +included: docker for vagrant + +TASK [docker : Install Docker prerequisites] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************* +ok: [vagrant] + +TASK [docker : Add Docker apt repository] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************* +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ****************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************* +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ******************** +ok: [vagrant] + +PLAY RECAP ********************************************************************* +vagrant : ok=11 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +``` + +
+ +This confirms that installation tasks can be isolated from broader Docker role execution. + +#### 6. Available tags + +Verified with: + +
+ansible-playbook playbooks/provision.yml --list-tags + +```text +$ ansible-playbook playbooks/provision.yml --list-tags + + +playbook: playbooks/provision.yml + + play #1 (webservers): Provision web servers TAGS: [] + TASK TAGS: [common, docker, docker_config, docker_install, packages, users] + +``` + +
+ +### Analysis + +Blocks improved the structure of both roles because related tasks are now grouped around a single intent instead of being scattered as flat tasks. In practice, this made the Docker install flow easier to reason about: install steps are in one place, recovery steps are in one place, and service enforcement is in one place. + +The rescue behavior in the Docker role is especially useful. The first `--tags "docker"` run showed a real transient APT/cache failure, and the play recovered automatically. That is more convincing than a purely theoretical discussion because the log captured an actual `rescued=1` run. + +The tag layout is also practical rather than decorative: + +- broad tags (`common`, `docker`) support role-level execution, +- narrow tags (`packages`, `users`, `docker_install`, `docker_config`) support targeted runs, +- the tag names are predictable and easy to remember during troubleshooting. + +### Research Answers + +1. **What happens if the rescue block also fails?** + - If a task inside `rescue` fails, the block is no longer recovered and the host stays failed for that task sequence. The `always` section still runs, but the play reports a failure unless some higher-level error handling changes that behavior. + +2. **Can you have nested blocks?** + - Yes. Ansible allows nested blocks. That said, I would use them carefully because deep nesting becomes hard to read quickly. + +3. **How do tags inherit to tasks within blocks?** + - Tags applied to a block are inherited by the tasks inside that block, including `rescue` and `always` tasks associated with the block. In this lab, role-level tags are applied from the playbook, while narrower tags are applied directly on the role blocks. + +--- + +## Task 2: Docker Compose + +### Implementation Summary + +- Renamed the deployment role from `app_deploy` to `web_app`. +- Kept descriptive role filenames for the web app implementation in `ansible/roles/web_app/tasks/web_app_tasks.yml` and `ansible/roles/web_app/defaults/web_app_defaults.yml`. +- Inlined the Docker role logic into `ansible/roles/docker/tasks/main.yml` and `ansible/roles/docker/handlers/main.yml`, leaving only the Ansible-required entrypoints as `main.yml`. +- Replaced the old single-container deployment logic with a Compose-based deployment in `ansible/roles/web_app/tasks/web_app_tasks.yml`. +- Added a Compose template in `ansible/roles/web_app/templates/docker-compose.yml.j2`. +- Added a role dependency in `ansible/roles/web_app/meta/main.yml` so `docker` is installed automatically before the app is deployed. +- Updated `ansible/playbooks/deploy.yml` and `ansible/playbooks/site.yml` to call `web_app`. + +### Compose Deployment Design + +The new role now: + +- optionally logs into Docker Hub when credentials are present, +- creates the project directory under `/opt/{{ app_name }}`, +- removes the legacy standalone container before migration to Compose, +- templates a `docker-compose.yml`, +- deploys the stack with `community.docker.docker_compose_v2`, +- waits for the application port and then verifies `/health`. + +### Practical Notes + +- I added retries around the Compose deployment step because the first live run hit a transient Docker Hub registry timeout. + +### Evidence + +The deployment now works end-to-end with Docker Compose: + +
+ansible-playbook playbooks/deploy.yml + +``` +$ ansible-playbook playbooks/deploy.yml + +PLAY [Deploy application] ******************************************************************************************************* + +TASK [Gathering Facts] ********************************************************************************************************** +ok: [vagrant] + +TASK [Run web app role] ********************************************************************************************************* +included: web_app for vagrant + +TASK [docker : Load docker role defaults] *************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker prerequisites] ************************************************************************************ +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************************************************************** +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************************************************************** +ok: [vagrant] + +TASK [docker : Add Docker apt repository] *************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ******************************************************************************* +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] ************************************************************************************ +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ********************************************************************* +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] ***************************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************************************************************** +ok: [vagrant] + +TASK [web_app : Log in to Docker Hub when credentials are available] ************************************************************ +ok: [vagrant] + +TASK [web_app : Ensure Compose project directory exists] ************************************************************************ +ok: [vagrant] + +TASK [web_app : Check for legacy standalone container] ************************************************************************** +ok: [vagrant] + +TASK [web_app : Remove legacy standalone container before Compose migration] **************************************************** +skipping: [vagrant] + +TASK [web_app : Template Docker Compose configuration] ************************************************************************** +ok: [vagrant] + +TASK [web_app : Deploy application stack with Docker Compose] ******************************************************************* +changed: [vagrant] + +TASK [web_app : Wait for application port] ************************************************************************************** +ok: [vagrant -> localhost] + +TASK [web_app : Verify application health endpoint] ***************************************************************************** +ok: [vagrant -> localhost] + +PLAY RECAP ********************************************************************************************************************** +vagrant : ok=21 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +``` + +
+ +The second deployment run proves idempotency for the Compose-based deployment: + +
+ansible-playbook playbooks/deploy.yml (second run) + +```text +$ ansible-playbook playbooks/deploy.yml + +PLAY [Deploy application] ******************************************************************************************************* + +TASK [Gathering Facts] ********************************************************************************************************** +ok: [vagrant] + +TASK [Run web app role] ********************************************************************************************************* +included: web_app for vagrant + +TASK [docker : Load docker role defaults] *************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker prerequisites] ************************************************************************************ +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************************************************************** +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************************************************************** +ok: [vagrant] + +TASK [docker : Add Docker apt repository] *************************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************************************************************** +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ******************************************************************************* +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] ************************************************************************************ +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ********************************************************************* +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] ***************************************************************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************************************************************** +ok: [vagrant] + +TASK [web_app : Log in to Docker Hub when credentials are available] ************************************************************ +ok: [vagrant] + +TASK [web_app : Ensure Compose project directory exists] ************************************************************************ +ok: [vagrant] + +TASK [web_app : Check for legacy standalone container] ************************************************************************** +ok: [vagrant] + +TASK [web_app : Remove legacy standalone container before Compose migration] **************************************************** +skipping: [vagrant] + +TASK [web_app : Template Docker Compose configuration] ************************************************************************** +ok: [vagrant] + +TASK [web_app : Deploy application stack with Docker Compose] ******************************************************************* +ok: [vagrant] + +TASK [web_app : Wait for application port] ************************************************************************************** +ok: [vagrant -> localhost] + +TASK [web_app : Verify application health endpoint] ***************************************************************************** +ok: [vagrant -> localhost] + +PLAY RECAP ********************************************************************************************************************** +vagrant : ok=21 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +``` + +
+ +Runtime verification on the VM confirms that the Compose stack is up and the application health endpoint is reachable: + +
+docker ps -a + +```text +vagrant@devops-core-s26:~$ docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +bc1ac63a19d3 localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" 13 seconds ago Up 12 seconds 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp devops-app +``` + +
+ +
+docker compose -f /opt/devops-app-py/docker-compose.yml ps + +```text +vagrant@devops-core-s26:~$ docker compose -f /opt/devops-app-py/docker-compose.yml ps +NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS +devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devops-app-py About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp +``` + +
+ +
+curl -fSsL 127.0.0.1:5000/health | jq + +```text +vagrant@devops-core-s26:~$ curl -fSsL 127.0.0.1:5000/health | jq +{ + "status": "healthy", + "timestamp": "2026-03-06T03:15:05.637621+00:00", + "uptime_seconds": 139 +} +``` + +
+ +### Validation Status + +- `ansible-playbook playbooks/deploy.yml --syntax-check` passes. +- `ansible-playbook playbooks/site.yml --syntax-check` passes. +- `ansible-lint` passes on the Task 2 files. +- A real deploy run succeeds with `failed=0` and `changed=1`, confirming that the Compose-based deployment works. +- A second deploy run returns `changed=0`, which demonstrates idempotency for the Compose workflow. +- The VM shows the expected running container, Compose project status, and a healthy `/health` response. + +## Task 3: Wipe Logic (pending) + +## Task 4: CI/CD (pending) + +## Task 5: Documentation + +This file is the lab documentation and will be extended as the remaining tasks are completed. diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml index 0710726c35..282103c6f2 100644 --- a/ansible/playbooks/deploy.yml +++ b/ansible/playbooks/deploy.yml @@ -6,9 +6,15 @@ - ../group_vars/all.yml tasks: - - name: Run app deploy role tasks/defaults/handlers + - name: Run web app role ansible.builtin.include_role: - name: app_deploy - tasks_from: app_deploy_tasks - defaults_from: app_deploy_defaults - handlers_from: app_deploy_handlers + name: web_app + tasks_from: web_app_tasks + defaults_from: web_app_defaults + apply: + tags: + - web_app + tags: + - web_app + - app_deploy + - compose diff --git a/ansible/playbooks/provision.yml b/ansible/playbooks/provision.yml index 4ba63ab0c0..cdb77ad22a 100644 --- a/ansible/playbooks/provision.yml +++ b/ansible/playbooks/provision.yml @@ -20,9 +20,7 @@ - name: Run docker role tasks/defaults/handlers ansible.builtin.include_role: name: docker - tasks_from: docker_tasks defaults_from: docker_defaults - handlers_from: docker_handlers apply: tags: - docker diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml index 29ea55585d..61e73bc983 100644 --- a/ansible/playbooks/site.yml +++ b/ansible/playbooks/site.yml @@ -19,23 +19,15 @@ - packages - users - - name: Run docker role tasks/defaults/handlers + - name: Run web app role ansible.builtin.include_role: - name: docker - tasks_from: docker_tasks - defaults_from: docker_defaults - handlers_from: docker_handlers + name: web_app + tasks_from: web_app_tasks + defaults_from: web_app_defaults apply: tags: - - docker + - web_app tags: - - docker - - docker_install - - docker_config - - - name: Run app deploy role tasks/defaults/handlers - ansible.builtin.include_role: - name: app_deploy - tasks_from: app_deploy_tasks - defaults_from: app_deploy_defaults - handlers_from: app_deploy_handlers + - web_app + - app_deploy + - compose diff --git a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml b/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml deleted file mode 100644 index 57afee1f0d..0000000000 --- a/ansible/roles/app_deploy/defaults/app_deploy_defaults.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -app_deploy_dockerhub_username: "{{ dockerhub_username | default('') }}" -app_deploy_dockerhub_password: "{{ dockerhub_password | default(docker_api_token | default('')) }}" - -app_deploy_name: "{{ app_name | default('devops-app-py') }}" -app_deploy_docker_image: >- - {{ docker_image | default((app_deploy_dockerhub_username ~ '/' ~ app_deploy_name) - if app_deploy_dockerhub_username | length > 0 else app_deploy_name) }} -app_deploy_docker_image_tag: "{{ docker_image_tag | default('latest') }}" - -app_deploy_port: "{{ app_port | default(5000) }}" -app_deploy_container_name: "{{ app_container_name | default('devops-app') }}" -app_deploy_container_internal_port: "{{ app_container_internal_port | default(5000) }}" -app_deploy_restart_policy: "{{ app_restart_policy | default('unless-stopped') }}" - -app_deploy_environment: >- - {{ app_environment | default({'HOST': '0.0.0.0', - 'PORT': (app_deploy_container_internal_port | string)}) }} - -app_deploy_healthcheck_path: "{{ app_healthcheck_path | default('/health') }}" -app_deploy_healthcheck_retries: "{{ app_healthcheck_retries | default(20) }}" -app_deploy_healthcheck_delay: "{{ app_healthcheck_delay | default(3) }}" -app_deploy_healthcheck_timeout: "{{ app_healthcheck_timeout | default(3) }}" -app_deploy_recreate_on_pull: "{{ app_recreate_on_pull | default(true) }}" -app_deploy_healthcheck_host: "{{ app_healthcheck_host | default(ansible_host | default(inventory_hostname)) }}" -app_deploy_healthcheck_delegate_to: "{{ app_healthcheck_delegate_to | default('localhost') }}" diff --git a/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml b/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml deleted file mode 100644 index 3e2a7d6741..0000000000 --- a/ansible/roles/app_deploy/handlers/app_deploy_handlers.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Restart App Container - community.docker.docker_container: - name: "{{ app_deploy_container_name }}" - state: started - restart: true diff --git a/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml b/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml deleted file mode 100644 index 96f90e5ef7..0000000000 --- a/ansible/roles/app_deploy/tasks/app_deploy_tasks.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -- name: Validate required Docker Hub credentials - ansible.builtin.assert: - that: - - app_deploy_dockerhub_username | string | length > 0 - - app_deploy_dockerhub_password | string | length > 0 - fail_msg: >- - Missing Docker Hub credentials. Define dockerhub_username and one of: - dockerhub_password or docker_api_token in ansible/group_vars/all.yml (vaulted). - -- name: Log in to Docker Hub - community.docker.docker_login: - registry_url: https://index.docker.io/v1/ - username: "{{ app_deploy_dockerhub_username }}" - password: "{{ app_deploy_dockerhub_password }}" - no_log: true - -- name: Pull application image - community.docker.docker_image: - name: "{{ app_deploy_docker_image }}:{{ app_deploy_docker_image_tag }}" - source: pull - register: app_deploy_image_pull - notify: Restart App Container - -- name: Check whether application container already exists - community.docker.docker_container_info: - name: "{{ app_deploy_container_name }}" - register: app_deploy_container_info - -- name: Stop existing container before replacement - community.docker.docker_container: - name: "{{ app_deploy_container_name }}" - state: stopped - when: - - app_deploy_container_info.exists | bool - - app_deploy_recreate_on_pull | bool - - app_deploy_image_pull.changed - - app_deploy_container_info.container is defined - - app_deploy_container_info.container.State.Running | default(false) - -- name: Remove old container before replacement - community.docker.docker_container: - name: "{{ app_deploy_container_name }}" - state: absent - when: - - app_deploy_container_info.exists | bool - - app_deploy_recreate_on_pull | bool - - app_deploy_image_pull.changed - -- name: Run application container - community.docker.docker_container: - name: "{{ app_deploy_container_name }}" - image: "{{ app_deploy_docker_image }}:{{ app_deploy_docker_image_tag }}" - command: "{{ app_deploy_container_command | default(omit) }}" - state: started - restart_policy: "{{ app_deploy_restart_policy }}" - ports: - - "{{ app_deploy_port }}:{{ app_deploy_container_internal_port }}" - env: "{{ app_deploy_environment }}" - -- name: Wait for application port - ansible.builtin.wait_for: - host: "{{ app_deploy_healthcheck_host }}" - port: "{{ app_deploy_port | int }}" - timeout: 60 - delay: 1 - delegate_to: "{{ app_deploy_healthcheck_delegate_to }}" - become: false - -- name: Verify application health endpoint - ansible.builtin.uri: - url: "http://{{ app_deploy_healthcheck_host }}:{{ app_deploy_port }}{{ app_deploy_healthcheck_path }}" - method: GET - status_code: 200 - return_content: true - timeout: "{{ app_deploy_healthcheck_timeout | int }}" - register: app_deploy_healthcheck - retries: "{{ app_deploy_healthcheck_retries | int }}" - delay: "{{ app_deploy_healthcheck_delay | int }}" - until: app_deploy_healthcheck.status == 200 - failed_when: app_deploy_healthcheck.json.status | default("") != "healthy" - delegate_to: "{{ app_deploy_healthcheck_delegate_to }}" - become: false diff --git a/ansible/roles/docker/handlers/docker_handlers.yml b/ansible/roles/docker/handlers/main.yml similarity index 100% rename from ansible/roles/docker/handlers/docker_handlers.yml rename to ansible/roles/docker/handlers/main.yml diff --git a/ansible/roles/docker/tasks/docker_tasks.yml b/ansible/roles/docker/tasks/main.yml similarity index 96% rename from ansible/roles/docker/tasks/docker_tasks.yml rename to ansible/roles/docker/tasks/main.yml index b9fa4f7013..8e29842d8b 100644 --- a/ansible/roles/docker/tasks/docker_tasks.yml +++ b/ansible/roles/docker/tasks/main.yml @@ -1,4 +1,10 @@ --- +- name: Load docker role defaults + ansible.builtin.include_vars: + file: "{{ role_path }}/defaults/docker_defaults.yml" + tags: + - always + - name: Manage Docker installation become: true tags: diff --git a/ansible/roles/web_app/defaults/web_app_defaults.yml b/ansible/roles/web_app/defaults/web_app_defaults.yml new file mode 100644 index 0000000000..102257c907 --- /dev/null +++ b/ansible/roles/web_app/defaults/web_app_defaults.yml @@ -0,0 +1,37 @@ +--- +web_app_registry_username: "{{ dockerhub_username | default('') }}" +web_app_registry_password: "{{ dockerhub_password | default(docker_api_token | default('')) }}" + +web_app_name: "{{ app_name | default('devops-app-py') }}" +web_app_service_name: "{{ web_app_name }}" +web_app_image: >- + {{ docker_image | default((web_app_registry_username ~ '/' ~ web_app_name) + if web_app_registry_username | length > 0 else web_app_name) }} +web_app_image_tag: "{{ docker_tag | default(docker_image_tag | default('latest')) }}" + +web_app_port: "{{ app_port | default(5000) }}" +web_app_container_name: "{{ app_container_name | default(web_app_name) }}" +web_app_internal_port: "{{ app_internal_port | default(app_container_internal_port | default(web_app_port)) }}" +web_app_restart_policy: "{{ app_restart_policy | default('unless-stopped') }}" + +web_app_environment: >- + {{ {'HOST': '0.0.0.0', 'PORT': (web_app_internal_port | string)} + | combine(app_environment | default({})) }} + +web_app_healthcheck_path: "{{ app_healthcheck_path | default('/health') }}" +web_app_healthcheck_retries: "{{ app_healthcheck_retries | default(20) }}" +web_app_healthcheck_delay: "{{ app_healthcheck_delay | default(3) }}" +web_app_healthcheck_timeout: "{{ app_healthcheck_timeout | default(3) }}" +web_app_healthcheck_host: "{{ app_healthcheck_host | default(ansible_host | default(inventory_hostname)) }}" +web_app_healthcheck_delegate_to: "{{ app_healthcheck_delegate_to | default('localhost') }}" + +web_app_compose_version: "{{ docker_compose_version | default('3.8') }}" +web_app_compose_project_dir: "{{ compose_project_dir | default('/opt/' ~ web_app_name) }}" +web_app_compose_file_name: "docker-compose.yml" +web_app_compose_pull_policy: "{{ app_compose_pull_policy | default('always') }}" +web_app_compose_recreate: "{{ app_compose_recreate | default('auto') }}" +web_app_compose_wait: "{{ app_compose_wait | default(true) }}" +web_app_compose_wait_timeout: "{{ app_compose_wait_timeout | default(60) }}" +web_app_compose_remove_orphans: "{{ app_compose_remove_orphans | default(true) }}" +web_app_network_name: "{{ web_app_name }}-network" +web_app_container_command: "{{ app_container_command | default('') }}" diff --git a/ansible/roles/web_app/meta/main.yml b/ansible/roles/web_app/meta/main.yml new file mode 100644 index 0000000000..2f1b4fbf00 --- /dev/null +++ b/ansible/roles/web_app/meta/main.yml @@ -0,0 +1,10 @@ +--- +dependencies: + - role: docker + tags: + - docker + - docker_install + - docker_config + - web_app + - app_deploy + - compose diff --git a/ansible/roles/web_app/tasks/web_app_tasks.yml b/ansible/roles/web_app/tasks/web_app_tasks.yml new file mode 100644 index 0000000000..c60ac2edaf --- /dev/null +++ b/ansible/roles/web_app/tasks/web_app_tasks.yml @@ -0,0 +1,107 @@ +--- +- name: Deploy web application with Docker Compose + become: true + tags: + - web_app + - app_deploy + - compose + block: + - name: Log in to Docker Hub when credentials are available + community.docker.docker_login: + registry_url: https://index.docker.io/v1/ + username: "{{ web_app_registry_username }}" + password: "{{ web_app_registry_password }}" + no_log: true + when: + - web_app_registry_username | string | length > 0 + - web_app_registry_password | string | length > 0 + + - name: Ensure Compose project directory exists + ansible.builtin.file: + path: "{{ web_app_compose_project_dir }}" + state: directory + owner: root + group: root + mode: "0755" + + - name: Check for legacy standalone container + community.docker.docker_container_info: + name: "{{ web_app_container_name }}" + register: web_app_legacy_container + + - name: Remove legacy standalone container before Compose migration + community.docker.docker_container: + name: "{{ web_app_container_name }}" + state: absent + when: + - web_app_legacy_container.exists | bool + - web_app_legacy_container.container is defined + - "'com.docker.compose.project' not in (web_app_legacy_container.container.Config.Labels | default({}))" + + - name: Template Docker Compose configuration + ansible.builtin.template: + src: docker-compose.yml.j2 + dest: "{{ web_app_compose_project_dir }}/{{ web_app_compose_file_name }}" + owner: root + group: root + mode: "0644" + + - name: Deploy application stack with Docker Compose + community.docker.docker_compose_v2: + project_src: "{{ web_app_compose_project_dir }}" + files: + - "{{ web_app_compose_file_name }}" + pull: "{{ web_app_compose_pull_policy }}" + recreate: "{{ web_app_compose_recreate }}" + remove_orphans: "{{ web_app_compose_remove_orphans | bool }}" + state: present + wait: "{{ web_app_compose_wait | bool }}" + wait_timeout: "{{ web_app_compose_wait_timeout | int }}" + register: web_app_compose_result + retries: 3 + delay: 10 + until: web_app_compose_result is succeeded + + - name: Wait for application port + ansible.builtin.wait_for: + host: "{{ web_app_healthcheck_host }}" + port: "{{ web_app_port | int }}" + timeout: 60 + delay: 1 + delegate_to: "{{ web_app_healthcheck_delegate_to }}" + become: false + + - name: Verify application health endpoint + ansible.builtin.uri: + url: "http://{{ web_app_healthcheck_host }}:{{ web_app_port }}{{ web_app_healthcheck_path }}" + method: GET + status_code: 200 + return_content: true + timeout: "{{ web_app_healthcheck_timeout | int }}" + register: web_app_healthcheck + retries: "{{ web_app_healthcheck_retries | int }}" + delay: "{{ web_app_healthcheck_delay | int }}" + until: web_app_healthcheck.status == 200 + failed_when: web_app_healthcheck.json.status | default("") != "healthy" + delegate_to: "{{ web_app_healthcheck_delegate_to }}" + become: false + + rescue: + - name: Capture docker compose status after failed deployment + ansible.builtin.command: + argv: + - docker + - compose + - -f + - "{{ web_app_compose_project_dir }}/{{ web_app_compose_file_name }}" + - ps + - --all + register: web_app_compose_ps + changed_when: false + failed_when: false + + - name: Fail deployment with compose status context + ansible.builtin.fail: + msg: >- + Web app deployment failed. Compose status: + {{ web_app_compose_ps.stdout | default('no compose status available') }} diff --git a/ansible/roles/web_app/templates/docker-compose.yml.j2 b/ansible/roles/web_app/templates/docker-compose.yml.j2 new file mode 100644 index 0000000000..0470877645 --- /dev/null +++ b/ansible/roles/web_app/templates/docker-compose.yml.j2 @@ -0,0 +1,21 @@ +services: + {{ web_app_service_name }}: + image: "{{ web_app_image }}:{{ web_app_image_tag }}" + container_name: "{{ web_app_container_name }}" +{% if web_app_container_command | length > 0 %} + command: "{{ web_app_container_command }}" +{% endif %} + ports: + - "{{ web_app_port }}:{{ web_app_internal_port }}" + environment: +{% for env_name, env_value in web_app_environment | dictsort %} + {{ env_name }}: "{{ env_value }}" +{% endfor %} + restart: "{{ web_app_restart_policy }}" + networks: + - web_app_network + +networks: + web_app_network: + name: "{{ web_app_network_name }}" + driver: bridge From 67f96414979e2840a1f40cb9c3edd1be7bb3d4dd Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 06:34:57 +0300 Subject: [PATCH 10/16] feat: ansible wipe logic --- ansible/docs/LAB06.md | 551 +++++++++++++++++- ansible/playbooks/deploy.yml | 1 + ansible/playbooks/site.yml | 1 + .../web_app/defaults/web_app_defaults.yml | 9 + ansible/roles/web_app/tasks/web_app_tasks.yml | 10 + ansible/roles/web_app/tasks/wipe.yml | 69 +++ 6 files changed, 630 insertions(+), 11 deletions(-) create mode 100644 ansible/roles/web_app/tasks/wipe.yml diff --git a/ansible/docs/LAB06.md b/ansible/docs/LAB06.md index 0090aceb39..7d50a8e52e 100644 --- a/ansible/docs/LAB06.md +++ b/ansible/docs/LAB06.md @@ -63,7 +63,7 @@ This run exercised only the Docker role and also proved that the `rescue` sectio
ansible-playbook playbooks/provision.yml --tags "docker" -```text +``` $ ansible-playbook playbooks/provision.yml --tags "docker" PLAY [Provision web servers] **************************************************************************************************** @@ -152,7 +152,7 @@ This is the strongest proof for Task 1 because it shows:
ansible-playbook playbooks/provision.yml --skip-tags "common" -```text +``` $ ansible-playbook playbooks/provision.yml --skip-tags "common" PLAY [Provision web servers] *************************************************** @@ -209,7 +209,7 @@ No `common` tasks ran, which confirms the role-level `common` tag is working.
ansible-playbook playbooks/provision.yml --tags "packages" -```text +``` $ ansible-playbook playbooks/provision.yml --tags "packages" PLAY [Provision web servers] *************************************************** @@ -242,7 +242,7 @@ This shows the `packages` tag is narrow enough to avoid unrelated common-role ta
ansible-playbook playbooks/provision.yml --tags "docker" --check -```text +``` $ ansible-playbook playbooks/provision.yml --tags "docker" --check PLAY [Provision web servers] *************************************************** @@ -299,7 +299,7 @@ Check mode completed without errors. One task reported `changed`, which is not s
ansible-playbook playbooks/provision.yml --tags "docker_install" -```text +``` $ ansible-playbook playbooks/provision.yml --tags "docker_install" PLAY [Provision web servers] *************************************************** @@ -352,7 +352,7 @@ Verified with:
ansible-playbook playbooks/provision.yml --list-tags -```text +``` $ ansible-playbook playbooks/provision.yml --list-tags @@ -506,7 +506,7 @@ The second deployment run proves idempotency for the Compose-based deployment:
ansible-playbook playbooks/deploy.yml (second run) -```text +``` $ ansible-playbook playbooks/deploy.yml PLAY [Deploy application] ******************************************************************************************************* @@ -588,7 +588,7 @@ Runtime verification on the VM confirms that the Compose stack is up and the app
docker ps -a -```text +``` vagrant@devops-core-s26:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc1ac63a19d3 localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" 13 seconds ago Up 12 seconds 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp devops-app @@ -599,7 +599,7 @@ bc1ac63a19d3 localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" 13
docker compose -f /opt/devops-app-py/docker-compose.yml ps -```text +``` vagrant@devops-core-s26:~$ docker compose -f /opt/devops-app-py/docker-compose.yml ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devops-app-py About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp @@ -610,7 +610,7 @@ devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devo
curl -fSsL 127.0.0.1:5000/health | jq -```text +``` vagrant@devops-core-s26:~$ curl -fSsL 127.0.0.1:5000/health | jq { "status": "healthy", @@ -630,7 +630,536 @@ vagrant@devops-core-s26:~$ curl -fSsL 127.0.0.1:5000/health | jq - A second deploy run returns `changed=0`, which demonstrates idempotency for the Compose workflow. - The VM shows the expected running container, Compose project status, and a healthy `/health` response. -## Task 3: Wipe Logic (pending) +## Task 3: Wipe Logic + +### Implementation Summary + +- Added the wipe control variables to `ansible/roles/web_app/defaults/web_app_defaults.yml`. +- Added the wipe task file `ansible/roles/web_app/tasks/wipe.yml`. +- Included wipe processing at the top of `ansible/roles/web_app/tasks/web_app_tasks.yml` so clean reinstall works as wipe → deploy. +- Added the `web_app_wipe` tag to the `web_app` role includes in `ansible/playbooks/deploy.yml` and `ansible/playbooks/site.yml`. +- Added optional image and volume cleanup switches with safe defaults of `false`. + +### Safety Design + +The wipe logic uses two controls: +- `web_app_wipe: true` is required before any destructive action happens. +- `--tags web_app_wipe` allows wipe-only execution without running the deployment block. + +Practical behavior: +- Normal deployment leaves wipe tasks skipped because `web_app_wipe` defaults to `false`. +- `ansible-playbook playbooks/deploy.yml -e web_app_wipe=true --tags web_app_wipe` performs wipe only. +- `ansible-playbook playbooks/deploy.yml -e web_app_wipe=true` performs clean reinstall. + +I used `-e app_compose_pull_policy=missing` for the deploy-related wipe tests so Docker Hub availability would not distort the wipe-logic results. That override was only for testing. + +### Evidence + +The evidence file is `task3.log`. + +#### Scenario 1: Normal deployment + +This shows that wipe tasks are present in the role flow but are skipped by default when `web_app_wipe` is `false`. + +
+ansible-playbook playbooks/deploy.yml -e app_compose_pull_policy=missing + +``` +$ ansible-playbook playbooks/deploy.yml -e app_compose_pull_policy=missing + +PLAY [Deploy application] ****************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run web app role] ******************************************************** +included: web_app for vagrant + +TASK [docker : Load docker role defaults] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker prerequisites] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************* +ok: [vagrant] + +TASK [docker : Add Docker apt repository] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************* +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ****************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************* +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ******************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] **************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************* +ok: [vagrant] + +TASK [web_app : Include web app wipe tasks] ************************************ +included: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant + +TASK [web_app : Check whether Compose file exists for wipe] ******************** +ok: [vagrant] + +TASK [web_app : Stop and remove Compose-managed containers] ******************** +skipping: [vagrant] + +TASK [web_app : Remove standalone web app container if present] **************** +skipping: [vagrant] + +TASK [web_app : Remove Compose file] ******************************************* +skipping: [vagrant] + +TASK [web_app : Remove Compose project directory] ****************************** +skipping: [vagrant] + +TASK [web_app : Optionally remove deployed image] ****************************** +skipping: [vagrant] + +TASK [web_app : Record web app wipe completion] ******************************** +skipping: [vagrant] + +TASK [web_app : Report web app wipe status] ************************************ +skipping: [vagrant] + +TASK [web_app : Log in to Docker Hub when credentials are available] *********** +ok: [vagrant] + +TASK [web_app : Ensure Compose project directory exists] *********************** +ok: [vagrant] + +TASK [web_app : Check for legacy standalone container] ************************* +ok: [vagrant] + +TASK [web_app : Remove legacy standalone container before Compose migration] *** +skipping: [vagrant] + +TASK [web_app : Template Docker Compose configuration] ************************* +ok: [vagrant] + +TASK [web_app : Deploy application stack with Docker Compose] ****************** +ok: [vagrant] + +TASK [web_app : Wait for application port] ************************************* +ok: [vagrant -> localhost] + +TASK [web_app : Verify application health endpoint] **************************** +ok: [vagrant -> localhost] + +PLAY RECAP ********************************************************************* +vagrant : ok=23 changed=0 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0 +``` + +
+ +
+ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' + +``` +$ ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' +vagrant | CHANGED | rc=0 >> +NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS +devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devops-app-py 11 minutes ago Up 11 minutes 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp +``` + +
+ +#### Scenario 2: Wipe only + +This is the explicit wipe-only path: variable enabled, tag selected, deployment tasks not executed. + +
+ansible-playbook playbooks/deploy.yml -e web_app_wipe=true --tags web_app_wipe + +``` +$ ansible-playbook playbooks/deploy.yml -e web_app_wipe=true --tags web_app_wipe + +PLAY [Deploy application] ****************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run web app role] ******************************************************** +included: web_app for vagrant + +TASK [docker : Load docker role defaults] ************************************** +ok: [vagrant] + +TASK [web_app : Include web app wipe tasks] ************************************ +included: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant + +TASK [web_app : Check whether Compose file exists for wipe] ******************** +ok: [vagrant] + +TASK [web_app : Stop and remove Compose-managed containers] ******************** +changed: [vagrant] + +TASK [web_app : Remove standalone web app container if present] **************** +ok: [vagrant] + +TASK [web_app : Remove Compose file] ******************************************* +changed: [vagrant] + +TASK [web_app : Remove Compose project directory] ****************************** +changed: [vagrant] + +TASK [web_app : Optionally remove deployed image] ****************************** +skipping: [vagrant] + +TASK [web_app : Record web app wipe completion] ******************************** +changed: [vagrant] + +TASK [web_app : Report web app wipe status] ************************************ +ok: [vagrant] => { + "msg": "Web app devops-app-py wipe completed. Project directory=/opt/devops-app-py." +} + +PLAY RECAP ********************************************************************* +vagrant : ok=11 changed=4 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +``` + +
+ +
+ansible webservers -m ansible.builtin.shell -a "docker ps -a | grep -F devops-app || true" + +``` +$ ansible webservers -m ansible.builtin.shell -a "docker ps -a | grep -F devops-app || true" +vagrant | CHANGED | rc=0 >> +``` + +
+ +
+ansible webservers -m ansible.builtin.shell -a "if [ -d /opt/devops-app-py ]; then echo present; else echo absent; fi" + +``` +$ ansible webservers -m ansible.builtin.shell -a "if [ -d /opt/devops-app-py ]; then echo present; else echo absent; fi" +vagrant | CHANGED | rc=0 >> +absent +``` + +
+ +#### Scenario 3: Clean reinstall + +This is the key workflow for Task 3: wipe first, then redeploy cleanly in the same playbook run. + +
+ansible-playbook playbooks/deploy.yml -e web_app_wipe=true -e app_compose_pull_policy=missing + +``` +$ ansible-playbook playbooks/deploy.yml -e web_app_wipe=true -e app_compose_pull_policy=missing + +PLAY [Deploy application] ****************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run web app role] ******************************************************** +included: web_app for vagrant + +TASK [docker : Load docker role defaults] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker prerequisites] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker keyring directory exists] ************************* +ok: [vagrant] + +TASK [docker : Add Docker GPG key] ********************************************* +ok: [vagrant] + +TASK [docker : Add Docker apt repository] ************************************** +ok: [vagrant] + +TASK [docker : Install Docker engine packages] ********************************* +ok: [vagrant] + +TASK [docker : Install Docker Python SDK package] ****************************** +ok: [vagrant] + +TASK [docker : Mark Docker service as ready] *********************************** +ok: [vagrant] + +TASK [docker : Ensure Docker service is enabled and running] ******************* +ok: [vagrant] + +TASK [docker : Record Docker installation block completion] ******************** +ok: [vagrant] + +TASK [docker : Add deployment user to docker group] **************************** +ok: [vagrant] + +TASK [docker : Record Docker configuration block completion] ******************* +ok: [vagrant] + +TASK [web_app : Include web app wipe tasks] ************************************ +included: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant + +TASK [web_app : Check whether Compose file exists for wipe] ******************** +ok: [vagrant] + +TASK [web_app : Stop and remove Compose-managed containers] ******************** +skipping: [vagrant] + +TASK [web_app : Remove standalone web app container if present] **************** +ok: [vagrant] + +TASK [web_app : Remove Compose file] ******************************************* +ok: [vagrant] + +TASK [web_app : Remove Compose project directory] ****************************** +ok: [vagrant] + +TASK [web_app : Optionally remove deployed image] ****************************** +skipping: [vagrant] + +TASK [web_app : Record web app wipe completion] ******************************** +changed: [vagrant] + +TASK [web_app : Report web app wipe status] ************************************ +ok: [vagrant] => { + "msg": "Web app devops-app-py wipe completed. Project directory=/opt/devops-app-py." +} + +TASK [web_app : Log in to Docker Hub when credentials are available] *********** +ok: [vagrant] + +TASK [web_app : Ensure Compose project directory exists] *********************** +changed: [vagrant] + +TASK [web_app : Check for legacy standalone container] ************************* +ok: [vagrant] + +TASK [web_app : Remove legacy standalone container before Compose migration] *** +skipping: [vagrant] + +TASK [web_app : Template Docker Compose configuration] ************************* +changed: [vagrant] + +TASK [web_app : Deploy application stack with Docker Compose] ****************** +changed: [vagrant] + +TASK [web_app : Wait for application port] ************************************* +ok: [vagrant -> localhost] + +TASK [web_app : Verify application health endpoint] **************************** +ok: [vagrant -> localhost] + +PLAY RECAP ********************************************************************* +vagrant : ok=28 changed=4 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0 +``` + +
+ +
+ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' + +``` +$ ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' +vagrant | CHANGED | rc=0 >> +NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS +devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devops-app-py 4 seconds ago Up 3 seconds 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp +``` + +
+ +
+ansible webservers -m ansible.builtin.shell -a "curl -fSsL 127.0.0.1:5000/health" + +``` +$ ansible webservers -m ansible.builtin.shell -a "curl -fSsL 127.0.0.1:5000/health" +vagrant | CHANGED | rc=0 >> +{"status":"healthy","timestamp":"2026-03-06T03:24:46.458130+00:00","uptime_seconds":3} +``` + +
+ +#### Scenario 4: Safety checks + +For Scenario 4a, the lab text says deployment should run normally when `--tags web_app_wipe` is used with `web_app_wipe=false`. In practice, Ansible tag filtering only selects the wipe-tagged path, so the deployment block does not run. The existing application remains running, which still proves the wipe did not trigger. I believe the lab wording is internally inconsistent here. + +
+ansible-playbook playbooks/deploy.yml --tags web_app_wipe + +``` +$ ansible-playbook playbooks/deploy.yml --tags web_app_wipe + +PLAY [Deploy application] ****************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run web app role] ******************************************************** +included: web_app for vagrant + +TASK [docker : Load docker role defaults] ************************************** +ok: [vagrant] + +TASK [web_app : Include web app wipe tasks] ************************************ +included: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant + +TASK [web_app : Check whether Compose file exists for wipe] ******************** +ok: [vagrant] + +TASK [web_app : Stop and remove Compose-managed containers] ******************** +skipping: [vagrant] + +TASK [web_app : Remove standalone web app container if present] **************** +skipping: [vagrant] + +TASK [web_app : Remove Compose file] ******************************************* +skipping: [vagrant] + +TASK [web_app : Remove Compose project directory] ****************************** +skipping: [vagrant] + +TASK [web_app : Optionally remove deployed image] ****************************** +skipping: [vagrant] + +TASK [web_app : Record web app wipe completion] ******************************** +skipping: [vagrant] + +TASK [web_app : Report web app wipe status] ************************************ +skipping: [vagrant] + +PLAY RECAP ********************************************************************* +vagrant : ok=5 changed=0 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0 +``` + +
+ +
+ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' + +``` +$ ansible webservers -m ansible.builtin.command -a 'docker compose -f /opt/devops-app-py/docker-compose.yml ps' +vagrant | CHANGED | rc=0 >> +NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS +devops-app localt0aster/devops-app-py:latest "sh -c 'gunicorn --b…" devops-app-py 11 minutes ago Up 11 minutes 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp +``` + +
+ +Scenario 4b is effectively the same selective wipe-only path as Scenario 2, but rechecked after a clean reinstall. + +
+ansible-playbook playbooks/deploy.yml -e web_app_wipe=true --tags web_app_wipe + +``` +$ ansible-playbook playbooks/deploy.yml -e web_app_wipe=true --tags web_app_wipe + +PLAY [Deploy application] ****************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [vagrant] + +TASK [Run web app role] ******************************************************** +included: web_app for vagrant + +TASK [docker : Load docker role defaults] ************************************** +ok: [vagrant] + +TASK [web_app : Include web app wipe tasks] ************************************ +included: /home/t0ast/Repos/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant + +TASK [web_app : Check whether Compose file exists for wipe] ******************** +ok: [vagrant] + +TASK [web_app : Stop and remove Compose-managed containers] ******************** +changed: [vagrant] + +TASK [web_app : Remove standalone web app container if present] **************** +ok: [vagrant] + +TASK [web_app : Remove Compose file] ******************************************* +changed: [vagrant] + +TASK [web_app : Remove Compose project directory] ****************************** +changed: [vagrant] + +TASK [web_app : Optionally remove deployed image] ****************************** +skipping: [vagrant] + +TASK [web_app : Record web app wipe completion] ******************************** +ok: [vagrant] + +TASK [web_app : Report web app wipe status] ************************************ +ok: [vagrant] => { + "msg": "Web app devops-app-py wipe completed. Project directory=/opt/devops-app-py." +} + +PLAY RECAP ********************************************************************* +vagrant : ok=11 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +``` + +
+ +
+ansible webservers -m ansible.builtin.shell -a "docker ps -a | grep -F devops-app || true" + +``` +$ ansible webservers -m ansible.builtin.shell -a "docker ps -a | grep -F devops-app || true" +vagrant | CHANGED | rc=0 >> +``` + +
+ +
+ansible webservers -m ansible.builtin.shell -a "if [ -d /opt/devops-app-py ]; then echo present; else echo absent; fi" + +``` +$ ansible webservers -m ansible.builtin.shell -a "if [ -d /opt/devops-app-py ]; then echo present; else echo absent; fi" +vagrant | CHANGED | rc=0 >> +absent +``` + +
+ +### Validation Status + +- `ansible-playbook playbooks/deploy.yml --syntax-check` passes. +- `ansible-playbook playbooks/site.yml --syntax-check` passes. +- `ansible-lint` passes on the Task 3 files. +- `ansible-playbook playbooks/deploy.yml --list-tags` shows `web_app_wipe`. +- All four wipe scenarios were exercised against the VM. +- The application was restored after testing. + +### Research Answers + +1. **Why use both variable AND tag?** + - The variable is the destructive-action safety switch. The tag is the execution selector. Together they reduce accidental wipes and also support a wipe-only workflow without running normal deployment tasks. + +2. **What's the difference between `never` tag and this approach?** + - `never` disables tasks unless explicitly requested by tag, but it does not express business intent by itself. The variable-plus-tag approach is clearer because it encodes both operator intent and destructive permission. It is also easier to support clean reinstall with the same playbook run. + +3. **Why must wipe logic come BEFORE deployment?** + - Because clean reinstall is a sequential workflow: remove the old deployment first, then recreate it from a known-clean state. If wipe happened after deployment, it would destroy the fresh deployment. + +4. **When would you want clean reinstallation vs. rolling update?** + - Clean reinstall is useful when state is corrupted, migrations need a known baseline, or you want to prove reproducibility from scratch. Rolling update is better when you want lower disruption and the current deployment is already healthy. + +5. **How would you extend this to wipe Docker images and volumes too?** + - The current implementation already exposes `web_app_wipe_remove_images` and `web_app_wipe_remove_volumes`. To go further, I would add named-volume targeting, network cleanup verification, and possibly a confirmation variable for destructive data removal if persistent volumes matter. + ## Task 4: CI/CD (pending) diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml index 282103c6f2..880c313fb7 100644 --- a/ansible/playbooks/deploy.yml +++ b/ansible/playbooks/deploy.yml @@ -18,3 +18,4 @@ - web_app - app_deploy - compose + - web_app_wipe diff --git a/ansible/playbooks/site.yml b/ansible/playbooks/site.yml index 61e73bc983..a80d09911d 100644 --- a/ansible/playbooks/site.yml +++ b/ansible/playbooks/site.yml @@ -31,3 +31,4 @@ - web_app - app_deploy - compose + - web_app_wipe diff --git a/ansible/roles/web_app/defaults/web_app_defaults.yml b/ansible/roles/web_app/defaults/web_app_defaults.yml index 102257c907..b79d064df1 100644 --- a/ansible/roles/web_app/defaults/web_app_defaults.yml +++ b/ansible/roles/web_app/defaults/web_app_defaults.yml @@ -35,3 +35,12 @@ web_app_compose_wait_timeout: "{{ app_compose_wait_timeout | default(60) }}" web_app_compose_remove_orphans: "{{ app_compose_remove_orphans | default(true) }}" web_app_network_name: "{{ web_app_name }}-network" web_app_container_command: "{{ app_container_command | default('') }}" + +# Wipe logic control +# Set to true to remove the deployed application before continuing. +# Wipe only: ansible-playbook playbooks/deploy.yml -e "web_app_wipe=true" --tags web_app_wipe +# Clean install: ansible-playbook playbooks/deploy.yml -e "web_app_wipe=true" +web_app_wipe: false +web_app_wipe_remove_images: false +web_app_wipe_remove_volumes: false +web_app_wipe_log_path: "/tmp/ansible-web-app-wipe.log" diff --git a/ansible/roles/web_app/tasks/web_app_tasks.yml b/ansible/roles/web_app/tasks/web_app_tasks.yml index c60ac2edaf..c8de93b0ca 100644 --- a/ansible/roles/web_app/tasks/web_app_tasks.yml +++ b/ansible/roles/web_app/tasks/web_app_tasks.yml @@ -1,4 +1,14 @@ --- +- name: Include web app wipe tasks + ansible.builtin.include_tasks: + file: wipe.yml + apply: + tags: + - web_app_wipe + tags: + - always + - web_app_wipe + - name: Deploy web application with Docker Compose become: true tags: diff --git a/ansible/roles/web_app/tasks/wipe.yml b/ansible/roles/web_app/tasks/wipe.yml new file mode 100644 index 0000000000..12bfce55f0 --- /dev/null +++ b/ansible/roles/web_app/tasks/wipe.yml @@ -0,0 +1,69 @@ +--- +- name: Check whether Compose file exists for wipe + ansible.builtin.stat: + path: "{{ web_app_compose_project_dir }}/{{ web_app_compose_file_name }}" + register: web_app_wipe_compose_file + become: true + tags: + - web_app_wipe + +- name: Wipe web application deployment + become: true + when: web_app_wipe | bool + tags: + - web_app_wipe + block: + - name: Stop and remove Compose-managed containers + community.docker.docker_compose_v2: + project_src: "{{ web_app_compose_project_dir }}" + files: + - "{{ web_app_compose_file_name }}" + state: absent + remove_orphans: true + remove_volumes: "{{ web_app_wipe_remove_volumes | bool }}" + when: web_app_wipe_compose_file.stat.exists + register: web_app_wipe_compose_down + failed_when: false + + - name: Remove standalone web app container if present + community.docker.docker_container: + name: "{{ web_app_container_name }}" + state: absent + + - name: Remove Compose file + ansible.builtin.file: + path: "{{ web_app_compose_project_dir }}/{{ web_app_compose_file_name }}" + state: absent + + - name: Remove Compose project directory + ansible.builtin.file: + path: "{{ web_app_compose_project_dir }}" + state: absent + + - name: Optionally remove deployed image + community.docker.docker_image_remove: + name: "{{ web_app_image }}" + tag: "{{ web_app_image_tag }}" + force: true + when: web_app_wipe_remove_images | bool + register: web_app_wipe_image_remove + failed_when: false + + always: + - name: Record web app wipe completion + ansible.builtin.lineinfile: + path: "{{ web_app_wipe_log_path }}" + line: >- + web_app wipe completed + (requested={{ web_app_wipe | bool }}, + compose_file_present={{ web_app_wipe_compose_file.stat.exists | default(false) }}, + remove_images={{ web_app_wipe_remove_images | bool }}, + remove_volumes={{ web_app_wipe_remove_volumes | bool }}) + create: true + mode: "0644" + + - name: Report web app wipe status + ansible.builtin.debug: + msg: >- + Web app {{ web_app_name }} wipe completed. + Project directory={{ web_app_compose_project_dir }}. From bda59e74af5e459497c2bff7a6d936a6537a37a8 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 07:26:42 +0300 Subject: [PATCH 11/16] feat: 2nd Vagrant VM with github-runner --- vagrant/.gitignore | 3 + vagrant/README.md | 83 ++++++++++- vagrant/Vagrantfile | 138 ++++++++++++------ vagrant/shared/github-runner.env.example | 14 ++ .../shared/provision-gh-runner-register.sh | 100 +++++++++++++ vagrant/shared/provision-gh-runner.sh | 91 ++++++++++++ 6 files changed, 381 insertions(+), 48 deletions(-) create mode 100644 vagrant/shared/github-runner.env.example create mode 100644 vagrant/shared/provision-gh-runner-register.sh create mode 100644 vagrant/shared/provision-gh-runner.sh diff --git a/vagrant/.gitignore b/vagrant/.gitignore index 09fd60c6cc..f6183f774c 100644 --- a/vagrant/.gitignore +++ b/vagrant/.gitignore @@ -7,3 +7,6 @@ shared/** !shared/provision.sh !shared/provision-post-kernel.sh +!shared/provision-gh-runner.sh +!shared/provision-gh-runner-register.sh +!shared/github-runner.env.example diff --git a/vagrant/README.md b/vagrant/README.md index f7d3d056e3..24174798f9 100644 --- a/vagrant/README.md +++ b/vagrant/README.md @@ -1,8 +1,11 @@ # Vagrant (libvirt) -This VM is configured for the `libvirt` provider and uses: +This Vagrant setup is configured for the `libvirt` provider and uses: - Box: `alvistack/ubuntu-24.04` +- Machines: + - `default` — main lab VM / deployment target + - `github-runner` — isolated self-hosted GitHub Actions runner VM ## Requirements @@ -28,11 +31,22 @@ To re-run provisioning on an existing VM: vagrant provision ``` +The `github-runner` machine is defined with `autostart: false`, so it will not +come up unless you ask for it explicitly: + +```bash +cd vagrant +vagrant up github-runner +vagrant ssh github-runner +``` + Provisioning is split into two stages: - `shared/provision.sh` (kernel/package update stage) - automatic reboot between stages - `shared/provision-post-kernel.sh` (post-kernel stage with ansible install) +- `shared/provision-gh-runner.sh` (runner VM only; installs the GitHub runner binaries) +- `shared/provision-gh-runner-register.sh` (runner VM only; manual registration step) SSH key setup: @@ -44,6 +58,8 @@ Static VM IP: - default: `192.168.121.50` - override: `VM_IP=192.168.121.60 vagrant up` +- runner default: `192.168.121.51` +- runner override: `RUNNER_VM_IP=192.168.121.61 vagrant up github-runner` This setup uses: @@ -65,3 +81,68 @@ Host vagrant User vagrant IdentityFile ~/.ssh/vagrant ``` + +## GitHub Runner VM + +The runner is intentionally isolated in its own VM. That keeps the deployment +target and the CI runner state separate. + +Bring up the runner VM: + +```bash +cd vagrant +vagrant up github-runner +``` + +Base runner provisioning installs: + +- `ansible` +- `git`, `curl`, `jq`, `tar`, `unzip` +- the GitHub Actions runner under `/opt/actions-runner` +- a dedicated `github-runner` user + +Registration is a separate manual step because GitHub registration tokens are +short-lived. + +1. Copy the example environment file: + +```bash +cp shared/github-runner.env.example shared/github-runner.env +``` + +2. Edit `shared/github-runner.env` and fill in: + +- `GH_RUNNER_URL` +- `GH_RUNNER_TOKEN` +- optional runner name / labels / group / workdir + +If the runner VM is already running, sync the updated file into the guest: + +```bash +vagrant rsync github-runner +``` + +3. Run the registration provisioner: + +```bash +vagrant provision github-runner --provision-with github-runner-register +``` + +You can also pass the same values through host environment variables instead of +using `shared/github-runner.env`. + +Useful commands: + +```bash +vagrant ssh github-runner +sudo systemctl list-units 'actions.runner.*' +sudo systemctl status 'actions.runner.*' +``` + +Notes: + +- The registration step is idempotent for an already configured runner; it + starts the service again if needed. +- The runner VM does not install Docker by default. For this lab's Ansible + workflow, that is sufficient. If you later add container actions, install + Docker on the runner VM as well. diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile index 53e78574f2..f6bc680c11 100644 --- a/vagrant/Vagrantfile +++ b/vagrant/Vagrantfile @@ -1,56 +1,100 @@ Vagrant.configure("2") do |config| - config.vm.box = "alvistack/ubuntu-24.04" - config.vm.box_check_update = false - config.vm.hostname = "devops-core-s26" - vm_ip = ENV.fetch("VM_IP", "192.168.121.50") + box_name = "alvistack/ubuntu-24.04" + target_vm_ip = ENV.fetch("VM_IP", "192.168.121.50") + runner_vm_ip = ENV.fetch("RUNNER_VM_IP", "192.168.121.51") host_ssh_key = File.expand_path("~/.ssh/vagrant") host_ssh_pub = "#{host_ssh_key}.pub" + fallback_ssh_key = File.expand_path("~/.vagrant.d/insecure_private_key") - # Prefer host key for SSH, but keep Vagrant's insecure key as a fallback. - config.ssh.insert_key = false - config.ssh.private_key_path = [ - host_ssh_key, - File.expand_path("~/.vagrant.d/insecure_private_key") - ] - - # Keep project root available in the guest for labs and tooling. - config.vm.synced_folder ".", "/vagrant", disabled: true - config.vm.synced_folder "./shared", "/shared" - config.vm.network "private_network", ip: vm_ip - - # Install host public key for `vagrant` user access. - if File.exist?(host_ssh_pub) - config.vm.provision "file", source: host_ssh_pub, destination: "/tmp/vagrant.pub" - config.vm.provision "shell", - name: "install-host-ssh-key", - inline: <<-SHELL - set -euo pipefail - if [ ! -f /tmp/vagrant.pub ]; then - echo "Skipping host SSH key install: /tmp/vagrant.pub not found." - exit 0 - fi - install -d -m 700 /home/vagrant/.ssh - touch /home/vagrant/.ssh/authorized_keys - pub_key="$(cat /tmp/vagrant.pub)" - grep -qxF "$pub_key" /home/vagrant/.ssh/authorized_keys || echo "$pub_key" >> /home/vagrant/.ssh/authorized_keys - chown -R vagrant:vagrant /home/vagrant/.ssh - chmod 700 /home/vagrant/.ssh - chmod 600 /home/vagrant/.ssh/authorized_keys - rm -f /tmp/vagrant.pub - SHELL + runner_env = { + "GH_RUNNER_VERSION" => ENV.fetch("GH_RUNNER_VERSION", ""), + "GH_RUNNER_URL" => ENV.fetch("GH_RUNNER_URL", ""), + "GH_RUNNER_TOKEN" => ENV.fetch("GH_RUNNER_TOKEN", ""), + "GH_RUNNER_NAME" => ENV.fetch("GH_RUNNER_NAME", ""), + "GH_RUNNER_LABELS" => ENV.fetch("GH_RUNNER_LABELS", ""), + "GH_RUNNER_GROUP" => ENV.fetch("GH_RUNNER_GROUP", ""), + "GH_RUNNER_WORKDIR" => ENV.fetch("GH_RUNNER_WORKDIR", ""), + "GH_RUNNER_DISABLE_UPDATE" => ENV.fetch("GH_RUNNER_DISABLE_UPDATE", "") + } + + configure_common_vm = lambda do |machine, hostname:, ip:, cpus:, memory:| + machine.vm.box = box_name + machine.vm.box_check_update = false + machine.vm.hostname = hostname + + machine.ssh.insert_key = false + machine.ssh.private_key_path = [host_ssh_key, fallback_ssh_key] + + machine.vm.synced_folder ".", "/vagrant", disabled: true + machine.vm.synced_folder "./shared", "/shared" + machine.vm.network "private_network", ip: ip + + if File.exist?(host_ssh_pub) + machine.vm.provision "file", source: host_ssh_pub, destination: "/tmp/vagrant.pub" + machine.vm.provision "shell", + name: "install-host-ssh-key", + inline: <<-SHELL + set -euo pipefail + if [ ! -f /tmp/vagrant.pub ]; then + echo "Skipping host SSH key install: /tmp/vagrant.pub not found." + exit 0 + fi + install -d -m 700 /home/vagrant/.ssh + touch /home/vagrant/.ssh/authorized_keys + pub_key="$(cat /tmp/vagrant.pub)" + grep -qxF "$pub_key" /home/vagrant/.ssh/authorized_keys || echo "$pub_key" >> /home/vagrant/.ssh/authorized_keys + chown -R vagrant:vagrant /home/vagrant/.ssh + chmod 700 /home/vagrant/.ssh + chmod 600 /home/vagrant/.ssh/authorized_keys + rm -f /tmp/vagrant.pub + SHELL + end + + machine.vm.provider :libvirt do |libvirt| + libvirt.cpus = cpus.to_i + libvirt.memory = memory.to_i + end end - # Stage 1: update/purge packages, including kernel changes. - config.vm.provision "shell", - name: "kernel-update", - path: "shared/provision.sh", - reboot: true - # Stage 2: post-reboot setup. - config.vm.provision "shell", name: "post-kernel", path: "shared/provision-post-kernel.sh" - - config.vm.provider :libvirt do |libvirt| - libvirt.cpus = ENV.fetch("VM_CPUS", "2").to_i - libvirt.memory = ENV.fetch("VM_MEMORY", "4096").to_i + config.vm.define "default", primary: true do |target| + configure_common_vm.call( + target, + hostname: "devops-core-s26", + ip: target_vm_ip, + cpus: ENV.fetch("VM_CPUS", "2"), + memory: ENV.fetch("VM_MEMORY", "2048") + ) + + target.vm.provision "shell", + name: "kernel-update", + path: "shared/provision.sh", + reboot: true + target.vm.provision "shell", name: "post-kernel", path: "shared/provision-post-kernel.sh" + end + + config.vm.define "github-runner", autostart: false do |runner| + configure_common_vm.call( + runner, + hostname: "github-runner-s26", + ip: runner_vm_ip, + cpus: ENV.fetch("RUNNER_VM_CPUS", "2"), + memory: ENV.fetch("RUNNER_VM_MEMORY", "2048") + ) + + runner.vm.provision "shell", + name: "kernel-update", + path: "shared/provision.sh", + reboot: true + runner.vm.provision "shell", name: "post-kernel", path: "shared/provision-post-kernel.sh" + runner.vm.provision "shell", + name: "github-runner-base", + path: "shared/provision-gh-runner.sh", + env: runner_env + runner.vm.provision "shell", + name: "github-runner-register", + path: "shared/provision-gh-runner-register.sh", + env: runner_env, + run: "never" end end diff --git a/vagrant/shared/github-runner.env.example b/vagrant/shared/github-runner.env.example new file mode 100644 index 0000000000..7c750fba09 --- /dev/null +++ b/vagrant/shared/github-runner.env.example @@ -0,0 +1,14 @@ +# Copy this file to shared/github-runner.env and fill in the values before +# running: +# vagrant provision github-runner --provision-with github-runner-register + +GH_RUNNER_URL="https://github.com/OWNER/REPOSITORY" +GH_RUNNER_TOKEN="REPLACE_WITH_EPHEMERAL_REGISTRATION_TOKEN" + +# Optional overrides +GH_RUNNER_NAME="github-runner-s26" +GH_RUNNER_LABELS="self-hosted,linux,vagrant" +GH_RUNNER_GROUP="Default" +GH_RUNNER_WORKDIR="_work" +# GH_RUNNER_VERSION="PIN_A_KNOWN_RUNNER_VERSION" +# GH_RUNNER_DISABLE_UPDATE="true" diff --git a/vagrant/shared/provision-gh-runner-register.sh b/vagrant/shared/provision-gh-runner-register.sh new file mode 100644 index 0000000000..be6902328a --- /dev/null +++ b/vagrant/shared/provision-gh-runner-register.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "$(id -u)" -ne 0 ]; then + echo "Please run this script as root or using sudo!" + exit 13 +fi + +if [ -f /shared/github-runner.env ]; then + set -a + # shellcheck disable=SC1091 + . /shared/github-runner.env + set +a +fi + +if [ ! -f /shared/github-runner.env ] && [ -z "${GH_RUNNER_URL:-}" ] && [ -z "${GH_RUNNER_TOKEN:-}" ]; then + cat <<'EOF' >&2 +Runner configuration is missing inside the guest. +If you created vagrant/shared/github-runner.env on the host after the VM was already running, +sync it first with: + vagrant rsync github-runner +Or bypass the shared file and pass GH_RUNNER_URL / GH_RUNNER_TOKEN in the host environment. +EOF +fi + +: "${GH_RUNNER_URL:?Set GH_RUNNER_URL in /shared/github-runner.env or the host environment.}" +: "${GH_RUNNER_TOKEN:?Set GH_RUNNER_TOKEN in /shared/github-runner.env or the host environment.}" + +if [ ! -x /opt/actions-runner/config.sh ]; then + echo "GitHub runner is not installed. Run the base provisioner first." >&2 + exit 1 +fi + +runner_name="${GH_RUNNER_NAME:-$(hostname -s)}" +runner_labels="${GH_RUNNER_LABELS:-self-hosted,linux,vagrant}" +runner_group="${GH_RUNNER_GROUP:-Default}" +runner_workdir="${GH_RUNNER_WORKDIR:-_work}" +runner_disable_update="${GH_RUNNER_DISABLE_UPDATE:-false}" + +export RUNNER_URL="$GH_RUNNER_URL" +export RUNNER_TOKEN="$GH_RUNNER_TOKEN" +export RUNNER_NAME="$runner_name" +export RUNNER_LABELS="$runner_labels" +export RUNNER_GROUP="$runner_group" +export RUNNER_WORKDIR="$runner_workdir" +export RUNNER_DISABLE_UPDATE="$runner_disable_update" + +if [ ! -f /opt/actions-runner/.runner ]; then + sudo -u github-runner --preserve-env=RUNNER_URL,RUNNER_TOKEN,RUNNER_NAME,RUNNER_LABELS,RUNNER_GROUP,RUNNER_WORKDIR,RUNNER_DISABLE_UPDATE bash <<'EOF' +set -euo pipefail +cd /opt/actions-runner + +config_args=( + ./config.sh + --unattended + --url "$RUNNER_URL" + --token "$RUNNER_TOKEN" + --name "$RUNNER_NAME" + --labels "$RUNNER_LABELS" + --work "$RUNNER_WORKDIR" + --replace +) + +if [ "$RUNNER_GROUP" != "Default" ]; then + config_args+=(--runnergroup "$RUNNER_GROUP") +fi + +if [ "$RUNNER_DISABLE_UPDATE" = "true" ]; then + config_args+=(--disableupdate) +fi + +"${config_args[@]}" +EOF +fi + +install -d /etc/needrestart/conf.d +cat <<'EOF' > /etc/needrestart/conf.d/actions_runner_services.conf +$nrconf{override_rc}{qr(^actions\.runner\..+\.service$)} = 0; +EOF + +if ! compgen -G "/etc/systemd/system/actions.runner.*.service" >/dev/null; then + ( + cd /opt/actions-runner + ./svc.sh install github-runner + ) +fi + +systemctl daemon-reload + +service_units=(/etc/systemd/system/actions.runner.*.service) +if [ "${service_units[0]}" = "/etc/systemd/system/actions.runner.*.service" ]; then + echo "Runner service unit was not created." >&2 + exit 1 +fi + +for service_unit in "${service_units[@]}"; do + systemctl enable --now "$(basename "$service_unit")" +done + +echo "GitHub runner configured and started successfully." diff --git a/vagrant/shared/provision-gh-runner.sh b/vagrant/shared/provision-gh-runner.sh new file mode 100644 index 0000000000..fe22cd89e2 --- /dev/null +++ b/vagrant/shared/provision-gh-runner.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "$(id -u)" -ne 0 ]; then + echo "Please run this script as root or using sudo!" + exit 13 +fi + +export DEBIAN_FRONTEND=noninteractive + +apt-get update +apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + git \ + jq \ + tar \ + unzip + +if ! id -u github-runner >/dev/null 2>&1; then + useradd --create-home --home-dir /home/github-runner --shell /bin/bash github-runner +fi + +install -d -o github-runner -g github-runner /opt/actions-runner +install -d -o github-runner -g github-runner /opt/actions-runner/_work + +runner_version="${GH_RUNNER_VERSION:-}" +if [ -z "$runner_version" ]; then + runner_version="$(curl -fsSL https://api.github.com/repos/actions/runner/releases/latest | jq -r '.tag_name | ltrimstr("v")')" +fi + +runner_arch="$(dpkg --print-architecture)" +case "$runner_arch" in + amd64) + runner_arch="x64" + ;; + arm64) + runner_arch="arm64" + ;; + *) + echo "Unsupported runner architecture: $runner_arch" >&2 + exit 1 + ;; +esac + +install_marker="/opt/actions-runner/.runner-version" +installed_version="" +if [ -f "$install_marker" ]; then + installed_version="$(cat "$install_marker")" +fi + +runner_is_configured="false" +if [ -f /opt/actions-runner/.runner ]; then + runner_is_configured="true" +fi + +if [ "$installed_version" != "$runner_version" ] || [ ! -x /opt/actions-runner/bin/Runner.Listener ]; then + if [ "$runner_is_configured" = "true" ] && [ -x /opt/actions-runner/bin/Runner.Listener ]; then + cat < "$install_marker" + chown -R github-runner:github-runner /opt/actions-runner +fi + +if [ ! -f /shared/github-runner.env ]; then + cat <<'EOF' +GitHub runner base installation complete. +Create /shared/github-runner.env from /shared/github-runner.env.example, +fill in GH_RUNNER_URL and GH_RUNNER_TOKEN, then run: + vagrant provision github-runner --provision-with github-runner-register +EOF +fi From 0efc37a4684683519fda84f43e71e6e296987eb4 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 07:34:37 +0300 Subject: [PATCH 12/16] I hope nothing explodes --- .github/actions/ansible-deploy/action.yml | 57 ++++++++ .github/actions/ansible-lint/action.yml | 39 ++++++ .github/actions/ansible-setup/action.yml | 59 ++++++++ .github/actions/ansible-ssh-setup/action.yml | 41 ++++++ .github/actions/http-healthcheck/action.yml | 50 +++++++ .github/workflows/ansible-deploy.yml | 134 +++++++++++++++++++ README.md | 1 + ansible/docs/LAB06.md | 60 ++++++++- ansible/requirements-ci.txt | 2 + 9 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 .github/actions/ansible-deploy/action.yml create mode 100644 .github/actions/ansible-lint/action.yml create mode 100644 .github/actions/ansible-setup/action.yml create mode 100644 .github/actions/ansible-ssh-setup/action.yml create mode 100644 .github/actions/http-healthcheck/action.yml create mode 100644 .github/workflows/ansible-deploy.yml create mode 100644 ansible/requirements-ci.txt diff --git a/.github/actions/ansible-deploy/action.yml b/.github/actions/ansible-deploy/action.yml new file mode 100644 index 0000000000..6382dc90a5 --- /dev/null +++ b/.github/actions/ansible-deploy/action.yml @@ -0,0 +1,57 @@ +name: Ansible Deploy +description: Run an Ansible playbook with vault decryption enabled + +inputs: + ansible-directory: + description: Directory containing the Ansible project + required: false + default: "ansible" + playbook-path: + description: Relative path to the playbook to execute + required: false + default: "playbooks/deploy.yml" + inventory-path: + description: Relative path to the inventory file + required: false + default: "inventory/hosts.ini" + vault-password: + description: Vault password used to decrypt encrypted vars + required: true + tags: + description: Comma-separated tag list to execute + required: false + default: "app_deploy" + +outputs: + log-path: + description: Path to the saved ansible-playbook log file + value: ${{ steps.deploy.outputs.log-path }} + +runs: + using: composite + steps: + - id: deploy + name: Run ansible-playbook + shell: bash + working-directory: ${{ inputs.ansible-directory }} + env: + VAULT_PASSWORD: ${{ inputs.vault-password }} + PLAYBOOK_PATH: ${{ inputs.playbook-path }} + INVENTORY_PATH: ${{ inputs.inventory-path }} + PLAYBOOK_TAGS: ${{ inputs.tags }} + run: | + set -euo pipefail + umask 077 + + log_path="${RUNNER_TEMP}/ansible-deploy.log" + + cleanup() { + rm -f .vault_pass + } + trap cleanup EXIT + + printf '%s\n' "$VAULT_PASSWORD" > .vault_pass + + ansible-playbook "$PLAYBOOK_PATH" -i "$INVENTORY_PATH" --tags "$PLAYBOOK_TAGS" | tee "$log_path" + + echo "log-path=$log_path" >> "$GITHUB_OUTPUT" diff --git a/.github/actions/ansible-lint/action.yml b/.github/actions/ansible-lint/action.yml new file mode 100644 index 0000000000..1a52f08ed6 --- /dev/null +++ b/.github/actions/ansible-lint/action.yml @@ -0,0 +1,39 @@ +name: Ansible Lint +description: Run ansible-lint and syntax checks with vault access + +inputs: + ansible-directory: + description: Directory containing the Ansible project + required: false + default: "ansible" + vault-password: + description: Vault password used to decrypt encrypted vars during linting + required: true + playbook-glob: + description: Playbook glob for ansible-lint + required: false + default: "playbooks/*.yml" + +runs: + using: composite + steps: + - name: Run ansible-lint and syntax checks + shell: bash + working-directory: ${{ inputs.ansible-directory }} + env: + VAULT_PASSWORD: ${{ inputs.vault-password }} + PLAYBOOK_GLOB: ${{ inputs.playbook-glob }} + run: | + set -euo pipefail + umask 077 + cleanup() { + rm -f .vault_pass + } + trap cleanup EXIT + + printf '%s\n' "$VAULT_PASSWORD" > .vault_pass + + ansible-lint $PLAYBOOK_GLOB + ansible-playbook playbooks/provision.yml --syntax-check + ansible-playbook playbooks/deploy.yml --syntax-check + ansible-playbook playbooks/site.yml --syntax-check diff --git a/.github/actions/ansible-setup/action.yml b/.github/actions/ansible-setup/action.yml new file mode 100644 index 0000000000..084b42c462 --- /dev/null +++ b/.github/actions/ansible-setup/action.yml @@ -0,0 +1,59 @@ +name: Ansible Setup +description: Set up a Python-based Ansible toolchain and required collections + +inputs: + python-version: + description: Python version to install + required: false + default: "3.12" + working-directory: + description: Directory containing the Ansible project + required: false + default: "ansible" + python-requirements-path: + description: Path to the pip requirements file + required: false + default: "ansible/requirements-ci.txt" + collection-requirements-path: + description: Path to the ansible-galaxy requirements file + required: false + default: "ansible/requirements.yml" + +runs: + using: composite + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + + - name: Cache Ansible toolchain + uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/.ansible/collections + ${{ inputs.working-directory }}/.venv-ci + key: ${{ runner.os }}-py${{ inputs.python-version }}-ansible-${{ hashFiles(inputs.python-requirements-path, inputs.collection-requirements-path) }} + restore-keys: | + ${{ runner.os }}-py${{ inputs.python-version }}-ansible- + + - name: Install Python dependencies + shell: bash + run: | + set -euo pipefail + python -m venv "${{ inputs.working-directory }}/.venv-ci" + . "${{ inputs.working-directory }}/.venv-ci/bin/activate" + python -m pip install --upgrade pip + python -m pip install -r "${{ inputs.python-requirements-path }}" + + - name: Install Ansible collections + shell: bash + run: | + set -euo pipefail + . "${{ inputs.working-directory }}/.venv-ci/bin/activate" + ansible-galaxy collection install -r "${{ inputs.collection-requirements-path }}" + + - name: Add Ansible venv to PATH + shell: bash + run: echo "${{ github.workspace }}/${{ inputs.working-directory }}/.venv-ci/bin" >> "$GITHUB_PATH" diff --git a/.github/actions/ansible-ssh-setup/action.yml b/.github/actions/ansible-ssh-setup/action.yml new file mode 100644 index 0000000000..d682973fc9 --- /dev/null +++ b/.github/actions/ansible-ssh-setup/action.yml @@ -0,0 +1,41 @@ +name: Ansible SSH Setup +description: Install the SSH key material required for Ansible access + +inputs: + ssh-private-key: + description: Private SSH key used to connect to the target VM + required: true + ssh-key-path: + description: Destination path for the private key + required: false + default: "~/.ssh/vagrant" + known-host: + description: Optional host to add to known_hosts + required: false + default: "" + +runs: + using: composite + steps: + - name: Configure SSH credentials + shell: bash + env: + SSH_PRIVATE_KEY: ${{ inputs.ssh-private-key }} + SSH_KEY_PATH: ${{ inputs.ssh-key-path }} + KNOWN_HOST: ${{ inputs.known-host }} + run: | + set -euo pipefail + + key_path="${SSH_KEY_PATH/#\~/$HOME}" + + install -d -m 700 "$HOME/.ssh" + install -d -m 700 "$(dirname "$key_path")" + printf '%s\n' "$SSH_PRIVATE_KEY" > "$key_path" + chmod 600 "$key_path" + + touch "$HOME/.ssh/known_hosts" + chmod 600 "$HOME/.ssh/known_hosts" + + if [ -n "$KNOWN_HOST" ]; then + ssh-keyscan -H "$KNOWN_HOST" >> "$HOME/.ssh/known_hosts" 2>/dev/null || true + fi diff --git a/.github/actions/http-healthcheck/action.yml b/.github/actions/http-healthcheck/action.yml new file mode 100644 index 0000000000..a1886f690d --- /dev/null +++ b/.github/actions/http-healthcheck/action.yml @@ -0,0 +1,50 @@ +name: HTTP Healthcheck +description: Poll an HTTP endpoint until it returns healthy JSON + +inputs: + url: + description: URL to poll + required: true + retries: + description: Number of polling attempts before failure + required: false + default: "10" + delay-seconds: + description: Delay between retries in seconds + required: false + default: "3" + jq-filter: + description: jq expression that must evaluate to true + required: false + default: '.status == "healthy"' + +runs: + using: composite + steps: + - name: Poll health endpoint + shell: bash + env: + URL: ${{ inputs.url }} + RETRIES: ${{ inputs.retries }} + DELAY_SECONDS: ${{ inputs.delay-seconds }} + JQ_FILTER: ${{ inputs.jq-filter }} + run: | + set -euo pipefail + + response="" + + for attempt in $(seq 1 "$RETRIES"); do + if response="$(curl -fsSL "$URL")"; then + break + fi + + if [ "$attempt" -eq "$RETRIES" ]; then + echo "Health check failed after $RETRIES attempts: $URL" >&2 + exit 1 + fi + + sleep "$DELAY_SECONDS" + done + + echo "$response" | jq . + echo "$response" | jq -e "$JQ_FILTER" >/dev/null diff --git a/.github/workflows/ansible-deploy.yml b/.github/workflows/ansible-deploy.yml new file mode 100644 index 0000000000..661852a11c --- /dev/null +++ b/.github/workflows/ansible-deploy.yml @@ -0,0 +1,134 @@ +name: Ansible Deployment + +on: + push: + branches: + - main + - master + paths: + - ansible/** + - .github/actions/ansible-setup/** + - .github/actions/ansible-lint/** + - .github/actions/ansible-ssh-setup/** + - .github/actions/ansible-deploy/** + - .github/actions/http-healthcheck/** + - .github/workflows/ansible-deploy.yml + - "!ansible/docs/**" + pull_request: + branches: + - main + - master + paths: + - ansible/** + - .github/actions/ansible-setup/** + - .github/actions/ansible-lint/** + - .github/actions/ansible-ssh-setup/** + - .github/actions/ansible-deploy/** + - .github/actions/http-healthcheck/** + - .github/workflows/ansible-deploy.yml + - "!ansible/docs/**" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ansible-deploy-${{ github.ref }} + cancel-in-progress: true + +env: + ANSIBLE_DIRECTORY: ansible + DEPLOY_PLAYBOOK: playbooks/deploy.yml + DEPLOY_TAGS: app_deploy + +jobs: + lint: + name: Ansible Lint + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Ansible toolchain + uses: ./.github/actions/ansible-setup + + - name: Run lint and syntax checks + uses: ./.github/actions/ansible-lint + with: + ansible-directory: ${{ env.ANSIBLE_DIRECTORY }} + vault-password: ${{ secrets.ANSIBLE_VAULT_PASSWORD }} + + deploy: + name: Deploy Application + needs: lint + if: github.event_name != 'pull_request' + runs-on: + - self-hosted + - linux + - vagrant + timeout-minutes: 20 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Ansible toolchain + uses: ./.github/actions/ansible-setup + + - name: Resolve target host from inventory + working-directory: ${{ env.ANSIBLE_DIRECTORY }} + run: | + set -euo pipefail + target_host="$( + awk ' + /^[[:space:]]*#/ { next } + /^\[/ { next } + NF { + for (i = 1; i <= NF; i++) { + if ($i ~ /^ansible_host=/) { + split($i, value, "=") + print value[2] + exit + } + } + } + ' inventory/hosts.ini + )" + + if [ -z "$target_host" ]; then + echo "Could not determine ansible_host from inventory/hosts.ini" >&2 + exit 1 + fi + + echo "TARGET_VM_HOST=$target_host" >> "$GITHUB_ENV" + + - name: Configure SSH access to the target VM + uses: ./.github/actions/ansible-ssh-setup + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + known-host: ${{ env.TARGET_VM_HOST }} + + - name: Verify target connectivity + working-directory: ${{ env.ANSIBLE_DIRECTORY }} + run: ansible webservers -m ansible.builtin.ping + + - id: deploy + name: Deploy web application + uses: ./.github/actions/ansible-deploy + with: + ansible-directory: ${{ env.ANSIBLE_DIRECTORY }} + playbook-path: ${{ env.DEPLOY_PLAYBOOK }} + vault-password: ${{ secrets.ANSIBLE_VAULT_PASSWORD }} + tags: ${{ env.DEPLOY_TAGS }} + + - name: Upload deployment log + if: always() && steps.deploy.outputs.log-path != '' + uses: actions/upload-artifact@v4 + with: + name: ansible-deploy-log + path: ${{ steps.deploy.outputs.log-path }} + + - name: Verify application health + uses: ./.github/actions/http-healthcheck + with: + url: http://${{ env.TARGET_VM_HOST }}:5000/health diff --git a/README.md b/README.md index a66ee3dc20..9d68fc1744 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Labs](https://img.shields.io/badge/Labs-18-blue)](#labs) [![Exam](https://img.shields.io/badge/Exam-Optional-green)](#exam-alternative) [![Duration](https://img.shields.io/badge/Duration-18%20Weeks-lightgrey)](#course-roadmap) +[![Ansible Deployment](https://github.com/LocalT0aster/DevOps-Core-S26/actions/workflows/ansible-deploy.yml/badge.svg)](https://github.com/LocalT0aster/DevOps-Core-S26/actions/workflows/ansible-deploy.yml) Master **production-grade DevOps practices** through hands-on labs. Build, containerize, deploy, monitor, and scale applications using industry-standard tools. diff --git a/ansible/docs/LAB06.md b/ansible/docs/LAB06.md index 7d50a8e52e..a75985ee23 100644 --- a/ansible/docs/LAB06.md +++ b/ansible/docs/LAB06.md @@ -1161,7 +1161,65 @@ absent - The current implementation already exposes `web_app_wipe_remove_images` and `web_app_wipe_remove_volumes`. To go further, I would add named-volume targeting, network cleanup verification, and possibly a confirmation variable for destructive data removal if persistent volumes matter. -## Task 4: CI/CD (pending) +## Task 4: CI/CD (3 pts) + +### Workflow Architecture + +- Added a dedicated GitHub Actions workflow in `.github/workflows/ansible-deploy.yml`. +- Split the workflow logic into local composite actions under `.github/actions/` so the workflow file stays orchestration-focused. +- Kept `lint` on `ubuntu-latest` and `deploy` on the isolated self-hosted runner labels `self-hosted`, `linux`, `vagrant`. +- Limited deployment to `push` and `workflow_dispatch`; pull requests run lint only. +- Added path filters so documentation-only changes under `ansible/docs/` do not trigger the deployment pipeline. + +### Modular Actions + +- `.github/actions/ansible-setup/action.yml` creates a Python virtual environment, installs `ansible-core` + `ansible-lint`, and installs required collections from `ansible/requirements.yml`. +- `.github/actions/ansible-lint/action.yml` writes the vault password to a temporary file, runs `ansible-lint`, and performs syntax checks on `provision.yml`, `deploy.yml`, and `site.yml`. +- `.github/actions/ansible-ssh-setup/action.yml` writes the target SSH key to `~/.ssh/vagrant` so the existing inventory file continues to work unchanged. +- `.github/actions/ansible-deploy/action.yml` runs `ansible-playbook playbooks/deploy.yml --tags app_deploy` and saves the playbook output as a workflow artifact. +- `.github/actions/http-healthcheck/action.yml` polls `http://:5000/health` and validates that the JSON reports `"status": "healthy"`. + +### Secrets and Repository Settings + +Required GitHub Actions secrets: +- `ANSIBLE_VAULT_PASSWORD` +- `SSH_PRIVATE_KEY` + +The workflow derives the deployment target IP from `ansible/inventory/hosts.ini`, so there is no second host variable to keep in sync. +The self-hosted runner itself is isolated in the separate `github-runner` Vagrant VM described in `vagrant/README.md`. + +### Files Added or Updated + +- Added `.github/workflows/ansible-deploy.yml` +- Added `.github/actions/ansible-setup/action.yml` +- Added `.github/actions/ansible-lint/action.yml` +- Added `.github/actions/ansible-ssh-setup/action.yml` +- Added `.github/actions/ansible-deploy/action.yml` +- Added `.github/actions/http-healthcheck/action.yml` +- Added `ansible/requirements-ci.txt` +- Added the workflow badge to `README.md` + +### Validation Status + +- The local Ansible side is already validated: `ansible-lint` passes, and the playbooks used by the workflow pass syntax checks. +- `vagrant validate` for the isolated runner VM passes. +- The GitHub Actions workflow and composite actions are implemented locally and ready to run on the configured self-hosted runner. +- Pull requests from external forks are intentionally excluded from the secret-backed lint path, because vault decryption requires repository secrets. +- A successful GitHub-hosted execution still depends on repository secrets being present and the workflow being triggered from GitHub. + +### Research Answers + +1. **What are the security implications of storing SSH keys in GitHub Secrets?** + - The main benefit is that the key is not committed to the repository, but it is still high-value material. Anyone who can modify a trusted workflow on the default branch can potentially exfiltrate it. The practical controls are branch protection, restricted workflow write access, least-privilege keys, and avoiding self-hosted execution on untrusted pull requests. + +2. **How would you implement a staging → production deployment pipeline?** + - I would split deployment into at least two environments, each with separate inventories, secrets, and GitHub environments. The workflow would deploy automatically to staging, run verification, and only then allow a protected manual approval gate for production. + +3. **What would you add to make rollbacks possible?** + - I would pin image tags to immutable versions instead of `latest`, persist the previously deployed tag, and add a rollback workflow input that redeploys the last known good version. For stronger rollback guarantees, I would also archive the exact Compose template and deployment metadata as workflow artifacts. + +4. **How does self-hosted runner improve security compared to GitHub-hosted?** + - In this lab's setup, the runner stays inside the local private network and can reach the VM directly without exposing SSH to the public internet. That reduces credential sprawl and keeps deployment traffic local. The tradeoff is that a self-hosted runner is persistent, so its trust boundary must be managed more carefully than GitHub-hosted ephemeral runners. ## Task 5: Documentation diff --git a/ansible/requirements-ci.txt b/ansible/requirements-ci.txt new file mode 100644 index 0000000000..313cb46fde --- /dev/null +++ b/ansible/requirements-ci.txt @@ -0,0 +1,2 @@ +ansible-core>=2.16,<2.20 +ansible-lint==26.3.0 From a55c6b2893cd350604e17a6a94df98ffdd677fba Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 07:50:07 +0300 Subject: [PATCH 13/16] fix: rebuild ansible ci venv on each run --- .github/actions/ansible-setup/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/ansible-setup/action.yml b/.github/actions/ansible-setup/action.yml index 084b42c462..db9bf8e309 100644 --- a/.github/actions/ansible-setup/action.yml +++ b/.github/actions/ansible-setup/action.yml @@ -33,7 +33,6 @@ runs: path: | ~/.cache/pip ~/.ansible/collections - ${{ inputs.working-directory }}/.venv-ci key: ${{ runner.os }}-py${{ inputs.python-version }}-ansible-${{ hashFiles(inputs.python-requirements-path, inputs.collection-requirements-path) }} restore-keys: | ${{ runner.os }}-py${{ inputs.python-version }}-ansible- @@ -42,6 +41,7 @@ runs: shell: bash run: | set -euo pipefail + rm -rf "${{ inputs.working-directory }}/.venv-ci" python -m venv "${{ inputs.working-directory }}/.venv-ci" . "${{ inputs.working-directory }}/.venv-ci/bin/activate" python -m pip install --upgrade pip From 2fb03c3d96de805525f9f85661db3ddc447f9c0f Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:21:49 +0300 Subject: [PATCH 14/16] fix: forgor about password --- .github/workflows/ansible-deploy.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/ansible-deploy.yml b/.github/workflows/ansible-deploy.yml index 661852a11c..db8b46b853 100644 --- a/.github/workflows/ansible-deploy.yml +++ b/.github/workflows/ansible-deploy.yml @@ -108,6 +108,15 @@ jobs: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} known-host: ${{ env.TARGET_VM_HOST }} + - name: Prepare vault password file + working-directory: ${{ env.ANSIBLE_DIRECTORY }} + env: + VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }} + run: | + set -euo pipefail + umask 077 + printf '%s\n' "$VAULT_PASSWORD" > .vault_pass + - name: Verify target connectivity working-directory: ${{ env.ANSIBLE_DIRECTORY }} run: ansible webservers -m ansible.builtin.ping @@ -132,3 +141,8 @@ jobs: uses: ./.github/actions/http-healthcheck with: url: http://${{ env.TARGET_VM_HOST }}:5000/health + + - name: Remove vault password file + if: always() + working-directory: ${{ env.ANSIBLE_DIRECTORY }} + run: rm -f .vault_pass From 2492c7d27ac02a50f12e2ca7f51bc1d7882b8489 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:29:02 +0300 Subject: [PATCH 15/16] work please --- .github/workflows/ansible-deploy.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ansible-deploy.yml b/.github/workflows/ansible-deploy.yml index db8b46b853..ce0f001192 100644 --- a/.github/workflows/ansible-deploy.yml +++ b/.github/workflows/ansible-deploy.yml @@ -3,8 +3,8 @@ name: Ansible Deployment on: push: branches: - - main - master + - "lab*" paths: - ansible/** - .github/actions/ansible-setup/** @@ -16,7 +16,6 @@ on: - "!ansible/docs/**" pull_request: branches: - - main - master paths: - ansible/** From 46873112f66f1e23ace45ae5df545d83292e21c6 Mon Sep 17 00:00:00 2001 From: LocalT0aster <90502400+LocalT0aster@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:44:33 +0300 Subject: [PATCH 16/16] feat: wrap up the report --- ansible/docs/LAB06.md | 1239 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1236 insertions(+), 3 deletions(-) diff --git a/ansible/docs/LAB06.md b/ansible/docs/LAB06.md index a75985ee23..48ef9ca971 100644 --- a/ansible/docs/LAB06.md +++ b/ansible/docs/LAB06.md @@ -1199,13 +1199,1238 @@ The self-hosted runner itself is isolated in the separate `github-runner` Vagran - Added `ansible/requirements-ci.txt` - Added the workflow badge to `README.md` +### Evidence + +The raw GitHub Actions run log is saved locally as `task4.log`. + +- Successful workflow run: +- Event: `push` +- Branch: `lab06` +- Result: `success` +- Lint job: +- Deploy job: +- Deployment log artifact: + +
+Workflow run summary + +```json +{ + "run_id": 22750506418, + "title": "work please", + "event": "push", + "branch": "lab06", + "status": "completed", + "conclusion": "success", + "created_at": "2026-03-06T05:29:07Z", + "updated_at": "2026-03-06T05:31:58Z" +} +``` + +
+ +
+Ansible Lint job excerpt + +```text +Passed: 0 failure(s), 0 warning(s) in 9 files processed of 9 encountered. Profile 'production' was required, and it passed. +playbook: playbooks/provision.yml +playbook: playbooks/deploy.yml +playbook: playbooks/site.yml +``` + +
+ +
+Deploy Application job excerpt + +```text +Prepare vault password file +Verify target connectivity +vagrant | SUCCESS => { + "changed": false, + "ping": "pong" +} +PLAY RECAP ********************************************************************* +vagrant : ok=22 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +Artifact ansible-deploy-log has been successfully uploaded! Final size is 808 bytes. Artifact ID is 5792366004 +Remove vault password file +``` + +
+ +
+Health check excerpt + +```json +{ + "status": "healthy", + "timestamp": "2026-03-06T05:31:51.856613+00:00", + "uptime_seconds": 7603 +} +``` + +
+ +
+Full log + +```log +Ansible Lint Set up job 2026-03-06T05:29:10.5329423Z Current runner version: '2.332.0' +Ansible Lint Set up job 2026-03-06T05:29:10.5360328Z ##[group]Runner Image Provisioner +Ansible Lint Set up job 2026-03-06T05:29:10.5361185Z Hosted Compute Agent +Ansible Lint Set up job 2026-03-06T05:29:10.5361774Z Version: 20260213.493 +Ansible Lint Set up job 2026-03-06T05:29:10.5362403Z Commit: 5c115507f6dd24b8de37d8bbe0bb4509d0cc0fa3 +Ansible Lint Set up job 2026-03-06T05:29:10.5363145Z Build Date: 2026-02-13T00:28:41Z +Ansible Lint Set up job 2026-03-06T05:29:10.5363778Z Worker ID: {2041351a-97c7-45c8-90a5-5ac75b9b9cf3} +Ansible Lint Set up job 2026-03-06T05:29:10.5364557Z Azure Region: northcentralus +Ansible Lint Set up job 2026-03-06T05:29:10.5365170Z ##[endgroup] +Ansible Lint Set up job 2026-03-06T05:29:10.5366962Z ##[group]Operating System +Ansible Lint Set up job 2026-03-06T05:29:10.5367667Z Ubuntu +Ansible Lint Set up job 2026-03-06T05:29:10.5368167Z 24.04.3 +Ansible Lint Set up job 2026-03-06T05:29:10.5368631Z LTS +Ansible Lint Set up job 2026-03-06T05:29:10.5369148Z ##[endgroup] +Ansible Lint Set up job 2026-03-06T05:29:10.5369635Z ##[group]Runner Image +Ansible Lint Set up job 2026-03-06T05:29:10.5370202Z Image: ubuntu-24.04 +Ansible Lint Set up job 2026-03-06T05:29:10.5370770Z Version: 20260302.42.1 +Ansible Lint Set up job 2026-03-06T05:29:10.5371770Z Included Software: https://github.com/actions/runner-images/blob/ubuntu24/20260302.42/images/ubuntu/Ubuntu2404-Readme.md +Ansible Lint Set up job 2026-03-06T05:29:10.5373467Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu24%2F20260302.42 +Ansible Lint Set up job 2026-03-06T05:29:10.5374434Z ##[endgroup] +Ansible Lint Set up job 2026-03-06T05:29:10.5375723Z ##[group]GITHUB_TOKEN Permissions +Ansible Lint Set up job 2026-03-06T05:29:10.5377590Z Contents: read +Ansible Lint Set up job 2026-03-06T05:29:10.5378212Z Metadata: read +Ansible Lint Set up job 2026-03-06T05:29:10.5378677Z ##[endgroup] +Ansible Lint Set up job 2026-03-06T05:29:10.5380727Z Secret source: Actions +Ansible Lint Set up job 2026-03-06T05:29:10.5381433Z Prepare workflow directory +Ansible Lint Set up job 2026-03-06T05:29:10.5877192Z Prepare all required actions +Ansible Lint Set up job 2026-03-06T05:29:10.5932576Z Getting action download info +Ansible Lint Set up job 2026-03-06T05:29:10.8794598Z Download action repository 'actions/checkout@v4' (SHA:34e114876b0b11c390a56381ad16ebd13914f8d5) +Ansible Lint Set up job 2026-03-06T05:29:11.1099497Z Complete job name: Ansible Lint +Ansible Lint Checkout code 2026-03-06T05:29:11.1884697Z ##[group]Run actions/checkout@v4 +Ansible Lint Checkout code 2026-03-06T05:29:11.1885706Z with: +Ansible Lint Checkout code 2026-03-06T05:29:11.1886156Z repository: LocalT0aster/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.1886842Z token: *** +Ansible Lint Checkout code 2026-03-06T05:29:11.1887231Z ssh-strict: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1887635Z ssh-user: git +Ansible Lint Checkout code 2026-03-06T05:29:11.1888031Z persist-credentials: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1888477Z clean: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1888878Z sparse-checkout-cone-mode: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1889348Z fetch-depth: 1 +Ansible Lint Checkout code 2026-03-06T05:29:11.1889753Z fetch-tags: false +Ansible Lint Checkout code 2026-03-06T05:29:11.1890154Z show-progress: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1890571Z lfs: false +Ansible Lint Checkout code 2026-03-06T05:29:11.1890938Z submodules: false +Ansible Lint Checkout code 2026-03-06T05:29:11.1891331Z set-safe-directory: true +Ansible Lint Checkout code 2026-03-06T05:29:11.1891962Z env: +Ansible Lint Checkout code 2026-03-06T05:29:11.1892352Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Checkout code 2026-03-06T05:29:11.1892850Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Checkout code 2026-03-06T05:29:11.1893371Z DEPLOY_TAGS: app_deploy +Ansible Lint Checkout code 2026-03-06T05:29:11.1893792Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.2964777Z Syncing repository: LocalT0aster/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.2967010Z ##[group]Getting Git version info +Ansible Lint Checkout code 2026-03-06T05:29:11.2967786Z Working directory is '/home/runner/work/DevOps-Core-S26/DevOps-Core-S26' +Ansible Lint Checkout code 2026-03-06T05:29:11.2968817Z [command]/usr/bin/git version +Ansible Lint Checkout code 2026-03-06T05:29:11.3042020Z git version 2.53.0 +Ansible Lint Checkout code 2026-03-06T05:29:11.3067759Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.3081932Z Temporarily overriding HOME='/home/runner/work/_temp/890e68c6-2607-4793-b4c9-d348425e2444' before making global git config changes +Ansible Lint Checkout code 2026-03-06T05:29:11.3094172Z Adding repository directory to the temporary git global config as a safe directory +Ansible Lint Checkout code 2026-03-06T05:29:11.3095606Z [command]/usr/bin/git config --global --add safe.directory /home/runner/work/DevOps-Core-S26/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.3134382Z Deleting the contents of '/home/runner/work/DevOps-Core-S26/DevOps-Core-S26' +Ansible Lint Checkout code 2026-03-06T05:29:11.3138290Z ##[group]Initializing the repository +Ansible Lint Checkout code 2026-03-06T05:29:11.3142225Z [command]/usr/bin/git init /home/runner/work/DevOps-Core-S26/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.3230735Z hint: Using 'master' as the name for the initial branch. This default branch name +Ansible Lint Checkout code 2026-03-06T05:29:11.3232149Z hint: will change to "main" in Git 3.0. To configure the initial branch name +Ansible Lint Checkout code 2026-03-06T05:29:11.3233366Z hint: to use in all of your new repositories, which will suppress this warning, +Ansible Lint Checkout code 2026-03-06T05:29:11.3234537Z hint: call: +Ansible Lint Checkout code 2026-03-06T05:29:11.3235183Z hint: +Ansible Lint Checkout code 2026-03-06T05:29:11.3236155Z hint: git config --global init.defaultBranch +Ansible Lint Checkout code 2026-03-06T05:29:11.3236776Z hint: +Ansible Lint Checkout code 2026-03-06T05:29:11.3237351Z hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and +Ansible Lint Checkout code 2026-03-06T05:29:11.3238302Z hint: 'development'. The just-created branch can be renamed via this command: +Ansible Lint Checkout code 2026-03-06T05:29:11.3239050Z hint: +Ansible Lint Checkout code 2026-03-06T05:29:11.3239448Z hint: git branch -m +Ansible Lint Checkout code 2026-03-06T05:29:11.3240148Z hint: +Ansible Lint Checkout code 2026-03-06T05:29:11.3240823Z hint: Disable this message with "git config set advice.defaultBranchName false" +Ansible Lint Checkout code 2026-03-06T05:29:11.3242206Z Initialized empty Git repository in /home/runner/work/DevOps-Core-S26/DevOps-Core-S26/.git/ +Ansible Lint Checkout code 2026-03-06T05:29:11.3246185Z [command]/usr/bin/git remote add origin https://github.com/LocalT0aster/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.3279691Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.3280429Z ##[group]Disabling automatic garbage collection +Ansible Lint Checkout code 2026-03-06T05:29:11.3284110Z [command]/usr/bin/git config --local gc.auto 0 +Ansible Lint Checkout code 2026-03-06T05:29:11.3312715Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.3313412Z ##[group]Setting up auth +Ansible Lint Checkout code 2026-03-06T05:29:11.3319862Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand +Ansible Lint Checkout code 2026-03-06T05:29:11.3350673Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +Ansible Lint Checkout code 2026-03-06T05:29:11.3675159Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +Ansible Lint Checkout code 2026-03-06T05:29:11.3706457Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +Ansible Lint Checkout code 2026-03-06T05:29:11.3938616Z [command]/usr/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +Ansible Lint Checkout code 2026-03-06T05:29:11.3969877Z [command]/usr/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +Ansible Lint Checkout code 2026-03-06T05:29:11.4214694Z [command]/usr/bin/git config --local http.https://github.com/.extraheader AUTHORIZATION: basic *** +Ansible Lint Checkout code 2026-03-06T05:29:11.4250962Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.4251733Z ##[group]Fetching the repository +Ansible Lint Checkout code 2026-03-06T05:29:11.4259070Z [command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +2492c7d27ac02a50f12e2ca7f51bc1d7882b8489:refs/remotes/origin/lab06 +Ansible Lint Checkout code 2026-03-06T05:29:11.7606599Z From https://github.com/LocalT0aster/DevOps-Core-S26 +Ansible Lint Checkout code 2026-03-06T05:29:11.7607942Z * [new ref] 2492c7d27ac02a50f12e2ca7f51bc1d7882b8489 -> origin/lab06 +Ansible Lint Checkout code 2026-03-06T05:29:11.7641114Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.7641819Z ##[group]Determining the checkout info +Ansible Lint Checkout code 2026-03-06T05:29:11.7644340Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.7651042Z [command]/usr/bin/git sparse-checkout disable +Ansible Lint Checkout code 2026-03-06T05:29:11.7694047Z [command]/usr/bin/git config --local --unset-all extensions.worktreeConfig +Ansible Lint Checkout code 2026-03-06T05:29:11.7726044Z ##[group]Checking out the ref +Ansible Lint Checkout code 2026-03-06T05:29:11.7730689Z [command]/usr/bin/git checkout --progress --force -B lab06 refs/remotes/origin/lab06 +Ansible Lint Checkout code 2026-03-06T05:29:11.7916810Z Switched to a new branch 'lab06' +Ansible Lint Checkout code 2026-03-06T05:29:11.7920253Z branch 'lab06' set up to track 'origin/lab06'. +Ansible Lint Checkout code 2026-03-06T05:29:11.7927351Z ##[endgroup] +Ansible Lint Checkout code 2026-03-06T05:29:11.7961096Z [command]/usr/bin/git log -1 --format=%H +Ansible Lint Checkout code 2026-03-06T05:29:11.7984326Z 2492c7d27ac02a50f12e2ca7f51bc1d7882b8489 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:11.8266011Z Prepare all required actions +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:11.8266740Z Getting action download info +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:11.9642088Z Download action repository 'actions/setup-python@v5' (SHA:a26af69be951a213d495a4c3e4e4022e16d87065) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.0926196Z Download action repository 'actions/cache@v4' (SHA:0057852bfaa89a56745cba8c7296529d2fc39830) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2754803Z ##[group]Run ./.github/actions/ansible-setup +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2756101Z with: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2756875Z python-version: 3.12 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2757772Z working-directory: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2758919Z python-requirements-path: ansible/requirements-ci.txt +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2760341Z collection-requirements-path: ansible/requirements.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2761526Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2762260Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2763240Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2764268Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2765123Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2953557Z ##[group]Run actions/setup-python@v5 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2954605Z with: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2955561Z python-version: 3.12 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2956433Z check-latest: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2957494Z token: *** +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2958279Z update-environment: true +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2959180Z allow-prereleases: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2960062Z freethreaded: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2960864Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2961589Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2962544Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2963542Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.2964389Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.4642413Z ##[group]Installed versions +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.4726679Z Successfully set up CPython (3.12.12) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.4729711Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5526985Z ##[group]Run actions/cache@v4 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5527927Z with: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5528767Z path: ~/.cache/pip +Ansible Lint Setup Ansible toolchain ~/.ansible/collections +Ansible Lint Setup Ansible toolchain +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5530434Z key: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5532114Z restore-keys: Linux-py3.12-ansible- +Ansible Lint Setup Ansible toolchain +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5533131Z enableCrossOsArchive: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5534054Z fail-on-cache-miss: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5534903Z lookup-only: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5535979Z save-always: false +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5536767Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5537478Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5538412Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5539397Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5540456Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5541914Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5543343Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5544669Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5546641Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5548045Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.5549177Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:12.8056849Z Cache hit for: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.2661813Z Received 16876233 of 16876233 (100.0%), 45.1 MBs/sec +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.2662769Z Cache Size: ~16 MB (16876233 B) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.2695856Z [command]/usr/bin/tar -xf /home/runner/work/_temp/ed14daa5-3d21-447d-b84b-82030a283c55/cache.tzst -P -C /home/runner/work/DevOps-Core-S26/DevOps-Core-S26 --use-compress-program unzstd +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3615615Z Cache restored successfully +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3743008Z Cache restored from key: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3852777Z ##[group]Run set -euo pipefail +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3853186Z set -euo pipefail +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3853496Z rm -rf "ansible/.venv-ci" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3853828Z python -m venv "ansible/.venv-ci" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3854470Z . "ansible/.venv-ci/bin/activate" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3854821Z python -m pip install --upgrade pip +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3855722Z python -m pip install -r "ansible/requirements-ci.txt" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3912991Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3913612Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3913856Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3914173Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3914488Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3914830Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3915535Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3916011Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3916433Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3916855Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3917310Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:13.3917678Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.4817418Z Requirement already satisfied: pip in ./ansible/.venv-ci/lib/python3.12/site-packages (25.0.1) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5674329Z Collecting pip +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5687767Z Using cached pip-26.0.1-py3-none-any.whl.metadata (4.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5720838Z Using cached pip-26.0.1-py3-none-any.whl (1.8 MB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5891297Z Installing collected packages: pip +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5893687Z Attempting uninstall: pip +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.5915418Z Found existing installation: pip 25.0.1 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.6291717Z Uninstalling pip-25.0.1: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:17.6349799Z Successfully uninstalled pip-25.0.1 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:18.7331183Z Successfully installed pip-26.0.1 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2368546Z Collecting ansible-core<2.20,>=2.16 (from -r ansible/requirements-ci.txt (line 1)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2386317Z Using cached ansible_core-2.19.7-py3-none-any.whl.metadata (7.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2666691Z Collecting ansible-lint==26.3.0 (from -r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2678442Z Using cached ansible_lint-26.3.0-py3-none-any.whl.metadata (6.2 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2841853Z Collecting ansible-compat>=25.8.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.2853515Z Using cached ansible_compat-25.12.1-py3-none-any.whl.metadata (3.4 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.3324507Z Collecting black>=24.3.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.3340053Z Using cached black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (88 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.4392554Z Collecting cffi>=1.15.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.4410566Z Using cached cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.6 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6020587Z Collecting cryptography>=37 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6039889Z Using cached cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (5.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6171492Z Collecting distro>=1.9.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6182889Z Using cached distro-1.9.0-py3-none-any.whl.metadata (6.8 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6342972Z Collecting filelock>=3.8.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6354454Z Using cached filelock-3.25.0-py3-none-any.whl.metadata (2.0 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6530994Z Collecting jsonschema>=4.10.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6542552Z Using cached jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6681268Z Collecting packaging>=22.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6693036Z Using cached packaging-26.0-py3-none-any.whl.metadata (3.3 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6782352Z Collecting pathspec<1.1.0,>=1.0.3 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.6793421Z Using cached pathspec-1.0.4-py3-none-any.whl.metadata (13 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.7114486Z Collecting pyyaml>=6.0.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.7127355Z Using cached pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.7288961Z Collecting referencing>=0.36.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.7300535Z Using cached referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8438693Z Collecting ruamel-yaml>=0.18.11 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8451054Z Using cached ruamel_yaml-0.19.1-py3-none-any.whl.metadata (16 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8808593Z Collecting ruamel-yaml-clib>=0.2.12 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8822030Z Using cached ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (3.5 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8919802Z Collecting subprocess-tee>=0.4.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.8931570Z Using cached subprocess_tee-0.4.2-py3-none-any.whl.metadata (3.3 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9056242Z Collecting wcmatch>=8.5.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9067895Z Using cached wcmatch-10.1-py3-none-any.whl.metadata (5.1 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9186855Z Collecting yamllint>=1.38.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9197893Z Using cached yamllint-1.38.0-py3-none-any.whl.metadata (4.2 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9318148Z Collecting jinja2>=3.1.0 (from ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9329139Z Using cached jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9434075Z Collecting resolvelib<2.0.0,>=0.5.3 (from ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9445494Z Using cached resolvelib-1.2.1-py3-none-any.whl.metadata (3.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9621498Z Collecting click>=8.0.0 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9632716Z Using cached click-8.3.1-py3-none-any.whl.metadata (2.6 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9715932Z Collecting mypy-extensions>=0.4.3 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9727321Z Using cached mypy_extensions-1.1.0-py3-none-any.whl.metadata (1.1 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9890085Z Collecting platformdirs>=2 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:19.9901303Z Using cached platformdirs-4.9.4-py3-none-any.whl.metadata (4.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0017127Z Collecting pytokens>=0.3.0 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0028577Z Using cached pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (3.8 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0121729Z Collecting pycparser (from cffi>=1.15.1->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0132684Z Using cached pycparser-3.0-py3-none-any.whl.metadata (8.2 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0616368Z Collecting MarkupSafe>=2.0 (from jinja2>=3.1.0->ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0628729Z Using cached markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.7 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0956111Z Collecting attrs>=22.2.0 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.0968028Z Using cached attrs-25.4.0-py3-none-any.whl.metadata (10 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.1071916Z Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.1087218Z Using cached jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3427391Z Collecting rpds-py>=0.25.0 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3441048Z Using cached rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3652689Z Collecting typing-extensions>=4.4.0 (from referencing>=0.36.2->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3664703Z Using cached typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3790215Z Collecting bracex>=2.1.1 (from wcmatch>=8.5.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3800941Z Using cached bracex-2.6-py3-none-any.whl.metadata (3.6 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3843568Z Using cached ansible_lint-26.3.0-py3-none-any.whl (330 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3857264Z Using cached ansible_core-2.19.7-py3-none-any.whl (2.4 MB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3886025Z Using cached pathspec-1.0.4-py3-none-any.whl (55 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3897085Z Using cached resolvelib-1.2.1-py3-none-any.whl (18 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3908164Z Using cached ansible_compat-25.12.1-py3-none-any.whl (27 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3919566Z Using cached black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3943377Z Using cached cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (219 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3955512Z Using cached click-8.3.1-py3-none-any.whl (108 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.3967497Z Using cached cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl (4.5 MB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4010695Z Using cached distro-1.9.0-py3-none-any.whl (20 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4021518Z Using cached filelock-3.25.0-py3-none-any.whl (26 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4032600Z Using cached jinja2-3.1.6-py3-none-any.whl (134 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4044242Z Using cached jsonschema-4.26.0-py3-none-any.whl (90 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4055630Z Using cached attrs-25.4.0-py3-none-any.whl (67 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4067265Z Using cached jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4078725Z Using cached markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (22 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4089307Z Using cached mypy_extensions-1.1.0-py3-none-any.whl (5.0 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4099989Z Using cached packaging-26.0-py3-none-any.whl (74 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4111364Z Using cached platformdirs-4.9.4-py3-none-any.whl (21 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4122788Z Using cached pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (269 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4135685Z Using cached pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4152160Z Using cached referencing-0.37.0-py3-none-any.whl (26 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4163610Z Using cached rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (394 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4177318Z Using cached ruamel_yaml-0.19.1-py3-none-any.whl (118 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4189476Z Using cached ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (788 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4205121Z Using cached subprocess_tee-0.4.2-py3-none-any.whl (5.2 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4216469Z Using cached typing_extensions-4.15.0-py3-none-any.whl (44 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4227263Z Using cached wcmatch-10.1-py3-none-any.whl (39 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4238042Z Using cached bracex-2.6-py3-none-any.whl (11 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4248958Z Using cached yamllint-1.38.0-py3-none-any.whl (68 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.4260046Z Using cached pycparser-3.0-py3-none-any.whl (48 kB) +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:20.5136341Z Installing collected packages: typing-extensions, subprocess-tee, ruamel-yaml-clib, ruamel-yaml, rpds-py, resolvelib, pyyaml, pytokens, pycparser, platformdirs, pathspec, packaging, mypy-extensions, MarkupSafe, filelock, distro, click, bracex, attrs, yamllint, wcmatch, referencing, jinja2, cffi, black, jsonschema-specifications, cryptography, jsonschema, ansible-core, ansible-compat, ansible-lint +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.1752917Z +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.1786289Z Successfully installed MarkupSafe-3.0.3 ansible-compat-25.12.1 ansible-core-2.19.7 ansible-lint-26.3.0 attrs-25.4.0 black-26.1.0 bracex-2.6 cffi-2.0.0 click-8.3.1 cryptography-46.0.5 distro-1.9.0 filelock-3.25.0 jinja2-3.1.6 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mypy-extensions-1.1.0 packaging-26.0 pathspec-1.0.4 platformdirs-4.9.4 pycparser-3.0 pytokens-0.4.1 pyyaml-6.0.3 referencing-0.37.0 resolvelib-1.2.1 rpds-py-0.30.0 ruamel-yaml-0.19.1 ruamel-yaml-clib-0.2.15 subprocess-tee-0.4.2 typing-extensions-4.15.0 wcmatch-10.1 yamllint-1.38.0 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3132093Z ##[group]Run set -euo pipefail +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3132406Z set -euo pipefail +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3132646Z . "ansible/.venv-ci/bin/activate" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3133042Z ansible-galaxy collection install -r "ansible/requirements.yml" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3182494Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3182814Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3182995Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3183248Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3183513Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3183785Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3184216Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3184628Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3185008Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3185717Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3186089Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:23.3186397Z ##[endgroup] +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.0929765Z Starting galaxy collection install process +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.0931533Z Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`. +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1336095Z ##[group]Run echo "/home/runner/work/DevOps-Core-S26/DevOps-Core-S26/ansible/.venv-ci/bin" >> "$GITHUB_PATH" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1336846Z echo "/home/runner/work/DevOps-Core-S26/DevOps-Core-S26/ansible/.venv-ci/bin" >> "$GITHUB_PATH" +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1385886Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1386212Z env: +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1386392Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1386668Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1386930Z DEPLOY_TAGS: app_deploy +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1387207Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1387607Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1388033Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1388398Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1388756Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1389121Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Setup Ansible toolchain 2026-03-06T05:29:24.1389428Z ##[endgroup] +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1511346Z Prepare all required actions +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1552577Z ##[group]Run ./.github/actions/ansible-lint +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1552839Z with: +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1553022Z ansible-directory: ansible +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1553378Z vault-password: *** +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1553613Z playbook-glob: playbooks/*.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1553834Z env: +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1554006Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1554240Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1554495Z DEPLOY_TAGS: app_deploy +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1554766Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1555562Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1555969Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1556338Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1556697Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1557060Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1557393Z ##[endgroup] +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1572559Z ##[group]Run set -euo pipefail +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1572828Z set -euo pipefail +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1573053Z umask 077 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1573263Z cleanup() { +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1573461Z  rm -f .vault_pass +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1573674Z } +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1573857Z trap cleanup EXIT +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1574064Z  +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1574274Z printf '%s\n' "$VAULT_PASSWORD" > .vault_pass +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1574564Z  +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1574750Z ansible-lint $PLAYBOOK_GLOB +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1575099Z ansible-playbook playbooks/provision.yml --syntax-check +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1575667Z ansible-playbook playbooks/deploy.yml --syntax-check +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1576063Z ansible-playbook playbooks/site.yml --syntax-check +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1619676Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1620023Z env: +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1620202Z ANSIBLE_DIRECTORY: ansible +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1620452Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1620726Z DEPLOY_TAGS: app_deploy +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1621008Z pythonLocation: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1621412Z PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib/pkgconfig +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1621812Z Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1622192Z Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1622568Z Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.12.12/x64 +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1622936Z LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.12.12/x64/lib +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1623292Z VAULT_PASSWORD: *** +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1623509Z PLAYBOOK_GLOB: playbooks/*.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:24.1623738Z ##[endgroup] +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:29.8477378Z +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:30.0769311Z Passed: 0 failure(s), 0 warning(s) in 9 files processed of 9 encountered. Profile 'production' was required, and it passed. +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:30.6324210Z +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:30.6324827Z playbook: playbooks/provision.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:31.1404326Z +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:31.1405013Z playbook: playbooks/deploy.yml +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:31.6590152Z +Ansible Lint Run lint and syntax checks 2026-03-06T05:29:31.6590785Z playbook: playbooks/site.yml +Ansible Lint Post Setup Ansible toolchain 2026-03-06T05:29:31.7061977Z Post job cleanup. +Ansible Lint Post Setup Ansible toolchain 2026-03-06T05:29:31.7645652Z Post job cleanup. +Ansible Lint Post Setup Ansible toolchain 2026-03-06T05:29:31.8932691Z Cache hit occurred on the primary key Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364, not saving cache. +Ansible Lint Post Setup Ansible toolchain 2026-03-06T05:29:31.9026958Z Post job cleanup. +Ansible Lint Post Checkout code 2026-03-06T05:29:32.0691853Z Post job cleanup. +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1650325Z [command]/usr/bin/git version +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1687355Z git version 2.53.0 +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1730032Z Temporarily overriding HOME='/home/runner/work/_temp/6c20ae22-94d6-4e20-a088-1bc5b65e29e6' before making global git config changes +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1731346Z Adding repository directory to the temporary git global config as a safe directory +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1744172Z [command]/usr/bin/git config --global --add safe.directory /home/runner/work/DevOps-Core-S26/DevOps-Core-S26 +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1779165Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand +Ansible Lint Post Checkout code 2026-03-06T05:29:32.1812297Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2056254Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2077494Z http.https://github.com/.extraheader +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2089800Z [command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2121225Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2357989Z [command]/usr/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +Ansible Lint Post Checkout code 2026-03-06T05:29:32.2390371Z [command]/usr/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +Ansible Lint Complete job 2026-03-06T05:29:32.2730379Z Cleaning up orphan processes +Deploy Application Set up job 2026-03-06T05:29:57.6492178Z Current runner version: '2.332.0' +Deploy Application Set up job 2026-03-06T05:29:57.6500080Z Runner name: 'github-runner-s26' +Deploy Application Set up job 2026-03-06T05:29:57.6501133Z Runner group name: 'Default' +Deploy Application Set up job 2026-03-06T05:29:57.6502174Z Machine name: 'github-runner-s26' +Deploy Application Set up job 2026-03-06T05:29:57.6505769Z ##[group]GITHUB_TOKEN Permissions +Deploy Application Set up job 2026-03-06T05:29:57.6508764Z Contents: read +Deploy Application Set up job 2026-03-06T05:29:57.6509511Z Metadata: read +Deploy Application Set up job 2026-03-06T05:29:57.6510335Z ##[endgroup] +Deploy Application Set up job 2026-03-06T05:29:57.6513654Z Secret source: Actions +Deploy Application Set up job 2026-03-06T05:29:57.6514727Z Prepare workflow directory +Deploy Application Set up job 2026-03-06T05:29:57.6992670Z Prepare all required actions +Deploy Application Set up job 2026-03-06T05:29:57.7029327Z Getting action download info +Deploy Application Set up job 2026-03-06T05:29:58.7100830Z Download action repository 'actions/checkout@v4' (SHA:34e114876b0b11c390a56381ad16ebd13914f8d5) +Deploy Application Set up job 2026-03-06T05:29:59.9331090Z Download action repository 'actions/upload-artifact@v4' (SHA:ea165f8d65b6e75b540449e92b4886f43607fa02) +Deploy Application Set up job 2026-03-06T05:30:04.4739595Z Complete job name: Deploy Application +Deploy Application Checkout code 2026-03-06T05:30:04.5258726Z ##[group]Run actions/checkout@v4 +Deploy Application Checkout code 2026-03-06T05:30:04.5259351Z with: +Deploy Application Checkout code 2026-03-06T05:30:04.5259658Z repository: LocalT0aster/DevOps-Core-S26 +Deploy Application Checkout code 2026-03-06T05:30:04.5260233Z token: *** +Deploy Application Checkout code 2026-03-06T05:30:04.5260506Z ssh-strict: true +Deploy Application Checkout code 2026-03-06T05:30:04.5260779Z ssh-user: git +Deploy Application Checkout code 2026-03-06T05:30:04.5261051Z persist-credentials: true +Deploy Application Checkout code 2026-03-06T05:30:04.5261350Z clean: true +Deploy Application Checkout code 2026-03-06T05:30:04.5261712Z sparse-checkout-cone-mode: true +Deploy Application Checkout code 2026-03-06T05:30:04.5283182Z fetch-depth: 1 +Deploy Application Checkout code 2026-03-06T05:30:04.5283514Z fetch-tags: false +Deploy Application Checkout code 2026-03-06T05:30:04.5283905Z show-progress: true +Deploy Application Checkout code 2026-03-06T05:30:04.5284216Z lfs: false +Deploy Application Checkout code 2026-03-06T05:30:04.5284495Z submodules: false +Deploy Application Checkout code 2026-03-06T05:30:04.5284768Z set-safe-directory: true +Deploy Application Checkout code 2026-03-06T05:30:04.5285558Z env: +Deploy Application Checkout code 2026-03-06T05:30:04.5285829Z ANSIBLE_DIRECTORY: ansible +Deploy Application Checkout code 2026-03-06T05:30:04.5286151Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Checkout code 2026-03-06T05:30:04.5286485Z DEPLOY_TAGS: app_deploy +Deploy Application Checkout code 2026-03-06T05:30:04.5286765Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:04.6162086Z Syncing repository: LocalT0aster/DevOps-Core-S26 +Deploy Application Checkout code 2026-03-06T05:30:04.6172832Z ##[group]Getting Git version info +Deploy Application Checkout code 2026-03-06T05:30:04.6173515Z Working directory is '/opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26' +Deploy Application Checkout code 2026-03-06T05:30:04.6174360Z [command]/usr/bin/git version +Deploy Application Checkout code 2026-03-06T05:30:04.6174679Z git version 2.52.0 +Deploy Application Checkout code 2026-03-06T05:30:04.6189251Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:04.6201711Z Temporarily overriding HOME='/opt/actions-runner/_work/_temp/02e2583d-1f43-4511-ab95-a17dab0dc139' before making global git config changes +Deploy Application Checkout code 2026-03-06T05:30:04.6202668Z Adding repository directory to the temporary git global config as a safe directory +Deploy Application Checkout code 2026-03-06T05:30:04.6226851Z [command]/usr/bin/git config --global --add safe.directory /opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26 +Deploy Application Checkout code 2026-03-06T05:30:04.6268709Z [command]/usr/bin/git config --local --get remote.origin.url +Deploy Application Checkout code 2026-03-06T05:30:04.6289926Z https://github.com/LocalT0aster/DevOps-Core-S26 +Deploy Application Checkout code 2026-03-06T05:30:04.6302713Z ##[group]Removing previously created refs, to avoid conflicts +Deploy Application Checkout code 2026-03-06T05:30:04.6306437Z [command]/usr/bin/git rev-parse --symbolic-full-name --verify --quiet HEAD +Deploy Application Checkout code 2026-03-06T05:30:04.6335472Z refs/heads/lab06 +Deploy Application Checkout code 2026-03-06T05:30:04.6360933Z [command]/usr/bin/git checkout --detach +Deploy Application Checkout code 2026-03-06T05:30:04.6361427Z HEAD is now at a55c6b2 fix: rebuild ansible ci venv on each run +Deploy Application Checkout code 2026-03-06T05:30:04.6399727Z [command]/usr/bin/git branch --delete --force lab06 +Deploy Application Checkout code 2026-03-06T05:30:04.6419714Z Deleted branch lab06 (was a55c6b2). +Deploy Application Checkout code 2026-03-06T05:30:04.6444500Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:04.6447185Z [command]/usr/bin/git submodule status +Deploy Application Checkout code 2026-03-06T05:30:04.6599060Z ##[group]Cleaning the repository +Deploy Application Checkout code 2026-03-06T05:30:04.6599701Z [command]/usr/bin/git clean -ffdx +Deploy Application Checkout code 2026-03-06T05:30:04.7382400Z Removing ansible/.venv-ci/ +Deploy Application Checkout code 2026-03-06T05:30:04.7399074Z [command]/usr/bin/git reset --hard HEAD +Deploy Application Checkout code 2026-03-06T05:30:04.7435602Z HEAD is now at a55c6b2 fix: rebuild ansible ci venv on each run +Deploy Application Checkout code 2026-03-06T05:30:04.7439527Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:04.7441304Z ##[group]Disabling automatic garbage collection +Deploy Application Checkout code 2026-03-06T05:30:04.7446972Z [command]/usr/bin/git config --local gc.auto 0 +Deploy Application Checkout code 2026-03-06T05:30:04.7478554Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:04.7479110Z ##[group]Setting up auth +Deploy Application Checkout code 2026-03-06T05:30:04.7486602Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand +Deploy Application Checkout code 2026-03-06T05:30:04.7524555Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +Deploy Application Checkout code 2026-03-06T05:30:04.7696597Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +Deploy Application Checkout code 2026-03-06T05:30:04.7718808Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +Deploy Application Checkout code 2026-03-06T05:30:05.1868602Z [command]/usr/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +Deploy Application Checkout code 2026-03-06T05:30:05.1870199Z [command]/usr/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +Deploy Application Checkout code 2026-03-06T05:30:05.1871124Z [command]/usr/bin/git config --local http.https://github.com/.extraheader AUTHORIZATION: basic *** +Deploy Application Checkout code 2026-03-06T05:30:05.1871927Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:05.1872274Z ##[group]Fetching the repository +Deploy Application Checkout code 2026-03-06T05:30:05.1872929Z [command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +2492c7d27ac02a50f12e2ca7f51bc1d7882b8489:refs/remotes/origin/lab06 +Deploy Application Checkout code 2026-03-06T05:30:05.4238858Z From https://github.com/LocalT0aster/DevOps-Core-S26 +Deploy Application Checkout code 2026-03-06T05:30:05.4240195Z + a55c6b2...2492c7d 2492c7d27ac02a50f12e2ca7f51bc1d7882b8489 -> origin/lab06 (forced update) +Deploy Application Checkout code 2026-03-06T05:30:05.4253108Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:05.4253515Z ##[group]Determining the checkout info +Deploy Application Checkout code 2026-03-06T05:30:05.4253862Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:05.4254090Z [command]/usr/bin/git sparse-checkout disable +Deploy Application Checkout code 2026-03-06T05:30:05.4319076Z [command]/usr/bin/git config --local --unset-all extensions.worktreeConfig +Deploy Application Checkout code 2026-03-06T05:30:05.4355659Z ##[group]Checking out the ref +Deploy Application Checkout code 2026-03-06T05:30:05.4357258Z [command]/usr/bin/git checkout --progress --force -B lab06 refs/remotes/origin/lab06 +Deploy Application Checkout code 2026-03-06T05:30:05.4395770Z Warning: you are leaving 1 commit behind, not connected to +Deploy Application Checkout code 2026-03-06T05:30:05.4397071Z any of your branches: +Deploy Application Checkout code 2026-03-06T05:30:05.4397250Z +Deploy Application Checkout code 2026-03-06T05:30:05.4397372Z a55c6b2 fix: rebuild ansible ci venv on each run +Deploy Application Checkout code 2026-03-06T05:30:05.4397551Z +Deploy Application Checkout code 2026-03-06T05:30:05.4397727Z If you want to keep it by creating a new branch, this may be a good time +Deploy Application Checkout code 2026-03-06T05:30:05.4398006Z to do so with: +Deploy Application Checkout code 2026-03-06T05:30:05.4398107Z +Deploy Application Checkout code 2026-03-06T05:30:05.4398222Z git branch a55c6b2 +Deploy Application Checkout code 2026-03-06T05:30:05.4398368Z +Deploy Application Checkout code 2026-03-06T05:30:05.4401993Z Switched to a new branch 'lab06' +Deploy Application Checkout code 2026-03-06T05:30:05.4406524Z branch 'lab06' set up to track 'origin/lab06'. +Deploy Application Checkout code 2026-03-06T05:30:05.4409674Z ##[endgroup] +Deploy Application Checkout code 2026-03-06T05:30:05.4436197Z [command]/usr/bin/git log -1 --format=%H +Deploy Application Checkout code 2026-03-06T05:30:05.4451707Z 2492c7d27ac02a50f12e2ca7f51bc1d7882b8489 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:05.4663275Z Prepare all required actions +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:05.4663720Z Getting action download info +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:05.7487960Z Download action repository 'actions/setup-python@v5' (SHA:a26af69be951a213d495a4c3e4e4022e16d87065) +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:09.0415725Z Download action repository 'actions/cache@v4' (SHA:0057852bfaa89a56745cba8c7296529d2fc39830) +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5880420Z ##[group]Run ./.github/actions/ansible-setup +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5880698Z with: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5880863Z python-version: 3.12 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5881059Z working-directory: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5881319Z python-requirements-path: ansible/requirements-ci.txt +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5881672Z collection-requirements-path: ansible/requirements.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5881948Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5882110Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5882411Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5882818Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5883002Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5991311Z ##[group]Run actions/setup-python@v5 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5991626Z with: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5991785Z python-version: 3.12 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5991981Z check-latest: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5992382Z token: *** +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5992626Z update-environment: true +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5992839Z allow-prereleases: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5993026Z freethreaded: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5993367Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5993524Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5993726Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5993962Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.5994142Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7393979Z ##[group]Installed versions +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7434733Z Successfully set up CPython (3.12.13) +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7436487Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7957480Z ##[group]Run actions/cache@v4 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7957724Z with: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7957975Z path: ~/.cache/pip +Deploy Application Setup Ansible toolchain ~/.ansible/collections +Deploy Application Setup Ansible toolchain +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7958375Z key: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7958770Z restore-keys: Linux-py3.12-ansible- +Deploy Application Setup Ansible toolchain +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959012Z enableCrossOsArchive: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959210Z fail-on-cache-miss: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959399Z lookup-only: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959567Z save-always: false +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959726Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7959881Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7960079Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7960298Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7960561Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7960944Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7961317Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7961663Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7962001Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7962559Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:13.7963084Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:14.4043248Z Cache hit for: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:16.4773003Z Received 0 of 16876233 (0.0%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:17.4766920Z Received 0 of 16876233 (0.0%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:18.4769115Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:19.4773453Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:20.4771646Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:21.4765071Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:22.4774139Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:23.4776252Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:24.4785122Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:25.4782607Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:26.4783331Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:27.4786680Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:28.4791776Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:29.4805527Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:30.4799815Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:31.4800143Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:32.4799538Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:33.4800713Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:34.4799954Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:35.4798905Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:36.4805551Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:37.4820057Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:38.4819188Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:39.4827866Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:40.4828823Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:41.4833593Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:42.4832544Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:43.4837095Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:44.4843083Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:45.4846837Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:46.4855272Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:47.4858765Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:48.4860108Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:49.4862180Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:50.4867065Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:51.4866433Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:52.4864504Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:53.4860951Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:54.4862233Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:55.4862078Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:56.4862231Z Received 99017 of 16876233 (0.6%), 0.0 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:57.4862363Z Received 4293321 of 16876233 (25.4%), 0.1 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:58.4866137Z Received 4293321 of 16876233 (25.4%), 0.1 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:30:59.4877504Z Received 8487625 of 16876233 (50.3%), 0.2 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:00.4885835Z Received 8487625 of 16876233 (50.3%), 0.2 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:01.4890920Z Received 8487625 of 16876233 (50.3%), 0.2 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:02.4895700Z Received 8487625 of 16876233 (50.3%), 0.2 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:03.4901206Z Received 8487625 of 16876233 (50.3%), 0.2 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3205436Z Received 16876233 of 16876233 (100.0%), 0.3 MBs/sec +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3206066Z Cache Size: ~16 MB (16876233 B) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3225913Z [command]/usr/bin/tar -xf /opt/actions-runner/_work/_temp/2ef53ebd-2583-4392-acbe-fba664f93a07/cache.tzst -P -C /opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26 --use-compress-program unzstd +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3692804Z Cache restored successfully +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3761111Z Cache restored from key: Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3836550Z ##[group]Run set -euo pipefail +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3836883Z set -euo pipefail +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3837088Z rm -rf "ansible/.venv-ci" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3837324Z python -m venv "ansible/.venv-ci" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3837570Z . "ansible/.venv-ci/bin/activate" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3837812Z python -m pip install --upgrade pip +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3838110Z python -m pip install -r "ansible/requirements-ci.txt" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3850274Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3850741Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3850906Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3851125Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3851360Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3851632Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3852014Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3852397Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3852748Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3853097Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3853450Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:04.3853731Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:06.5334681Z Requirement already satisfied: pip in ./ansible/.venv-ci/lib/python3.12/site-packages (25.0.1) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9460353Z Collecting pip +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9471527Z Using cached pip-26.0.1-py3-none-any.whl.metadata (4.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9495739Z Using cached pip-26.0.1-py3-none-any.whl (1.8 MB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9631733Z Installing collected packages: pip +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9633426Z Attempting uninstall: pip +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9651606Z Found existing installation: pip 25.0.1 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9891716Z Uninstalling pip-25.0.1: +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:13.9931126Z Successfully uninstalled pip-25.0.1 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:14.6728555Z Successfully installed pip-26.0.1 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.2284637Z Collecting ansible-core<2.20,>=2.16 (from -r ansible/requirements-ci.txt (line 1)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.2295418Z Using cached ansible_core-2.19.7-py3-none-any.whl.metadata (7.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.3078820Z Collecting ansible-lint==26.3.0 (from -r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.3088678Z Using cached ansible_lint-26.3.0-py3-none-any.whl.metadata (6.2 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.3781496Z Collecting ansible-compat>=25.8.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.3790856Z Using cached ansible_compat-25.12.1-py3-none-any.whl.metadata (3.4 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.4707132Z Collecting black>=24.3.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.4716630Z Using cached black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (88 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.6128224Z Collecting cffi>=1.15.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.6137764Z Using cached cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.6 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.7927015Z Collecting cryptography>=37 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.7937012Z Using cached cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (5.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.8671128Z Collecting distro>=1.9.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.8682256Z Using cached distro-1.9.0-py3-none-any.whl.metadata (6.8 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.9373489Z Collecting filelock>=3.8.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:15.9386611Z Using cached filelock-3.25.0-py3-none-any.whl.metadata (2.0 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.0109744Z Collecting jsonschema>=4.10.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.0120324Z Using cached jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.0792137Z Collecting packaging>=22.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.0801561Z Using cached packaging-26.0-py3-none-any.whl.metadata (3.3 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.1437771Z Collecting pathspec<1.1.0,>=1.0.3 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.1452500Z Using cached pathspec-1.0.4-py3-none-any.whl.metadata (13 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.2274470Z Collecting pyyaml>=6.0.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.2288415Z Using cached pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.2980758Z Collecting referencing>=0.36.2 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.2990421Z Using cached referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.4413848Z Collecting ruamel-yaml>=0.18.11 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.4431007Z Using cached ruamel_yaml-0.19.1-py3-none-any.whl.metadata (16 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.5318734Z Collecting ruamel-yaml-clib>=0.2.12 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.5330098Z Using cached ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (3.5 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.5966352Z Collecting subprocess-tee>=0.4.1 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.5975349Z Using cached subprocess_tee-0.4.2-py3-none-any.whl.metadata (3.3 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.6638567Z Collecting wcmatch>=8.5.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.6651187Z Using cached wcmatch-10.1-py3-none-any.whl.metadata (5.1 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.7312397Z Collecting yamllint>=1.38.0 (from ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.7323026Z Using cached yamllint-1.38.0-py3-none-any.whl.metadata (4.2 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.7987117Z Collecting jinja2>=3.1.0 (from ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.7997263Z Using cached jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.8639164Z Collecting resolvelib<2.0.0,>=0.5.3 (from ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.8651084Z Using cached resolvelib-1.2.1-py3-none-any.whl.metadata (3.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.9362504Z Collecting click>=8.0.0 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:16.9375445Z Using cached click-8.3.1-py3-none-any.whl.metadata (2.6 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.0012448Z Collecting mypy-extensions>=0.4.3 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.0024237Z Using cached mypy_extensions-1.1.0-py3-none-any.whl.metadata (1.1 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.0715338Z Collecting platformdirs>=2 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.0726463Z Using cached platformdirs-4.9.4-py3-none-any.whl.metadata (4.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.1416270Z Collecting pytokens>=0.3.0 (from black>=24.3.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.1425142Z Using cached pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (3.8 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.2067636Z Collecting pycparser (from cffi>=1.15.1->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.2082912Z Using cached pycparser-3.0-py3-none-any.whl.metadata (8.2 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.3010526Z Collecting MarkupSafe>=2.0 (from jinja2>=3.1.0->ansible-core<2.20,>=2.16->-r ansible/requirements-ci.txt (line 1)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.3019786Z Using cached markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.7 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.4000818Z Collecting attrs>=22.2.0 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.4016296Z Using cached attrs-25.4.0-py3-none-any.whl.metadata (10 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.4695332Z Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.4707000Z Using cached jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.7147396Z Collecting rpds-py>=0.25.0 (from jsonschema>=4.10.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.7156027Z Using cached rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.7938498Z Collecting typing-extensions>=4.4.0 (from referencing>=0.36.2->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.7949097Z Using cached typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8610682Z Collecting bracex>=2.1.1 (from wcmatch>=8.5.0->ansible-lint==26.3.0->-r ansible/requirements-ci.txt (line 2)) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8620246Z Using cached bracex-2.6-py3-none-any.whl.metadata (3.6 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8657240Z Using cached ansible_lint-26.3.0-py3-none-any.whl (330 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8667064Z Using cached ansible_core-2.19.7-py3-none-any.whl (2.4 MB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8682968Z Using cached pathspec-1.0.4-py3-none-any.whl (55 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8690638Z Using cached resolvelib-1.2.1-py3-none-any.whl (18 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8698234Z Using cached ansible_compat-25.12.1-py3-none-any.whl (27 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8705759Z Using cached black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8718422Z Using cached cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (219 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8726345Z Using cached click-8.3.1-py3-none-any.whl (108 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8735000Z Using cached cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl (4.5 MB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8755686Z Using cached distro-1.9.0-py3-none-any.whl (20 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8763372Z Using cached filelock-3.25.0-py3-none-any.whl (26 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8770674Z Using cached jinja2-3.1.6-py3-none-any.whl (134 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8778285Z Using cached jsonschema-4.26.0-py3-none-any.whl (90 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8786395Z Using cached attrs-25.4.0-py3-none-any.whl (67 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8793893Z Using cached jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8801335Z Using cached markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (22 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8810007Z Using cached mypy_extensions-1.1.0-py3-none-any.whl (5.0 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8818082Z Using cached packaging-26.0-py3-none-any.whl (74 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8827093Z Using cached platformdirs-4.9.4-py3-none-any.whl (21 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8835125Z Using cached pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (269 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8843675Z Using cached pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (807 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8853576Z Using cached referencing-0.37.0-py3-none-any.whl (26 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8861708Z Using cached rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (394 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8870267Z Using cached ruamel_yaml-0.19.1-py3-none-any.whl (118 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8879101Z Using cached ruamel_yaml_clib-0.2.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (788 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8888596Z Using cached subprocess_tee-0.4.2-py3-none-any.whl (5.2 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8897105Z Using cached typing_extensions-4.15.0-py3-none-any.whl (44 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8905400Z Using cached wcmatch-10.1-py3-none-any.whl (39 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8912148Z Using cached bracex-2.6-py3-none-any.whl (11 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8920436Z Using cached yamllint-1.38.0-py3-none-any.whl (68 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.8929741Z Using cached pycparser-3.0-py3-none-any.whl (48 kB) +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:17.9681888Z Installing collected packages: typing-extensions, subprocess-tee, ruamel-yaml-clib, ruamel-yaml, rpds-py, resolvelib, pyyaml, pytokens, pycparser, platformdirs, pathspec, packaging, mypy-extensions, MarkupSafe, filelock, distro, click, bracex, attrs, yamllint, wcmatch, referencing, jinja2, cffi, black, jsonschema-specifications, cryptography, jsonschema, ansible-core, ansible-compat, ansible-lint +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.4801930Z +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.4827204Z Successfully installed MarkupSafe-3.0.3 ansible-compat-25.12.1 ansible-core-2.19.7 ansible-lint-26.3.0 attrs-25.4.0 black-26.1.0 bracex-2.6 cffi-2.0.0 click-8.3.1 cryptography-46.0.5 distro-1.9.0 filelock-3.25.0 jinja2-3.1.6 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 mypy-extensions-1.1.0 packaging-26.0 pathspec-1.0.4 platformdirs-4.9.4 pycparser-3.0 pytokens-0.4.1 pyyaml-6.0.3 referencing-0.37.0 resolvelib-1.2.1 rpds-py-0.30.0 ruamel-yaml-0.19.1 ruamel-yaml-clib-0.2.15 subprocess-tee-0.4.2 typing-extensions-4.15.0 wcmatch-10.1 yamllint-1.38.0 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7108789Z ##[group]Run set -euo pipefail +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7109088Z set -euo pipefail +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7109301Z . "ansible/.venv-ci/bin/activate" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7109613Z ansible-galaxy collection install -r "ansible/requirements.yml" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7118701Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7118978Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7119140Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7119362Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7119585Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7119866Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7120262Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7120665Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7121032Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7121412Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7121795Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.7122083Z ##[endgroup] +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.8582727Z [WARNING]: Deprecation warnings can be disabled by setting `deprecation_warnings=False` in ansible.cfg. +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.8585490Z [DEPRECATION WARNING]: DEFAULT_MANAGED_STR option. Reason: The `ansible_managed` variable can be set just like any other variable, or a different variable can be used. +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.8586598Z Alternatives: Set the `ansible_managed` variable, or use any custom variable in templates. This feature will be removed from ansible-core version 2.23. +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:20.8587575Z +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.0412152Z Starting galaxy collection install process +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.0413773Z Nothing to do. All requested collections are already installed. If you want to reinstall them, consider using `--force`. +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1165007Z ##[group]Run echo "/opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26/ansible/.venv-ci/bin" >> "$GITHUB_PATH" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1165671Z echo "/opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26/ansible/.venv-ci/bin" >> "$GITHUB_PATH" +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1174955Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1175220Z env: +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1175388Z ANSIBLE_DIRECTORY: ansible +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1175598Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1175823Z DEPLOY_TAGS: app_deploy +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1176090Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1176475Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1176862Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1177206Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1177576Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1177923Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Setup Ansible toolchain 2026-03-06T05:31:21.1178380Z ##[endgroup] +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1279754Z ##[group]Run set -euo pipefail +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1280229Z set -euo pipefail +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1280543Z target_host="$( +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1280903Z  awk ' +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1281137Z  /^[[:space:]]*#/ { next } +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1281415Z  /^\[/ { next } +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1281695Z  NF { +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1281992Z  for (i = 1; i <= NF; i++) { +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1282367Z  if ($i ~ /^ansible_host=/) { +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1282691Z  split($i, value, "=") +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1283073Z  print value[2] +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1283403Z  exit +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1283692Z  } +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1284191Z  } +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1284449Z  } +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1284725Z  ' inventory/hosts.ini +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1285173Z )" +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1285419Z  +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1285729Z if [ -z "$target_host" ]; then +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1286258Z  echo "Could not determine ansible_host from inventory/hosts.ini" >&2 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1286775Z  exit 1 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1287030Z fi +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1287277Z  +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1287612Z echo "TARGET_VM_HOST=$target_host" >> "$GITHUB_ENV" +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1304058Z shell: /usr/bin/bash -e {0} +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1304401Z env: +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1304663Z ANSIBLE_DIRECTORY: ansible +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1305177Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1305563Z DEPLOY_TAGS: app_deploy +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1305969Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1306624Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1307275Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1307883Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1308559Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1309167Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Resolve target host from inventory 2026-03-06T05:31:21.1309639Z ##[endgroup] +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1398964Z Prepare all required actions +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1425869Z ##[group]Run ./.github/actions/ansible-ssh-setup +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1426139Z with: +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1427741Z ssh-private-key: *** +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1427946Z known-host: 192.168.121.50 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1428487Z ssh-key-path: ~/.ssh/vagrant +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1428672Z env: +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1428876Z ANSIBLE_DIRECTORY: ansible +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1429141Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1429488Z DEPLOY_TAGS: app_deploy +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1430020Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1430557Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1431104Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1431573Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1432190Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1432833Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1433368Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1433635Z ##[endgroup] +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1450702Z ##[group]Run set -euo pipefail +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1451087Z set -euo pipefail +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1451359Z  +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1451627Z key_path="${SSH_KEY_PATH/#\~/$HOME}" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1451990Z  +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1452214Z install -d -m 700 "$HOME/.ssh" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1452546Z install -d -m 700 "$(dirname "$key_path")" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1452831Z printf '%s\n' "$SSH_PRIVATE_KEY" > "$key_path" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1453085Z chmod 600 "$key_path" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1453270Z  +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1453450Z touch "$HOME/.ssh/known_hosts" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1453777Z chmod 600 "$HOME/.ssh/known_hosts" +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1453991Z  +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1454160Z if [ -n "$KNOWN_HOST" ]; then +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1454476Z  ssh-keyscan -H "$KNOWN_HOST" >> "$HOME/.ssh/known_hosts" 2>/dev/null || true +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1454781Z fi +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1464672Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1465104Z env: +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1465271Z ANSIBLE_DIRECTORY: ansible +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1465655Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1465883Z DEPLOY_TAGS: app_deploy +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1466159Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1466572Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1466981Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1467375Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1467736Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1468184Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1468502Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1470330Z SSH_PRIVATE_KEY: *** +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1470552Z SSH_KEY_PATH: ~/.ssh/vagrant +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1470761Z KNOWN_HOST: 192.168.121.50 +Deploy Application Configure SSH access to the target VM 2026-03-06T05:31:21.1470958Z ##[endgroup] +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3636008Z ##[group]Run set -euo pipefail +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3636331Z set -euo pipefail +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3636526Z umask 077 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3636742Z printf '%s\n' "$VAULT_PASSWORD" > .vault_pass +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3647110Z shell: /usr/bin/bash -e {0} +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3647418Z env: +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3647583Z ANSIBLE_DIRECTORY: ansible +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3647796Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3648097Z DEPLOY_TAGS: app_deploy +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3648379Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3648795Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3649207Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3649583Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3650192Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3650901Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3651195Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3651681Z VAULT_PASSWORD: *** +Deploy Application Prepare vault password file 2026-03-06T05:31:21.3651864Z ##[endgroup] +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3715635Z ##[group]Run ansible webservers -m ansible.builtin.ping +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3716023Z ansible webservers -m ansible.builtin.ping +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3725398Z shell: /usr/bin/bash -e {0} +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3725623Z env: +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3725787Z ANSIBLE_DIRECTORY: ansible +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3726022Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3726262Z DEPLOY_TAGS: app_deploy +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3726550Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3726964Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3727372Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3727847Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3728334Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3728701Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3729032Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Verify target connectivity 2026-03-06T05:31:21.3729236Z ##[endgroup] +Deploy Application Verify target connectivity 2026-03-06T05:31:22.7085708Z vagrant | SUCCESS => { +Deploy Application Verify target connectivity 2026-03-06T05:31:22.7086542Z "changed": false, +Deploy Application Verify target connectivity 2026-03-06T05:31:22.7086737Z "ping": "pong" +Deploy Application Verify target connectivity 2026-03-06T05:31:22.7086919Z } +Deploy Application Deploy web application 2026-03-06T05:31:22.7740839Z Prepare all required actions +Deploy Application Deploy web application 2026-03-06T05:31:22.7772377Z ##[group]Run ./.github/actions/ansible-deploy +Deploy Application Deploy web application 2026-03-06T05:31:22.7772622Z with: +Deploy Application Deploy web application 2026-03-06T05:31:22.7772795Z ansible-directory: ansible +Deploy Application Deploy web application 2026-03-06T05:31:22.7773016Z playbook-path: playbooks/deploy.yml +Deploy Application Deploy web application 2026-03-06T05:31:22.7773339Z vault-password: *** +Deploy Application Deploy web application 2026-03-06T05:31:22.7773529Z tags: app_deploy +Deploy Application Deploy web application 2026-03-06T05:31:22.7773717Z inventory-path: inventory/hosts.ini +Deploy Application Deploy web application 2026-03-06T05:31:22.7774033Z env: +Deploy Application Deploy web application 2026-03-06T05:31:22.7774189Z ANSIBLE_DIRECTORY: ansible +Deploy Application Deploy web application 2026-03-06T05:31:22.7774391Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Deploy web application 2026-03-06T05:31:22.7774667Z DEPLOY_TAGS: app_deploy +Deploy Application Deploy web application 2026-03-06T05:31:22.7775068Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7775475Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Deploy web application 2026-03-06T05:31:22.7775860Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7776208Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7776600Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7776974Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Deploy web application 2026-03-06T05:31:22.7777285Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Deploy web application 2026-03-06T05:31:22.7777521Z ##[endgroup] +Deploy Application Deploy web application 2026-03-06T05:31:22.7789074Z ##[group]Run set -euo pipefail +Deploy Application Deploy web application 2026-03-06T05:31:22.7789339Z set -euo pipefail +Deploy Application Deploy web application 2026-03-06T05:31:22.7789542Z umask 077 +Deploy Application Deploy web application 2026-03-06T05:31:22.7789713Z  +Deploy Application Deploy web application 2026-03-06T05:31:22.7789906Z log_path="${RUNNER_TEMP}/ansible-deploy.log" +Deploy Application Deploy web application 2026-03-06T05:31:22.7790139Z  +Deploy Application Deploy web application 2026-03-06T05:31:22.7790294Z cleanup() { +Deploy Application Deploy web application 2026-03-06T05:31:22.7790472Z  rm -f .vault_pass +Deploy Application Deploy web application 2026-03-06T05:31:22.7790651Z } +Deploy Application Deploy web application 2026-03-06T05:31:22.7790808Z trap cleanup EXIT +Deploy Application Deploy web application 2026-03-06T05:31:22.7790990Z  +Deploy Application Deploy web application 2026-03-06T05:31:22.7791180Z printf '%s\n' "$VAULT_PASSWORD" > .vault_pass +Deploy Application Deploy web application 2026-03-06T05:31:22.7791419Z  +Deploy Application Deploy web application 2026-03-06T05:31:22.7791726Z ansible-playbook "$PLAYBOOK_PATH" -i "$INVENTORY_PATH" --tags "$PLAYBOOK_TAGS" | tee "$log_path" +Deploy Application Deploy web application 2026-03-06T05:31:22.7792091Z  +Deploy Application Deploy web application 2026-03-06T05:31:22.7792278Z echo "log-path=$log_path" >> "$GITHUB_OUTPUT" +Deploy Application Deploy web application 2026-03-06T05:31:22.7802395Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Deploy web application 2026-03-06T05:31:22.7802669Z env: +Deploy Application Deploy web application 2026-03-06T05:31:22.7802840Z ANSIBLE_DIRECTORY: ansible +Deploy Application Deploy web application 2026-03-06T05:31:22.7803059Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Deploy web application 2026-03-06T05:31:22.7803284Z DEPLOY_TAGS: app_deploy +Deploy Application Deploy web application 2026-03-06T05:31:22.7803560Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7803946Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Deploy web application 2026-03-06T05:31:22.7804328Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7804676Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7805109Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Deploy web application 2026-03-06T05:31:22.7805452Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Deploy web application 2026-03-06T05:31:22.7805733Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Deploy web application 2026-03-06T05:31:22.7806020Z VAULT_PASSWORD: *** +Deploy Application Deploy web application 2026-03-06T05:31:22.7806213Z PLAYBOOK_PATH: playbooks/deploy.yml +Deploy Application Deploy web application 2026-03-06T05:31:22.7806433Z INVENTORY_PATH: inventory/hosts.ini +Deploy Application Deploy web application 2026-03-06T05:31:22.7806651Z PLAYBOOK_TAGS: app_deploy +Deploy Application Deploy web application 2026-03-06T05:31:22.7806832Z ##[endgroup] +Deploy Application Deploy web application 2026-03-06T05:31:23.1853694Z +Deploy Application Deploy web application 2026-03-06T05:31:23.1855725Z PLAY [Deploy application] ****************************************************** +Deploy Application Deploy web application 2026-03-06T05:31:23.1870137Z +Deploy Application Deploy web application 2026-03-06T05:31:23.1871854Z TASK [Gathering Facts] ********************************************************* +Deploy Application Deploy web application 2026-03-06T05:31:24.1988353Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:24.1991083Z +Deploy Application Deploy web application 2026-03-06T05:31:24.1991421Z TASK [Run web app role] ******************************************************** +Deploy Application Deploy web application 2026-03-06T05:31:24.2774549Z included: web_app for vagrant +Deploy Application Deploy web application 2026-03-06T05:31:24.2777912Z +Deploy Application Deploy web application 2026-03-06T05:31:24.2778295Z TASK [docker : Load docker role defaults] ************************************** +Deploy Application Deploy web application 2026-03-06T05:31:24.3006960Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:24.3007239Z +Deploy Application Deploy web application 2026-03-06T05:31:24.3007555Z TASK [docker : Install Docker prerequisites] *********************************** +Deploy Application Deploy web application 2026-03-06T05:31:37.6684351Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:37.6685233Z +Deploy Application Deploy web application 2026-03-06T05:31:37.6685698Z TASK [docker : Ensure Docker keyring directory exists] ************************* +Deploy Application Deploy web application 2026-03-06T05:31:38.0194162Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:38.0195223Z +Deploy Application Deploy web application 2026-03-06T05:31:38.0195503Z TASK [docker : Add Docker GPG key] ********************************************* +Deploy Application Deploy web application 2026-03-06T05:31:38.6477382Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:38.6478060Z +Deploy Application Deploy web application 2026-03-06T05:31:38.6478249Z TASK [docker : Add Docker apt repository] ************************************** +Deploy Application Deploy web application 2026-03-06T05:31:39.0961629Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:39.0962379Z +Deploy Application Deploy web application 2026-03-06T05:31:39.0962593Z TASK [docker : Install Docker engine packages] ********************************* +Deploy Application Deploy web application 2026-03-06T05:31:39.9038774Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:39.9039596Z +Deploy Application Deploy web application 2026-03-06T05:31:39.9039935Z TASK [docker : Install Docker Python SDK package] ****************************** +Deploy Application Deploy web application 2026-03-06T05:31:40.7113465Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:40.7114301Z +Deploy Application Deploy web application 2026-03-06T05:31:40.7114984Z TASK [docker : Mark Docker service as ready] *********************************** +Deploy Application Deploy web application 2026-03-06T05:31:40.7248008Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:40.7248187Z +Deploy Application Deploy web application 2026-03-06T05:31:40.7248370Z TASK [docker : Ensure Docker service is enabled and running] ******************* +Deploy Application Deploy web application 2026-03-06T05:31:41.2950461Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:41.2951270Z +Deploy Application Deploy web application 2026-03-06T05:31:41.2951998Z TASK [docker : Record Docker installation block completion] ******************** +Deploy Application Deploy web application 2026-03-06T05:31:41.6671862Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:41.6672474Z +Deploy Application Deploy web application 2026-03-06T05:31:41.6672884Z TASK [docker : Add deployment user to docker group] **************************** +Deploy Application Deploy web application 2026-03-06T05:31:42.1253486Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:42.1253807Z +Deploy Application Deploy web application 2026-03-06T05:31:42.1254165Z TASK [docker : Record Docker configuration block completion] ******************* +Deploy Application Deploy web application 2026-03-06T05:31:42.4014420Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:42.4015201Z +Deploy Application Deploy web application 2026-03-06T05:31:42.4015690Z TASK [web_app : Include web app wipe tasks] ************************************ +Deploy Application Deploy web application 2026-03-06T05:31:42.4227650Z included: /opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26/ansible/roles/web_app/tasks/wipe.yml for vagrant +Deploy Application Deploy web application 2026-03-06T05:31:42.4229296Z +Deploy Application Deploy web application 2026-03-06T05:31:42.4230444Z TASK [web_app : Log in to Docker Hub when credentials are available] *********** +Deploy Application Deploy web application 2026-03-06T05:31:43.0978245Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:43.0985222Z +Deploy Application Deploy web application 2026-03-06T05:31:43.0986015Z TASK [web_app : Ensure Compose project directory exists] *********************** +Deploy Application Deploy web application 2026-03-06T05:31:43.3761498Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:43.3761774Z +Deploy Application Deploy web application 2026-03-06T05:31:43.3762026Z TASK [web_app : Check for legacy standalone container] ************************* +Deploy Application Deploy web application 2026-03-06T05:31:44.0326329Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:44.0326547Z +Deploy Application Deploy web application 2026-03-06T05:31:44.0326808Z TASK [web_app : Remove legacy standalone container before Compose migration] *** +Deploy Application Deploy web application 2026-03-06T05:31:44.0522208Z skipping: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:44.0522462Z +Deploy Application Deploy web application 2026-03-06T05:31:44.0522727Z TASK [web_app : Template Docker Compose configuration] ************************* +Deploy Application Deploy web application 2026-03-06T05:31:44.6914512Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:44.6915400Z +Deploy Application Deploy web application 2026-03-06T05:31:44.6915611Z TASK [web_app : Deploy application stack with Docker Compose] ****************** +Deploy Application Deploy web application 2026-03-06T05:31:47.5675136Z ok: [vagrant] +Deploy Application Deploy web application 2026-03-06T05:31:47.5675772Z +Deploy Application Deploy web application 2026-03-06T05:31:47.5675983Z TASK [web_app : Wait for application port] ************************************* +Deploy Application Deploy web application 2026-03-06T05:31:48.8916776Z ok: [vagrant -> localhost] +Deploy Application Deploy web application 2026-03-06T05:31:48.8917460Z +Deploy Application Deploy web application 2026-03-06T05:31:48.8917655Z TASK [web_app : Verify application health endpoint] **************************** +Deploy Application Deploy web application 2026-03-06T05:31:49.3035774Z ok: [vagrant -> localhost] +Deploy Application Deploy web application 2026-03-06T05:31:49.3035978Z +Deploy Application Deploy web application 2026-03-06T05:31:49.3036114Z PLAY RECAP ********************************************************************* +Deploy Application Deploy web application 2026-03-06T05:31:49.3036827Z vagrant : ok=22 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 +Deploy Application Deploy web application 2026-03-06T05:31:49.3037103Z +Deploy Application Upload deployment log 2026-03-06T05:31:49.3876767Z ##[group]Run actions/upload-artifact@v4 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3877027Z with: +Deploy Application Upload deployment log 2026-03-06T05:31:49.3877263Z name: ansible-deploy-log +Deploy Application Upload deployment log 2026-03-06T05:31:49.3877536Z path: /opt/actions-runner/_work/_temp/ansible-deploy.log +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878027Z if-no-files-found: warn +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878218Z compression-level: 6 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878406Z overwrite: false +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878581Z include-hidden-files: false +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878774Z env: +Deploy Application Upload deployment log 2026-03-06T05:31:49.3878941Z ANSIBLE_DIRECTORY: ansible +Deploy Application Upload deployment log 2026-03-06T05:31:49.3879148Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Upload deployment log 2026-03-06T05:31:49.3879366Z DEPLOY_TAGS: app_deploy +Deploy Application Upload deployment log 2026-03-06T05:31:49.3879620Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3879995Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Upload deployment log 2026-03-06T05:31:49.3880380Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3880717Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3881090Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3881522Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Upload deployment log 2026-03-06T05:31:49.3881932Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Upload deployment log 2026-03-06T05:31:49.3882178Z ##[endgroup] +Deploy Application Upload deployment log 2026-03-06T05:31:49.5697737Z With the provided path, there will be 1 file uploaded +Deploy Application Upload deployment log 2026-03-06T05:31:49.5700524Z Artifact name is valid! +Deploy Application Upload deployment log 2026-03-06T05:31:49.5701410Z Root directory input is valid! +Deploy Application Upload deployment log 2026-03-06T05:31:50.0726944Z Beginning upload of artifact content to blob storage +Deploy Application Upload deployment log 2026-03-06T05:31:51.2153751Z Uploaded bytes 808 +Deploy Application Upload deployment log 2026-03-06T05:31:51.4759396Z Finished uploading artifact content to blob storage! +Deploy Application Upload deployment log 2026-03-06T05:31:51.4765601Z SHA256 digest of uploaded artifact zip is f81eaa1099002b69ff9e2cbf817f9266dd7ccfa0569af8cc9456757ad35a79e2 +Deploy Application Upload deployment log 2026-03-06T05:31:51.4766682Z Finalizing artifact upload +Deploy Application Upload deployment log 2026-03-06T05:31:51.7819447Z Artifact ansible-deploy-log.zip successfully finalized. Artifact ID 5792366004 +Deploy Application Upload deployment log 2026-03-06T05:31:51.7820077Z Artifact ansible-deploy-log has been successfully uploaded! Final size is 808 bytes. Artifact ID is 5792366004 +Deploy Application Upload deployment log 2026-03-06T05:31:51.7825632Z Artifact download URL: https://github.com/LocalT0aster/DevOps-Core-S26/actions/runs/22750506418/artifacts/5792366004 +Deploy Application Verify application health 2026-03-06T05:31:51.7906094Z Prepare all required actions +Deploy Application Verify application health 2026-03-06T05:31:51.7945544Z ##[group]Run ./.github/actions/http-healthcheck +Deploy Application Verify application health 2026-03-06T05:31:51.7945786Z with: +Deploy Application Verify application health 2026-03-06T05:31:51.7946000Z url: http://192.168.121.50:5000/health +Deploy Application Verify application health 2026-03-06T05:31:51.7946378Z retries: 10 +Deploy Application Verify application health 2026-03-06T05:31:51.7946541Z delay-seconds: 3 +Deploy Application Verify application health 2026-03-06T05:31:51.7946722Z jq-filter: .status == "healthy" +Deploy Application Verify application health 2026-03-06T05:31:51.7946918Z env: +Deploy Application Verify application health 2026-03-06T05:31:51.7947078Z ANSIBLE_DIRECTORY: ansible +Deploy Application Verify application health 2026-03-06T05:31:51.7947283Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Verify application health 2026-03-06T05:31:51.7947503Z DEPLOY_TAGS: app_deploy +Deploy Application Verify application health 2026-03-06T05:31:51.7947798Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7948210Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Verify application health 2026-03-06T05:31:51.7948588Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7948946Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7949312Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7949683Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Verify application health 2026-03-06T05:31:51.7949992Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Verify application health 2026-03-06T05:31:51.7950188Z ##[endgroup] +Deploy Application Verify application health 2026-03-06T05:31:51.7961664Z ##[group]Run set -euo pipefail +Deploy Application Verify application health 2026-03-06T05:31:51.7961940Z set -euo pipefail +Deploy Application Verify application health 2026-03-06T05:31:51.7962141Z  +Deploy Application Verify application health 2026-03-06T05:31:51.7962297Z response="" +Deploy Application Verify application health 2026-03-06T05:31:51.7962468Z  +Deploy Application Verify application health 2026-03-06T05:31:51.7962651Z for attempt in $(seq 1 "$RETRIES"); do +Deploy Application Verify application health 2026-03-06T05:31:51.7962922Z  if response="$(curl -fsSL "$URL")"; then +Deploy Application Verify application health 2026-03-06T05:31:51.7963152Z  break +Deploy Application Verify application health 2026-03-06T05:31:51.7963325Z  fi +Deploy Application Verify application health 2026-03-06T05:31:51.7963477Z  +Deploy Application Verify application health 2026-03-06T05:31:51.7963665Z  if [ "$attempt" -eq "$RETRIES" ]; then +Deploy Application Verify application health 2026-03-06T05:31:51.7964155Z  echo "Health check failed after $RETRIES attempts: $URL" >&2 +Deploy Application Verify application health 2026-03-06T05:31:51.7964541Z  exit 1 +Deploy Application Verify application health 2026-03-06T05:31:51.7964803Z  fi +Deploy Application Verify application health 2026-03-06T05:31:51.7965062Z  +Deploy Application Verify application health 2026-03-06T05:31:51.7965263Z  sleep "$DELAY_SECONDS" +Deploy Application Verify application health 2026-03-06T05:31:51.7965467Z done +Deploy Application Verify application health 2026-03-06T05:31:51.7965619Z  +Deploy Application Verify application health 2026-03-06T05:31:51.7965778Z echo "$response" | jq . +Deploy Application Verify application health 2026-03-06T05:31:51.7966048Z echo "$response" | jq -e "$JQ_FILTER" >/dev/null +Deploy Application Verify application health 2026-03-06T05:31:51.7975984Z shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} +Deploy Application Verify application health 2026-03-06T05:31:51.7976317Z env: +Deploy Application Verify application health 2026-03-06T05:31:51.7976490Z ANSIBLE_DIRECTORY: ansible +Deploy Application Verify application health 2026-03-06T05:31:51.7976706Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Verify application health 2026-03-06T05:31:51.7977112Z DEPLOY_TAGS: app_deploy +Deploy Application Verify application health 2026-03-06T05:31:51.7977471Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7977899Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Verify application health 2026-03-06T05:31:51.7978322Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7978707Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7979071Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Verify application health 2026-03-06T05:31:51.7979436Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Verify application health 2026-03-06T05:31:51.7979733Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Verify application health 2026-03-06T05:31:51.7979968Z URL: http://192.168.121.50:5000/health +Deploy Application Verify application health 2026-03-06T05:31:51.7980186Z RETRIES: 10 +Deploy Application Verify application health 2026-03-06T05:31:51.7980346Z DELAY_SECONDS: 3 +Deploy Application Verify application health 2026-03-06T05:31:51.7980525Z JQ_FILTER: .status == "healthy" +Deploy Application Verify application health 2026-03-06T05:31:51.7980725Z ##[endgroup] +Deploy Application Verify application health 2026-03-06T05:31:51.8117339Z { +Deploy Application Verify application health 2026-03-06T05:31:51.8118416Z "status": "healthy", +Deploy Application Verify application health 2026-03-06T05:31:51.8119624Z "timestamp": "2026-03-06T05:31:51.856613+00:00", +Deploy Application Verify application health 2026-03-06T05:31:51.8125582Z "uptime_seconds": 7603 +Deploy Application Verify application health 2026-03-06T05:31:51.8126569Z } +Deploy Application Remove vault password file 2026-03-06T05:31:51.8173310Z ##[group]Run rm -f .vault_pass +Deploy Application Remove vault password file 2026-03-06T05:31:51.8173612Z rm -f .vault_pass +Deploy Application Remove vault password file 2026-03-06T05:31:51.8183658Z shell: /usr/bin/bash -e {0} +Deploy Application Remove vault password file 2026-03-06T05:31:51.8183890Z env: +Deploy Application Remove vault password file 2026-03-06T05:31:51.8184060Z ANSIBLE_DIRECTORY: ansible +Deploy Application Remove vault password file 2026-03-06T05:31:51.8184297Z DEPLOY_PLAYBOOK: playbooks/deploy.yml +Deploy Application Remove vault password file 2026-03-06T05:31:51.8184526Z DEPLOY_TAGS: app_deploy +Deploy Application Remove vault password file 2026-03-06T05:31:51.8184815Z pythonLocation: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Remove vault password file 2026-03-06T05:31:51.8185349Z PKG_CONFIG_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib/pkgconfig +Deploy Application Remove vault password file 2026-03-06T05:31:51.8185769Z Python_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Remove vault password file 2026-03-06T05:31:51.8186221Z Python2_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Remove vault password file 2026-03-06T05:31:51.8186587Z Python3_ROOT_DIR: /opt/actions-runner/_work/_tool/Python/3.12.13/x64 +Deploy Application Remove vault password file 2026-03-06T05:31:51.8186969Z LD_LIBRARY_PATH: /opt/actions-runner/_work/_tool/Python/3.12.13/x64/lib +Deploy Application Remove vault password file 2026-03-06T05:31:51.8187298Z TARGET_VM_HOST: 192.168.121.50 +Deploy Application Remove vault password file 2026-03-06T05:31:51.8187521Z ##[endgroup] +Deploy Application Post Setup Ansible toolchain 2026-03-06T05:31:51.8272725Z Post job cleanup. +Deploy Application Post Setup Ansible toolchain 2026-03-06T05:31:51.8758473Z Post job cleanup. +Deploy Application Post Setup Ansible toolchain 2026-03-06T05:31:51.9913680Z Cache hit occurred on the primary key Linux-py3.12-ansible-70fee6f2b98d7def1a2c43ddbf364d7b6b2648821ca185e0955c8d98e4cb9364, not saving cache. +Deploy Application Post Setup Ansible toolchain 2026-03-06T05:31:51.9977690Z Post job cleanup. +Deploy Application Post Checkout code 2026-03-06T05:31:52.1550112Z Post job cleanup. +Deploy Application Post Checkout code 2026-03-06T05:31:52.2320436Z [command]/usr/bin/git version +Deploy Application Post Checkout code 2026-03-06T05:31:52.2355214Z git version 2.52.0 +Deploy Application Post Checkout code 2026-03-06T05:31:52.2385866Z Temporarily overriding HOME='/opt/actions-runner/_work/_temp/92425419-0a79-44b9-9641-d9e6f2b4f52e' before making global git config changes +Deploy Application Post Checkout code 2026-03-06T05:31:52.2453359Z Adding repository directory to the temporary git global config as a safe directory +Deploy Application Post Checkout code 2026-03-06T05:31:52.2456877Z [command]/usr/bin/git config --global --add safe.directory /opt/actions-runner/_work/DevOps-Core-S26/DevOps-Core-S26 +Deploy Application Post Checkout code 2026-03-06T05:31:52.2458061Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand +Deploy Application Post Checkout code 2026-03-06T05:31:52.2475428Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +Deploy Application Post Checkout code 2026-03-06T05:31:52.2676524Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +Deploy Application Post Checkout code 2026-03-06T05:31:52.2696268Z http.https://github.com/.extraheader +Deploy Application Post Checkout code 2026-03-06T05:31:52.2704496Z [command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader +Deploy Application Post Checkout code 2026-03-06T05:31:52.2731261Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +Deploy Application Post Checkout code 2026-03-06T05:31:52.2879233Z [command]/usr/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +Deploy Application Post Checkout code 2026-03-06T05:31:52.2903772Z [command]/usr/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +Deploy Application Complete job 2026-03-06T05:31:52.3147748Z Cleaning up orphan processes +``` + +
+ + ### Validation Status - The local Ansible side is already validated: `ansible-lint` passes, and the playbooks used by the workflow pass syntax checks. - `vagrant validate` for the isolated runner VM passes. -- The GitHub Actions workflow and composite actions are implemented locally and ready to run on the configured self-hosted runner. +- The GitHub Actions workflow completed successfully in run `22750506418`. +- The `Ansible Lint` and `Deploy Application` jobs both completed successfully. +- The deploy job resolved the target host from inventory, prepared `.vault_pass`, verified SSH connectivity with `ansible ping`, deployed the playbook, uploaded the deployment log artifact, checked `/health`, and removed `.vault_pass` afterwards. +- Two workflow defects were found and fixed during testing: stale self-hosted runner virtualenv caching and creating `.vault_pass` too late for the connectivity check. - Pull requests from external forks are intentionally excluded from the secret-backed lint path, because vault decryption requires repository secrets. -- A successful GitHub-hosted execution still depends on repository secrets being present and the workflow being triggered from GitHub. +- The workflow now has successful GitHub-side evidence, not just local validation. ### Research Answers @@ -1223,4 +2448,12 @@ The self-hosted runner itself is isolated in the separate `github-runner` Vagran ## Task 5: Documentation -This file is the lab documentation and will be extended as the remaining tasks are completed. +This file now serves as the complete lab report for Lab 6. + +### Final Status + +- Task 1 blocks and tags are implemented and validated. +- Task 2 Docker Compose deployment is implemented, idempotent, and verified on the VM. +- Task 3 wipe logic is implemented and tested across the required scenarios. +- Task 4 GitHub Actions CI/CD is implemented and validated with successful workflow run `22750506418`. +- Supporting raw evidence files collected during the lab include `task1.log`, `task3.log`, and `task4.log`.