1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-21 13:23:07 +01:00

feat: release check mode (#4095)

This commit is contained in:
uponminiature
2025-09-01 22:28:49 +01:00
committed by GitHub
parent 0b401aacd1
commit 01c564228b
8 changed files with 85 additions and 38 deletions

View File

@@ -1,5 +1,9 @@
<template> <template>
<Dropdown class="dropdown-end" @closed="releaseSeen = mostRecent?.tag ?? config.version"> <Dropdown
class="dropdown-end"
@click="config.releaseCheckMode === 'manual' && fetchReleases()"
@closed="releaseSeen = mostRecent?.tag ?? config.version"
>
<template #trigger> <template #trigger>
<mdi:announcement class="size-6 -rotate-12" /> <mdi:announcement class="size-6 -rotate-12" />
<template v-if="announcements.length > 0 && releaseSeen != mostRecent?.tag"> <template v-if="announcements.length > 0 && releaseSeen != mostRecent?.tag">
@@ -63,7 +67,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAnnouncements } from "@/stores/announcements"; import { useAnnouncements } from "@/stores/announcements";
const { announcements, mostRecent } = useAnnouncements(); const { announcements, mostRecent, fetchReleases } = useAnnouncements();
const { t } = useI18n(); const { t } = useI18n();
const releaseSeen = useProfileStorage("releaseSeen", config.version); const releaseSeen = useProfileStorage("releaseSeen", config.version);

View File

@@ -12,7 +12,25 @@ type Announcement = {
breaking: number; breaking: number;
}; };
const { data: releases } = useFetch(withBase("/api/releases")).get().json<Announcement[]>(); const releases = ref<Announcement[]>([]);
let fetched = false;
async function fetchReleases() {
if (fetched) return;
fetched = true;
try {
const { data } = await useFetch(withBase("/api/releases")).get().json<Announcement[]>();
releases.value = data.value || [];
} catch (error) {
console.error("Error while fetching releases:\n", error);
fetched = false;
}
}
if (config.releaseCheckMode === "automatic") {
fetchReleases();
}
const otherAnnouncements = [] as Announcement[]; const otherAnnouncements = [] as Announcement[];
@@ -33,5 +51,6 @@ export function useAnnouncements() {
announcements, announcements,
latestRelease, latestRelease,
hasRelease, hasRelease,
fetchReleases,
}; };
} }

View File

