Compare commits
19 Commits
feature/co
...
main
Author | SHA1 | Date |
---|---|---|
trivernis | 3f03fb677d | 1 year ago |
trivernis | 978f14d18d | 1 year ago |
trivernis | d891eab6f6 | 1 year ago |
trivernis | 5605bc3a12 | 1 year ago |
trivernis | 0d74097da0 | 1 year ago |
trivernis | ce0343c384 | 1 year ago |
trivernis | 895385f218 | 1 year ago |
trivernis | 6aeed20dbf | 1 year ago |
trivernis | d3d7659bca | 1 year ago |
trivernis | ddbe85b19d | 1 year ago |
trivernis | cec4206590 | 1 year ago |
trivernis | db67bd6908 | 1 year ago |
trivernis | 345a12896f | 1 year ago |
trivernis | e5c7d9016d | 1 year ago |
trivernis | 1a07de1c0a | 1 year ago |
trivernis | e8400a31d9 | 1 year ago |
trivernis | 5621b4733c | 1 year ago |
trivernis | 45ecf8c376 | 1 year ago |
trivernis | 0606d3fed9 | 1 year ago |
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
use ./lib/cntfy.nu
|
||||
|
||||
def main [
|
||||
subcommand: string@subcommands
|
||||
] {
|
||||
if $subcommand == "help" {
|
||||
print $"cntfy <subcommand>",
|
||||
print ""
|
||||
print "Subcommands: "
|
||||
|
||||
for subcommand in ( subcommands ) {
|
||||
print ""
|
||||
print $"(ansi {attr: b})($subcommand)(ansi reset)"
|
||||
print ( help $"main ($subcommand)" )
|
||||
}
|
||||
} else {
|
||||
let span = (metadata $subcommand).span;
|
||||
error make {
|
||||
msg: $"Unknown subcommand ($subcommand)",
|
||||
label: {
|
||||
text: "Unknown subcommand",
|
||||
start: $span.start,
|
||||
end: $span.end
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def subcommands [] {
|
||||
["publish"]
|
||||
}
|
||||
|
||||
alias `main publish` = cntfy publish
|
@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
def main [
|
||||
subcommand: string@subcommands
|
||||
] {
|
||||
if $subcommand == "help" {
|
||||
print $"cntfy <subcommand>",
|
||||
print ""
|
||||
print "Subcommands: "
|
||||
|
||||
for subcommand in ( subcommands ) {
|
||||
print ""
|
||||
print $"(ansi {attr: b})($subcommand)(ansi reset)"
|
||||
print ( help $"main ($subcommand)" )
|
||||
}
|
||||
} else {
|
||||
let span = (metadata $subcommand).span;
|
||||
error make {
|
||||
msg: $"Unknown subcommand ($subcommand)",
|
||||
label: {
|
||||
text: "Unknown subcommand",
|
||||
start: $span.start,
|
||||
end: $span.end
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def subcommands [] {
|
||||
["publish"]
|
||||
}
|
||||
|
||||
# Publishes a message
|
||||
export def `main publish` [
|
||||
topic: string
|
||||
body: any
|
||||
--title: string
|
||||
--priority: string
|
||||
--tags: string
|
||||
] {
|
||||
let headers = ( []
|
||||
| append [Title $title]
|
||||
| append [Priority $priority]
|
||||
| append [Tags $tags]
|
||||
)
|
||||
|
||||
let cfg = ( get_config )
|
||||
http put -u $cfg.username -p $cfg.password -H $headers ( build_url $topic ) $body
|
||||
}
|
||||
|
||||
def get_config [] {
|
||||
let cfg_path = ( $env.HOME | path join ".config/cntfy/config.toml" )
|
||||
|
||||
if ($cfg_path | path exists ) == false {
|
||||
let span = (metadata $cfg_path).span
|
||||
|
||||
error make {
|
||||
msg: $"Config file ($cfg_path) does not exist",
|
||||
label: {
|
||||
text: "This file does not exist",
|
||||
start: $span.start,
|
||||
end: $span.end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
( $cfg_path | open )
|
||||
}
|
||||
|
||||
def build_url [topic: string] {
|
||||
$"https://ntfy.trivernis.dev/($topic)"
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
use ./config.nu
|
||||
|
||||
# Publishes a message
|
||||
export def publish [
|
||||
topic: string
|
||||
message: string
|
||||
--title: string
|
||||
--priority: number
|
||||
--tags: list<string>
|
||||
--actions: list<any>
|
||||
--icon: string
|
||||
] {
|
||||
let cfg = ( config read_file cntfy )
|
||||
|
||||
if ( $env.NTFY_LIMIT? == 0) {
|
||||
sleep 5sec
|
||||
let-env NTFY_LIMIT = 3
|
||||
}
|
||||
|
||||
let request_body = ({
|
||||
topic: $topic
|
||||
title: $title
|
||||
message: $message
|
||||
tags: ( $tags | append ( hostname ) )
|
||||
priority: $priority
|
||||
actions: $actions
|
||||
icon: $icon
|
||||
} | to json )
|
||||
http put -u $cfg.username -p $cfg.password $cfg.url $request_body
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
# reads a config file
|
||||
export def read_file [app: string, filename = "config.toml"] {
|
||||
get_path $app | path join $filename | open
|
||||
}
|
||||
|
||||
# returns the path to an apps config dir
|
||||
export def get_path [app: string] {
|
||||
let home = $env.HOME?
|
||||
|
||||
if $home == null {
|
||||
return ( "/etc" | path join $app )
|
||||
}
|
||||
let local = ( $home | path join ".config" | path join $app )
|
||||
|
||||
if ( $local | path exists ) {
|
||||
$local
|
||||
} else {
|
||||
let etc_cfg = ( "/etc" | path join $app )
|
||||
|
||||
if ( $etc_cfg | path exists ) {
|
||||
$etc_cfg
|
||||
} else {
|
||||
mkdir $local
|
||||
$local
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
export def get_image_digest [image: string, tag: string] {
|
||||
let token = ( get_token $image )
|
||||
mut headers = ( []
|
||||
| append [Accept "application/vnd.docker.distribution.manifest.v2+json"]
|
||||
| append [Authorization $"Bearer ($token)"]
|
||||
)
|
||||
|
||||
( http get -H $headers $"https://registry.hub.docker.com/v2/($image)/manifests/($tag)"
|
||||
| from json
|
||||
| get config
|
||||
| get digest
|
||||
| split row ":"
|
||||
| get 1
|
||||
)
|
||||
}
|
||||
|
||||
def get_token [image: string] {
|
||||
http get $"https://auth.docker.io/token?scope=repository:($image):pull&service=registry.docker.io" | get token
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
# prelude script that can be sourced into other scripts for all modules
|
||||
use ./cntfy.nu
|
||||
use ./config.nu
|
@ -0,0 +1,74 @@
|
||||
#!/bin/env nu
|
||||
use ./lib/cntfy.nu
|
||||
use ./lib/dockerhub.nu
|
||||
|
||||
def main [
|
||||
--ntfy: bool
|
||||
] {
|
||||
let images = ( get_images )
|
||||
let image_count = ( $images | length )
|
||||
if $image_count == 0 {
|
||||
print "No images found"
|
||||
return
|
||||
}
|
||||
print $"($image_count) local image[s] found"
|
||||
|
||||
( $images
|
||||
| where { |$it| $it.Names? != null }
|
||||
| insert Name {|$it| $it.Names | first }
|
||||
| where {|| needs_update }
|
||||
| each {|| print_needs_update $ntfy }
|
||||
)
|
||||
}
|
||||
|
||||
def get_images [] {
|
||||
podman images --no-trunc --format json | from json
|
||||
}
|
||||
|
||||
export def needs_update [] {
|
||||
let data = $in
|
||||
let name_parts = ( $data.Name | split row "/" --number 2 )
|
||||
let registry = ( $name_parts | first )
|
||||
let img_parts = ( $name_parts | last | split row ":" )
|
||||
let image = ( $img_parts | get 0 )
|
||||
let tag = ( $img_parts | get 1 )
|
||||
let digest = $data.Id
|
||||
print $"Checking if ($image):($tag) has updates on ($registry)"
|
||||
|
||||
if $registry == "docker.io" {
|
||||
try {
|
||||
( dockerhub get_image_digest $image $tag ) != $digest
|
||||
} catch {
|
||||
print $"Failed to get image information ($in)"
|
||||
false
|
||||
}
|
||||
} else {
|
||||
print $"Host ($registry) is not supported"
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
def print_needs_update [ntfy: bool] {
|
||||
let data = $in
|
||||
let containers = ( containers_for_image $data.Name )
|
||||
print $"Image `($data.Name)` needs to be updated. Used by ($containers | str join ', ')"
|
||||
|
||||
if $ntfy {
|
||||
(
|
||||
cntfy publish
|
||||
--tags [ podman $data.Name ]
|
||||
--priority 4
|
||||
--title $"($data.Name) outdated"
|
||||
"updates" $"Container ($data.Name) needs to be updated. Used by ($data.Containers) containers. Used by: ( $containers | str join '\n' )"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def containers_for_image [image: string] {
|
||||
( podman container ls --all --format json
|
||||
| from json
|
||||
| where Image == $image
|
||||
| insert Name {|$it| $it.Names? | get 0 }
|
||||
| get Name
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue