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