@@ -13,6 +13,7 @@ export interface Config {
enableActions: boolean; enableActions: boolean;
enableShell: boolean; enableShell: boolean;
disableAvatars: boolean; disableAvatars: boolean;
releaseCheckMode: "automatic" | "manual";
user?: { user?: {
username: string; username: string;
email: string; email: string;

View File

@@ -6,26 +6,27 @@ title: Environment Variables and Subcommands
Configurations can be done with flags or environment variables. The table below outlines all supported options and their respective env vars. Configurations can be done with flags or environment variables. The table below outlines all supported options and their respective env vars.
| Flag | Env Variable | Default | | Flag | Env Variable | Default |
| --------------------- | -------------------------- | -------------- | | ---------------------- | --------------------------- | -------------- |
| `--addr` | `DOZZLE_ADDR` | `:8080` | | `--addr` | `DOZZLE_ADDR` | `:8080` |
| `--base` | `DOZZLE_BASE` | `/` | | `--base` | `DOZZLE_BASE` | `/` |
| `--hostname` | `DOZZLE_HOSTNAME` | `""` | | `--hostname` | `DOZZLE_HOSTNAME` | `""` |
| `--level` | `DOZZLE_LEVEL` | `info` | | `--level` | `DOZZLE_LEVEL` | `info` |
| `--auth-provider` | `DOZZLE_AUTH_PROVIDER` | `none` | | `--auth-provider` | `DOZZLE_AUTH_PROVIDER` | `none` |
| `--auth-header-user` | `DOZZLE_AUTH_HEADER_USER` | `Remote-User` | | `--auth-header-user` | `DOZZLE_AUTH_HEADER_USER` | `Remote-User` |
| `--auth-header-email` | `DOZZLE_AUTH_HEADER_EMAIL` | `Remote-Email` | | `--auth-header-email` | `DOZZLE_AUTH_HEADER_EMAIL` | `Remote-Email` |
| `--auth-header-name` | `DOZZLE_AUTH_HEADER_NAME` | `Remote-Name` | | `--auth-header-name` | `DOZZLE_AUTH_HEADER_NAME` | `Remote-Name` |
| `--enable-actions` | `DOZZLE_ENABLE_ACTIONS` | `false` | | `--enable-actions` | `DOZZLE_ENABLE_ACTIONS` | `false` |
| `--enable-shell` | `DOZZLE_ENABLE_SHELL` | `false` | | `--enable-shell` | `DOZZLE_ENABLE_SHELL` | `false` |
| `--disable-avatars` | `DOZZLE_DISABLE_AVATARS` | `false` | | `--disable-avatars` | `DOZZLE_DISABLE_AVATARS` | `false` |
| `--filter` | `DOZZLE_FILTER` | `""` | | `--filter` | `DOZZLE_FILTER` | `""` |
| `--no-analytics` | `DOZZLE_NO_ANALYTICS` | `false` | | `--no-analytics` | `DOZZLE_NO_ANALYTICS` | `false` |
| `--mode` | `DOZZLE_MODE` | `server` | | `--mode` | `DOZZLE_MODE` | `server` |
| `--remote-host` | `DOZZLE_REMOTE_HOST` | | | `--release-check-mode` | `DOZZLE_RELEASE_CHECK_MODE` | `automatic` |
| `--remote-agent` | `DOZZLE_REMOTE_AGENT` | | | `--remote-host` | `DOZZLE_REMOTE_HOST` | |
| `--timeout` | `DOZZLE_TIMEOUT` | `10s` | | `--remote-agent` | `DOZZLE_REMOTE_AGENT` | |
| `--namespace` | `DOZZLE_NAMESPACE` | `""` | | `--timeout` | `DOZZLE_TIMEOUT` | `10s` |
| `--namespace` | `DOZZLE_NAMESPACE` | `""` |
> [!TIP] > [!TIP]
> Some flags like `--remote-host` or `--remote-agent` can be used multiple times. For example, `--remote-agent 167.99.1.1:7007 --remote-agent 167.99.1.2:7007` or comma-separated `DOZZLE_REMOTE_AGENT=167.99.1.1:7007,167.99.1.2:7007`. > Some flags like `--remote-host` or `--remote-agent` can be used multiple times. For example, `--remote-agent 167.99.1.1:7007 --remote-agent 167.99.1.2:7007` or comma-separated `DOZZLE_REMOTE_AGENT=167.99.1.1:7007,167.99.1.2:7007`.

View File

@@ -26,6 +26,7 @@ type Args struct {
DisableAvatars bool `arg:"--disable-avatars,env:DOZZLE_DISABLE_AVATARS" default:"false" help:"disables avatars for authenticated users."` DisableAvatars bool `arg:"--disable-avatars,env:DOZZLE_DISABLE_AVATARS" default:"false" help:"disables avatars for authenticated users."`
FilterStrings []string `arg:"env:DOZZLE_FILTER,--filter,separate" help:"filters docker containers using Docker syntax."` FilterStrings []string `arg:"env:DOZZLE_FILTER,--filter,separate" help:"filters docker containers using Docker syntax."`
Filter map[string][]string `arg:"-"` Filter map[string][]string `arg:"-"`
ReleaseCheckMode string `arg:"--release-check-mode,env:DOZZLE_RELEASE_CHECK_MODE" default:"automatic" help:"sets the release check mode. When manual, releases will not be automatically fetched."`
RemoteHost []string `arg:"env:DOZZLE_REMOTE_HOST,--remote-host,separate" help:"list of hosts to connect remotely"` RemoteHost []string `arg:"env:DOZZLE_REMOTE_HOST,--remote-host,separate" help:"list of hosts to connect remotely"`
RemoteAgent []string `arg:"env:DOZZLE_REMOTE_AGENT,--remote-agent,separate" help:"list of agents to connect remotely"` RemoteAgent []string `arg:"env:DOZZLE_REMOTE_AGENT,--remote-agent,separate" help:"list of agents to connect remotely"`
NoAnalytics bool `arg:"--no-analytics,env:DOZZLE_NO_ANALYTICS" help:"disables anonymous analytics"` NoAnalytics bool `arg:"--no-analytics,env:DOZZLE_NO_ANALYTICS" help:"disables anonymous analytics"`

View File

@@ -52,6 +52,7 @@ func (h *handler) executeTemplate(w http.ResponseWriter, req *http.Request) {
config["enableActions"] = h.config.EnableActions config["enableActions"] = h.config.EnableActions
config["enableShell"] = h.config.EnableShell config["enableShell"] = h.config.EnableShell
config["disableAvatars"] = h.config.DisableAvatars config["disableAvatars"] = h.config.DisableAvatars
config["releaseCheckMode"] = h.config.ReleaseCheckMode
} }
if user != nil { if user != nil {

View File

@@ -17,6 +17,13 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
type ReleaseCheckMode string
const (
Automatic ReleaseCheckMode = "automatic"
Manual ReleaseCheckMode = "manual"
)
type AuthProvider string type AuthProvider string
const ( const (
@@ -27,17 +34,18 @@ const (
// Config is a struct for configuring the web service // Config is a struct for configuring the web service
type Config struct { type Config struct {
Base string Base string
Addr string Addr string
Version string Version string
Hostname string Hostname string
NoAnalytics bool NoAnalytics bool
Dev bool Dev bool
Authorization Authorization Authorization Authorization
EnableActions bool EnableActions bool
EnableShell bool EnableShell bool
DisableAvatars bool DisableAvatars bool
Labels container.ContainerLabels ReleaseCheckMode ReleaseCheckMode
Labels container.ContainerLabels
} }
type Authorization struct { type Authorization struct {

20
main.go
View File

@@ -140,6 +140,17 @@ func fileExists(filename string) bool {
func createServer(args cli.Args, hostService web.HostService) *http.Server { func createServer(args cli.Args, hostService web.HostService) *http.Server {
_, dev := os.LookupEnv("DEV") _, dev := os.LookupEnv("DEV")
var releaseCheckMode web.ReleaseCheckMode = web.Automatic
switch args.ReleaseCheckMode {
case "automatic":
releaseCheckMode = web.Automatic
case "manual":
releaseCheckMode = web.Manual
default:
log.Fatal().Str("releaseCheckMode", args.ReleaseCheckMode).Msg("Invalid release check mode")
}
var provider web.AuthProvider = web.NONE var provider web.AuthProvider = web.NONE
var authorizer web.Authorizer var authorizer web.Authorizer
if args.AuthProvider == "forward-proxy" { if args.AuthProvider == "forward-proxy" {
@@ -198,10 +209,11 @@ func createServer(args cli.Args, hostService web.HostService) *http.Server {
Authorizer: authorizer, Authorizer: authorizer,
TTL: authTTL, TTL: authTTL,
}, },
EnableActions: args.EnableActions, EnableActions: args.EnableActions,
EnableShell: args.EnableShell, EnableShell: args.EnableShell,
DisableAvatars: args.DisableAvatars, DisableAvatars: args.DisableAvatars,
Labels: args.Filter, ReleaseCheckMode: releaseCheckMode,
Labels: args.Filter,
} }
assets, err := fs.Sub(content, "dist") assets, err := fs.Sub(content, "dist")