Compare commits

...

8 commits

Author SHA1 Message Date
Imbus
c0e643f299 Ignore and make now builds into bin/ 2025-06-24 12:41:26 +02:00
Imbus
73507c3e7f Systemd service file WIP 2025-06-24 12:40:45 +02:00
Imbus
adda00508e Ignore 2025-06-24 12:40:37 +02:00
Imbus
a6ac787270 Template config 2025-06-24 12:40:25 +02:00
Imbus
573e8e3617 Remove root config 2025-06-24 12:39:43 +02:00
Imbus
9d2eec5250 Default target is now build 2025-06-24 12:39:37 +02:00
Imbus
64553bb153 Containerfile, composefile and makefile target for building images 2025-06-24 12:35:49 +02:00
Imbus
0b11ac87cd Creating config if not exists via templating 2025-06-24 12:35:06 +02:00
9 changed files with 112 additions and 12 deletions

3
.gitignore vendored
View file

@ -1,2 +1,3 @@
*.db *.db
beretta* data
bin

16
Containerfile Normal file
View file

@ -0,0 +1,16 @@
FROM docker.io/golang:1.24 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY src src
RUN GOOS=linux go build -o beretta src/*.go
# FROM docker.io/alpine:3
FROM docker.io/debian:bookworm-slim
RUN apt-get update && apt-get install -y \
ca-certificates \
sqlite3 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/beretta /beretta
ENTRYPOINT ["/beretta"]

View file

@ -1,8 +1,11 @@
build:
go build -o bin/beretta src/*.go
run: run:
go run src/*.go go run src/*.go
build: build-container:
go build -o beretta src/*.go podman build -t beretta .
clean: clean:
rm beretta rm beretta

14
beretta.service Normal file
View file

@ -0,0 +1,14 @@
[Unit]
Description=Beretta Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/beretta
Restart=on-failure
RestartSec=5
User=beretta
WorkingDirectory=/usr/local/bin
[Install]
WantedBy=multi-user.target

11
docker-compose.yml Normal file
View file

@ -0,0 +1,11 @@
services:
beretta:
image: beretta:latest
name: beretta-server
build:
context: .
command: >
-config /data/beretta.json
-db /data/cache.db
volumes:
- ./data:/data:Z

View file

@ -10,6 +10,6 @@
} }
], ],
"interval": 1200, "interval": 1200,
"ntfy_topic": "hee4waeNguch" "ntfy_topic": "{{.TopicToken}}"
} }

View file

@ -1,12 +1,18 @@
package main package main
import ( import (
_ "embed"
"flag" "flag"
"log" "log"
"math/rand" "math/rand"
"os"
"text/template"
"time" "time"
) )
//go:embed beretta.json
var defconfig string
type RepoUpdate struct { type RepoUpdate struct {
repo Repo repo Repo
Tag string Tag string
@ -22,7 +28,7 @@ func notifierThread(c chan RepoUpdate, n Notifier) {
} }
func repoThread(c chan RepoUpdate, repo Repo, avgInterval int, db Db) { func repoThread(c chan RepoUpdate, repo Repo, avgInterval int, db Db) {
log.Println("Checking", repo.IdTuple()) log.Println("Checking: ", repo.IdTuple())
tag, err := repo.GetLatestTag() tag, err := repo.GetLatestTag()
isNewVersion, err_2 := db.CheckAndStore(repo.IdTuple(), tag.Name) isNewVersion, err_2 := db.CheckAndStore(repo.IdTuple(), tag.Name)
@ -33,6 +39,7 @@ func repoThread(c chan RepoUpdate, repo Repo, avgInterval int, db Db) {
} else if isNewVersion { } else if isNewVersion {
c <- RepoUpdate{repo, tag.Name} c <- RepoUpdate{repo, tag.Name}
} }
log.Println("Checking done: ", repo.IdTuple())
sleepTime := time.Duration(rand.Intn(avgInterval)) * time.Second sleepTime := time.Duration(rand.Intn(avgInterval)) * time.Second
time.Sleep(sleepTime) time.Sleep(sleepTime)
@ -41,25 +48,54 @@ func repoThread(c chan RepoUpdate, repo Repo, avgInterval int, db Db) {
} }
func main() { func main() {
conf_path := flag.String("config", "beretta.json", "The path to the config file")
conf := flag.String("config", "./beretta.json", "The path to the config file") db_path := flag.String("db", "cache.db", "The path to the cache database")
flag.Parse() flag.Parse()
log.Printf("Using config path: %s", *conf) tmpl, err := template.New("config").Parse(defconfig)
if err != nil {
panic(err)
}
randtk, err := randToken(8)
if err != nil {
panic(err)
}
data := map[string]any{
"TopicToken": randtk,
}
if _, err := os.Stat(*conf_path); os.IsNotExist(err) {
log.Printf("Writing new config file: %s", *conf_path)
file, err := os.Create(*conf_path)
if err != nil {
panic(err)
}
err = tmpl.Execute(file, data)
if err != nil {
log.Fatalf("Error writing config file: %s", err)
return
}
}
log.Printf("Using config path: %s", *conf_path)
log.Printf("Using db path: %s", *db_path)
// Load configuration // Load configuration
config, err := loadConfig(*conf) config, err := loadConfig(*conf_path)
if err != nil { if err != nil {
log.Fatalf("Failed to load configuration: %v", err) log.Fatalf("Failed to load configuration: %v", err)
} }
// Create database // Create database
db, err := NewSQLiteDb("tags.db") db, err := NewSQLiteDb(*db_path)
if err != nil { if err != nil {
log.Fatalf("Failed to create database: %v", err) log.Fatalf("Failed to create database: %v", err)
} }
notifier := NtfyNotifier{Topic: config.NtfyTopic} notifier := NtfyNotifier{Topic: config.NtfyTopic}
log.Printf("Sending notifications to: %s", notifier.Url())
c := make(chan RepoUpdate) c := make(chan RepoUpdate)

14
src/random_token.go Normal file
View file

@ -0,0 +1,14 @@
package main
import (
"crypto/rand"
"encoding/hex"
)
func randToken(n int) (string, error) {
bytes := make([]byte, n)
if _, err := rand.Read(bytes); err != nil {
return "", err
}
return hex.EncodeToString(bytes), nil
}

View file

@ -39,6 +39,7 @@ func loadConfig(file string) (Config, error) {
type Notifier interface { type Notifier interface {
Notify(repo Repo, tag string) bool Notify(repo Repo, tag string) bool
Url() string
} }
type NtfyNotifier struct { type NtfyNotifier struct {
@ -46,10 +47,10 @@ type NtfyNotifier struct {
} }
func (n NtfyNotifier) Notify(repo Repo, tag string) bool { func (n NtfyNotifier) Notify(repo Repo, tag string) bool {
ntfyURL := fmt.Sprintf("https://ntfy.sh/%s", n.Topic) // ntfyURL := fmt.Sprintf("https://ntfy.sh/%s", n.Topic)
message := fmt.Sprintf("New release for %s/%s: %s", repo.Owner(), repo.Name(), tag) message := fmt.Sprintf("New release for %s/%s: %s", repo.Owner(), repo.Name(), tag)
_, err := http.Post(ntfyURL, "text/plain", bytes.NewBuffer([]byte(message))) _, err := http.Post(n.Url(), "text/plain", bytes.NewBuffer([]byte(message)))
if err != nil { if err != nil {
log.Printf("Failed to send notification: %v", err) log.Printf("Failed to send notification: %v", err)
return false return false
@ -57,3 +58,7 @@ func (n NtfyNotifier) Notify(repo Repo, tag string) bool {
log.Printf("Notification sent: %s", message) log.Printf("Notification sent: %s", message)
return true return true
} }
func (n NtfyNotifier) Url() string {
return fmt.Sprintf("https://ntfy.sh/%s", n.Topic)
}