Adds a StepRunUpdater step that starts app-dono-updater after the app container comes up: a poll loop (docker pull, compare image IDs, recreate on change) baked into the official docker:cli image via `sh -c`, reusing the same docker run argv as the initial container start so the two can't drift. Not built on Watchtower: containrrr/watchtower was archived upstream in Dec 2025 with no maintained successor recommended for production use, so this avoids taking on that dependency.
127 lines
2.5 KiB
Go
127 lines
2.5 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"time"
|
|
|
|
tea "charm.land/bubbletea/v2"
|
|
)
|
|
|
|
// --- Messages ---
|
|
|
|
// Docker installation check
|
|
type DockerCheckedMsg struct{ Installed bool }
|
|
type DockerInstalledMsg struct{ Err error }
|
|
type TickMsg struct{}
|
|
|
|
// Image downloading and checking
|
|
type ImageCheckMsg struct {
|
|
Exists bool
|
|
Err error
|
|
}
|
|
type ImageDownloadFinishedMsg struct {
|
|
Message string
|
|
Err error
|
|
}
|
|
type DownloadTickMsg struct{}
|
|
type ConfigFileMsg struct{ Err error }
|
|
type DockerRunMsg struct{ Err error }
|
|
|
|
// --- Commands ---
|
|
|
|
func CheckDockerCmd() tea.Cmd {
|
|
return func() tea.Msg {
|
|
_, err := exec.LookPath("docker")
|
|
return DockerCheckedMsg{Installed: err == nil}
|
|
}
|
|
}
|
|
|
|
func TickCmd() tea.Cmd {
|
|
return tea.Tick(100*time.Millisecond, func(t time.Time) tea.Msg {
|
|
return TickMsg{}
|
|
})
|
|
}
|
|
|
|
func DownloadImageCmd(image, username, password string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
loginOut, err := exec.Command(
|
|
"docker", "login", image,
|
|
"-u", username,
|
|
"-p", password,
|
|
).CombinedOutput()
|
|
|
|
if err != nil {
|
|
return ImageDownloadFinishedMsg{
|
|
Message: string(loginOut),
|
|
Err: fmt.Errorf("falha no login: %w", err),
|
|
}
|
|
}
|
|
|
|
message, err := PullImage(image)
|
|
return ImageDownloadFinishedMsg{Message: message, Err: err}
|
|
}
|
|
}
|
|
|
|
func CheckImageCmd(image string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
cmd := exec.Command("docker", "image", "inspect", image)
|
|
err := cmd.Run()
|
|
|
|
return ImageCheckMsg{
|
|
Exists: err == nil,
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
func GenerateWireguardConfigFile(cv ConfigValues, path string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := WriteWireguardConfigFile(cv, path)
|
|
|
|
return ConfigFileMsg{
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
func GenerateConfigFile(cv ConfigValues, path string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := WriteConfigFile(cv, path)
|
|
|
|
return ConfigFileMsg{
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
func RunAppContainer(image, name, filePath, destinationPath string, cv ConfigValues) tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := RunAppClienteContainer(image, name, filePath, destinationPath, cv)
|
|
|
|
return DockerRunMsg{
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
func RunWireguardContainer(path string, cv ConfigValues) tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := RunWireguardDockerContainer(path, cv)
|
|
|
|
return DockerRunMsg{
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
func RunUpdaterContainer(appImage, appContainerName, configPath, configDestinationPath string, cv ConfigValues) tea.Cmd {
|
|
return func() tea.Msg {
|
|
err := RunUpdaterDockerContainer(appImage, appContainerName, configPath, configDestinationPath, cv)
|
|
|
|
return DockerRunMsg{
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|