Compare commits

..

19 Commits

35
cntfy

@ -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)"
}

@ -1,24 +0,0 @@
#!/bin/env nu
export def main [] {
get_info "docker.io/itzg/minecraft-server"
}
export def get_info [image_name: string] {
let info = ( parse_name $image_name )
let token = ( get_token $info.registry $info.group $info.image )
http get -H [Authorization $"Bearer ($token)"] $"https://index.($info.registry)/v2/($info.group)/($info.image)/manifests/latest" | from json
}
def parse_name [image_name: string] {
let parts = ( $image_name | split row "/" )
{
registry: $parts.0
group: $parts.1
image: $parts.2
}
}
def get_token [registry: string, group: string, image: string] {
http get $"https://auth.($registry)/token?service=registry.($registry)&scope=repository:($group)/($image):pull" | get token
}

@ -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

@ -1,6 +1,6 @@
#!/bin/env nu #!/bin/env nu
use cntfy.nu use ./lib/cntfy.nu
# Checks for package updates # Checks for package updates
def main [ def main [
@ -11,6 +11,8 @@ def main [
msg: "This script needs to be run as root" msg: "This script needs to be run as root"
} }
} }
pacman -Sy
let updates = ( checkupdates | split row "\n" ) let updates = ( checkupdates | split row "\n" )
let update_count = ( $updates | length ) let update_count = ( $updates | length )
@ -28,7 +30,7 @@ def main [
} else { } else {
$update_msg = ( $updates | str join "\n" ) $update_msg = ( $updates | str join "\n" )
} }
cntfy main publish --title $"($update_count) package[s] need to be updated" updates $update_msg cntfy publish --tags [ pacman ] --title $"($update_count) package[s] need to be updated" updates $update_msg
} }
} }
} }

@ -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…
Cancel
Save