2023-09-15 23:53:53 +02:00
|
|
|
package apkupdater
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2023-09-16 03:54:50 +02:00
|
|
|
"os/exec"
|
2023-09-15 23:53:53 +02:00
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-09-16 03:56:32 +02:00
|
|
|
// Create a new updater. Invoke Run().
|
|
|
|
func InitPkgUpdater() (PackageUpdater, error) {
|
|
|
|
|
|
|
|
alpine := isAlpine()
|
|
|
|
|
|
|
|
if alpine {
|
|
|
|
log.Println("Detected Alpine. Setting up Alpine Package Updater.")
|
|
|
|
return NewAlpineLinuxPackageUpdater(
|
|
|
|
time.Hour * 24,
|
|
|
|
[]string{"yt-dlp", "ffmpeg"},
|
|
|
|
), nil
|
|
|
|
}
|
2023-09-15 23:53:53 +02:00
|
|
|
|
2023-09-16 03:56:32 +02:00
|
|
|
log.Println("OS not known. Using dummy Package Updater")
|
|
|
|
return NewDummyPackageUpdater(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns true if the os running the application
|
|
|
|
// is using Alpine Linux. If an error occurs it
|
|
|
|
// returns false
|
|
|
|
func isAlpine() bool {
|
|
|
|
|
|
|
|
cmd := exec.Command("grep", "Alpine", "/etc/os-release")
|
|
|
|
_, err := cmd.Output()
|
|
|
|
if err != nil || cmd.ProcessState.ExitCode() != 0 { return false }
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Provides a package updater to run along side
|
|
|
|
Application. It updates a set of packages at
|
|
|
|
runtime. Run() starts a goroutine and returns.
|
|
|
|
Stop() signals stop to the running goroutine.
|
|
|
|
*/
|
2023-09-15 23:53:53 +02:00
|
|
|
type PackageUpdater interface {
|
|
|
|
Update()
|
|
|
|
Run()
|
|
|
|
Stop()
|
|
|
|
ValidPackages() bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type AlpineLinuxPackageUpdate struct {
|
|
|
|
Interval time.Duration
|
|
|
|
Packages []string
|
|
|
|
doneChan chan string
|
|
|
|
apkLock *sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *AlpineLinuxPackageUpdate) Update() {
|
2023-09-16 03:54:50 +02:00
|
|
|
|
2023-09-15 23:53:53 +02:00
|
|
|
log.Println("Updating packages...")
|
2023-09-16 03:54:50 +02:00
|
|
|
cmd := exec.Command("apk", u.Packages...)
|
2023-09-22 00:31:49 +02:00
|
|
|
u.apkLock.Lock()
|
2023-09-16 03:54:50 +02:00
|
|
|
stdout, err := cmd.Output()
|
2023-09-15 23:53:53 +02:00
|
|
|
u.apkLock.Unlock()
|
2023-09-16 03:54:50 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Println(err.Error())
|
|
|
|
}
|
|
|
|
if cmd.ProcessState.ExitCode() != 1 {
|
|
|
|
log.Printf("Update command returned exit status %d\n", cmd.ProcessState.ExitCode())
|
|
|
|
log.Println(string(stdout))
|
|
|
|
}
|
2023-09-15 23:53:53 +02:00
|
|
|
log.Println("Done updating packges")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *AlpineLinuxPackageUpdate) Run() {
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
mainloop:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <- u.doneChan:
|
|
|
|
fmt.Println("Stopping updater...")
|
|
|
|
break mainloop
|
|
|
|
case <- time.After(u.Interval):
|
|
|
|
u.Update()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println("Updater stopped")
|
|
|
|
}()
|
2023-09-16 03:54:50 +02:00
|
|
|
log.Println("Started Alpine linux package updater")
|
2023-09-15 23:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *AlpineLinuxPackageUpdate) ValidPackages() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *AlpineLinuxPackageUpdate) Stop() {
|
|
|
|
u.doneChan <- ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewAlpineLinuxPackageUpdater (
|
|
|
|
interval time.Duration,
|
|
|
|
packages []string,
|
2023-09-16 03:56:32 +02:00
|
|
|
) PackageUpdater {
|
|
|
|
return &AlpineLinuxPackageUpdate{
|
2023-09-15 23:53:53 +02:00
|
|
|
Interval: interval,
|
|
|
|
Packages: packages,
|
|
|
|
doneChan: make(chan string),
|
|
|
|
apkLock: &sync.Mutex{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-16 03:56:32 +02:00
|
|
|
type DummyPackageUpdater struct {}
|
|
|
|
func (u *DummyPackageUpdater) Run() {}
|
|
|
|
func (u *DummyPackageUpdater) Stop() {}
|
|
|
|
func (u *DummyPackageUpdater) ValidPackages() bool { return true }
|
|
|
|
func (u *DummyPackageUpdater) Update() {}
|
|
|
|
|
|
|
|
func NewDummyPackageUpdater() PackageUpdater {
|
|
|
|
return &DummyPackageUpdater{}
|
|
|
|
}
|
|
|
|
|