apt_updates: the role owns the apt metrics (Debian collector off, explicit zero rows, multi-suite security detection)
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
src: apt-updates-metrics.j2
|
src: apt-updates-metrics.j2
|
||||||
dest: /usr/local/sbin/apt-updates-metrics
|
dest: /usr/local/sbin/apt-updates-metrics
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
register: apt_updates_script
|
||||||
|
|
||||||
- name: Create the apt timers' drop-in directories
|
- name: Create the apt timers' drop-in directories
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
@@ -39,3 +40,41 @@
|
|||||||
when: apt_updates_dropins.changed
|
when: apt_updates_dropins.changed
|
||||||
# Check mode does not write the drop-ins.
|
# Check mode does not write the drop-ins.
|
||||||
ignore_errors: "{{ ansible_check_mode }}"
|
ignore_errors: "{{ ansible_check_mode }}"
|
||||||
|
|
||||||
|
# Debian's prometheus-node-exporter-apt collector writes apt.prom with the same metric families as this role under
|
||||||
|
# other HELP texts; node_exporter drops the rows of both files then. This role owns the apt metrics, so the
|
||||||
|
# collector stays off and its file, also a stale leftover of a removed collector, goes away.
|
||||||
|
- name: Look for the Debian apt metrics collector
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /lib/systemd/system/prometheus-node-exporter-apt.timer
|
||||||
|
register: apt_updates_debian_collector
|
||||||
|
|
||||||
|
- name: Stop and disable the Debian apt metrics collector timer
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: prometheus-node-exporter-apt.timer
|
||||||
|
enabled: false
|
||||||
|
state: stopped
|
||||||
|
when: apt_updates_debian_collector.stat.exists
|
||||||
|
|
||||||
|
- name: Stop the Debian apt metrics collector service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: prometheus-node-exporter-apt.service
|
||||||
|
state: stopped
|
||||||
|
when: apt_updates_debian_collector.stat.exists
|
||||||
|
|
||||||
|
- name: Remove the Debian apt metrics collector output
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ apt_updates_textfile_dir }}/apt.prom"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
# The timers' drop-ins write the metrics after the next apt run; this gives a new host and a changed script
|
||||||
|
# current metrics at once.
|
||||||
|
- name: Look for the apt metrics file
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ apt_updates_textfile_dir }}/apt_updates.prom"
|
||||||
|
register: apt_updates_prom
|
||||||
|
|
||||||
|
- name: Write the apt metrics
|
||||||
|
ansible.builtin.command: /usr/local/sbin/apt-updates-metrics
|
||||||
|
when: apt_updates_script.changed or not apt_updates_prom.stat.exists
|
||||||
|
changed_when: true
|
||||||
|
|||||||
@@ -9,11 +9,14 @@ out=$textfile_dir/apt_updates.prom
|
|||||||
tmp=$(mktemp "$textfile_dir/.apt_updates.XXXXXX")
|
tmp=$(mktemp "$textfile_dir/.apt_updates.XXXXXX")
|
||||||
trap 'rm -f "$tmp"' EXIT
|
trap 'rm -f "$tmp"' EXIT
|
||||||
|
|
||||||
arch=$(dpkg --print-architecture)
|
# Architectures a pending package can have: the native and foreign ones, plus "all" for architecture-independent
|
||||||
|
# packages. Each gets a row per kind even at 0, so a resolved backlog reads as 0 and not as a vanished series.
|
||||||
|
archs="$(dpkg --print-architecture) $(dpkg --print-foreign-architectures | tr '\n' ' ') all"
|
||||||
|
|
||||||
# The simulated upgrade lists "Inst <package> [<installed>] (<candidate> <origin> [<arch>])" per package.
|
# The simulated upgrade lists "Inst <package> [<installed>] (<candidate> <origins> [<arch>])" per package. A version in
|
||||||
# An origin containing "security" counts as security, everything else as regular.
|
# several suites lists them all, comma separated. A package counts as security when any origin contains "security",
|
||||||
pending=$(apt-get -s upgrade | awk -v host="$host" -v arch="$arch" '
|
# everything else as regular.
|
||||||
|
pending=$(apt-get -s upgrade | awk -v host="$host" -v archs="$archs" '
|
||||||
/^Inst / {
|
/^Inst / {
|
||||||
line = $0
|
line = $0
|
||||||
sub(/^[^(]*\(/, "", line)
|
sub(/^[^(]*\(/, "", line)
|
||||||
@@ -21,13 +24,16 @@ pending=$(apt-get -s upgrade | awk -v host="$host" -v arch="$arch" '
|
|||||||
n = split(line, f, " ")
|
n = split(line, f, " ")
|
||||||
pkg_arch = f[n]
|
pkg_arch = f[n]
|
||||||
gsub(/\[|\]/, "", pkg_arch)
|
gsub(/\[|\]/, "", pkg_arch)
|
||||||
origin = (n >= 3) ? f[2] : ""
|
sub(/^[^ ]+ /, "", line)
|
||||||
kind = (tolower(origin) ~ /security/) ? "security" : "regular"
|
kind = (tolower(line) ~ /security/) ? "security" : "regular"
|
||||||
count[kind, pkg_arch]++
|
count[kind, pkg_arch]++
|
||||||
}
|
}
|
||||||
END {
|
END {
|
||||||
if (!(("security", arch) in count)) count["security", arch] = 0
|
split(archs, a, " ")
|
||||||
if (!(("regular", arch) in count)) count["regular", arch] = 0
|
for (i in a) {
|
||||||
|
if (!(("security", a[i]) in count)) count["security", a[i]] = 0
|
||||||
|
if (!(("regular", a[i]) in count)) count["regular", a[i]] = 0
|
||||||
|
}
|
||||||
for (key in count) {
|
for (key in count) {
|
||||||
split(key, k, SUBSEP)
|
split(key, k, SUBSEP)
|
||||||
printf "apt_upgrades_pending{host=\"%s\",origin=\"%s\",arch=\"%s\"} %d\n", host, k[1], k[2], count[key]
|
printf "apt_upgrades_pending{host=\"%s\",origin=\"%s\",arch=\"%s\"} %d\n", host, k[1], k[2], count[key]
|
||||||
@@ -41,11 +47,15 @@ if [[ -e /run/reboot-required ]]; then
|
|||||||
reboot=1
|
reboot=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Debian writes update-stamp, Ubuntu update-success-stamp; both are touched by a successful update.
|
# Debian writes update-stamp, Ubuntu update-success-stamp; both are touched by a successful update. Both are missing
|
||||||
|
# until apt.systemd.daily has run an update, then the package cache stands in.
|
||||||
stamp=/var/lib/apt/periodic/update-success-stamp
|
stamp=/var/lib/apt/periodic/update-success-stamp
|
||||||
if [[ ! -e $stamp ]]; then
|
if [[ ! -e $stamp ]]; then
|
||||||
stamp=/var/lib/apt/periodic/update-stamp
|
stamp=/var/lib/apt/periodic/update-stamp
|
||||||
fi
|
fi
|
||||||
|
if [[ ! -e $stamp ]]; then
|
||||||
|
stamp=/var/cache/apt/pkgcache.bin
|
||||||
|
fi
|
||||||
cache=$(stat -c %Y "$stamp")
|
cache=$(stat -c %Y "$stamp")
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user