mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-24 06:26:17 +01:00
Compare commits
6 Commits
01e75c19ba
...
battery-fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e73399b87 | ||
|
|
e149366451 | ||
|
|
8da1ded73e | ||
|
|
efa37b2312 | ||
|
|
bcdb4c92b5 | ||
|
|
a7d07310b6 |
@@ -20,9 +20,8 @@ func HasReadableBattery() bool {
|
|||||||
}
|
}
|
||||||
haveCheckedBattery = true
|
haveCheckedBattery = true
|
||||||
bat, err := battery.Get(0)
|
bat, err := battery.Get(0)
|
||||||
if err == nil && bat != nil {
|
systemHasBattery = err == nil && bat != nil && bat.Design != 0 && bat.Full != 0
|
||||||
systemHasBattery = true
|
if !systemHasBattery {
|
||||||
} else {
|
|
||||||
slog.Debug("No battery found", "err", err)
|
slog.Debug("No battery found", "err", err)
|
||||||
}
|
}
|
||||||
return systemHasBattery
|
return systemHasBattery
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ func getToken() (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(tokenBytes), nil
|
return strings.TrimSpace(string(tokenBytes)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOptions returns the WebSocket client options, creating them if necessary.
|
// getOptions returns the WebSocket client options, creating them if necessary.
|
||||||
|
|||||||
@@ -537,4 +537,25 @@ func TestGetToken(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "", token, "Empty file should return empty string")
|
assert.Equal(t, "", token, "Empty file should return empty string")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("strips whitespace from TOKEN_FILE", func(t *testing.T) {
|
||||||
|
unsetEnvVars()
|
||||||
|
|
||||||
|
tokenWithWhitespace := " test-token-with-whitespace \n\t"
|
||||||
|
expectedToken := "test-token-with-whitespace"
|
||||||
|
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.Remove(tokenFile.Name())
|
||||||
|
|
||||||
|
_, err = tokenFile.WriteString(tokenWithWhitespace)
|
||||||
|
require.NoError(t, err)
|
||||||
|
tokenFile.Close()
|
||||||
|
|
||||||
|
os.Setenv("TOKEN_FILE", tokenFile.Name())
|
||||||
|
defer os.Unsetenv("TOKEN_FILE")
|
||||||
|
|
||||||
|
token, err := getToken()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expectedToken, token, "Whitespace should be stripped from token file content")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,35 +175,31 @@ func (h *Hub) registerCronJobs(_ *core.ServeEvent) error {
|
|||||||
|
|
||||||
// custom middlewares
|
// custom middlewares
|
||||||
func (h *Hub) registerMiddlewares(se *core.ServeEvent) {
|
func (h *Hub) registerMiddlewares(se *core.ServeEvent) {
|
||||||
|
// authorizes request with user matching the provided email
|
||||||
|
authorizeRequestWithEmail := func(e *core.RequestEvent, email string) (err error) {
|
||||||
|
if e.Auth != nil || email == "" {
|
||||||
|
return e.Next()
|
||||||
|
}
|
||||||
|
isAuthRefresh := e.Request.URL.Path == "/api/collections/users/auth-refresh" && e.Request.Method == http.MethodPost
|
||||||
|
e.Auth, err = e.App.FindFirstRecordByData("users", "email", email)
|
||||||
|
if err != nil || !isAuthRefresh {
|
||||||
|
return e.Next()
|
||||||
|
}
|
||||||
|
// auth refresh endpoint, make sure token is set in header
|
||||||
|
token, _ := e.Auth.NewAuthToken()
|
||||||
|
e.Request.Header.Set("Authorization", token)
|
||||||
|
return e.Next()
|
||||||
|
}
|
||||||
|
// authenticate with trusted header
|
||||||
|
if autoLogin, _ := GetEnv("AUTO_LOGIN"); autoLogin != "" {
|
||||||
|
se.Router.BindFunc(func(e *core.RequestEvent) error {
|
||||||
|
return authorizeRequestWithEmail(e, autoLogin)
|
||||||
|
})
|
||||||
|
}
|
||||||
// authenticate with trusted header
|
// authenticate with trusted header
|
||||||
if trustedHeader, _ := GetEnv("TRUSTED_AUTH_HEADER"); trustedHeader != "" {
|
if trustedHeader, _ := GetEnv("TRUSTED_AUTH_HEADER"); trustedHeader != "" {
|
||||||
se.Router.BindFunc(func(e *core.RequestEvent) error {
|
se.Router.BindFunc(func(e *core.RequestEvent) error {
|
||||||
if e.Auth != nil {
|
return authorizeRequestWithEmail(e, e.Request.Header.Get(trustedHeader))
|
||||||
return e.Next()
|
|
||||||
}
|
|
||||||
trustedEmail := e.Request.Header.Get(trustedHeader)
|
|
||||||
if trustedEmail == "" {
|
|
||||||
return e.Next()
|
|
||||||
}
|
|
||||||
isAuthRefresh := e.Request.URL.Path == "/api/collections/users/auth-refresh" && e.Request.Method == http.MethodPost
|
|
||||||
if !isAuthRefresh {
|
|
||||||
authRecord, err := e.App.FindAuthRecordByEmail("users", trustedEmail)
|
|
||||||
if err == nil {
|
|
||||||
e.Auth = authRecord
|
|
||||||
}
|
|
||||||
return e.Next()
|
|
||||||
}
|
|
||||||
// if auth refresh endpoint, find user record directly and generate token
|
|
||||||
user, err := e.App.FindFirstRecordByData("users", "email", trustedEmail)
|
|
||||||
if err != nil {
|
|
||||||
return e.Next()
|
|
||||||
}
|
|
||||||
e.Auth = user
|
|
||||||
// need to set the authorization header for the client sdk to pick up the token
|
|
||||||
if token, err := user.NewAuthToken(); err == nil {
|
|
||||||
e.Request.Header.Set("Authorization", token)
|
|
||||||
}
|
|
||||||
return e.Next()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -712,6 +712,60 @@ func TestCreateUserEndpointAvailability(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAutoLoginMiddleware(t *testing.T) {
|
||||||
|
var hubs []*beszelTests.TestHub
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
defer os.Unsetenv("AUTO_LOGIN")
|
||||||
|
for _, hub := range hubs {
|
||||||
|
hub.Cleanup()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
os.Setenv("AUTO_LOGIN", "user@test.com")
|
||||||
|
|
||||||
|
testAppFactory := func(t testing.TB) *pbTests.TestApp {
|
||||||
|
hub, _ := beszelTests.NewTestHub(t.TempDir())
|
||||||
|
hubs = append(hubs, hub)
|
||||||
|
hub.StartHub()
|
||||||
|
return hub.TestApp
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []beszelTests.ApiScenario{
|
||||||
|
{
|
||||||
|
Name: "GET /getkey - without auto login should fail",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
URL: "/api/beszel/getkey",
|
||||||
|
ExpectedStatus: 401,
|
||||||
|
ExpectedContent: []string{"requires valid"},
|
||||||
|
TestAppFactory: testAppFactory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "GET /getkey - with auto login should fail if no matching user",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
URL: "/api/beszel/getkey",
|
||||||
|
ExpectedStatus: 401,
|
||||||
|
ExpectedContent: []string{"requires valid"},
|
||||||
|
TestAppFactory: testAppFactory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "GET /getkey - with auto login should succeed",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
URL: "/api/beszel/getkey",
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
ExpectedContent: []string{"\"key\":", "\"v\":"},
|
||||||
|
TestAppFactory: testAppFactory,
|
||||||
|
BeforeTestFunc: func(t testing.TB, app *pbTests.TestApp, e *core.ServeEvent) {
|
||||||
|
beszelTests.CreateUser(app, "user@test.com", "password123")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
scenario.Test(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTrustedHeaderMiddleware(t *testing.T) {
|
func TestTrustedHeaderMiddleware(t *testing.T) {
|
||||||
var hubs []*beszelTests.TestHub
|
var hubs []*beszelTests.TestHub
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,10 @@
|
|||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true
|
"recommended": true,
|
||||||
|
"correctness": {
|
||||||
|
"useUniqueElementIds": "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
@@ -35,4 +38,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { memo, useEffect, useRef, useState } from "react"
|
|||||||
import { $router, basePath, Link, navigate } from "./router"
|
import { $router, basePath, Link, navigate } from "./router"
|
||||||
import { SystemRecord } from "@/types"
|
import { SystemRecord } from "@/types"
|
||||||
import { SystemStatus } from "@/lib/enums"
|
import { SystemStatus } from "@/lib/enums"
|
||||||
import { AppleIcon, DockerIcon, TuxIcon, WindowsIcon } from "./ui/icons"
|
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "./ui/icons"
|
||||||
import { InputCopy } from "./ui/input-copy"
|
import { InputCopy } from "./ui/input-copy"
|
||||||
import { getPagePath } from "@nanostores/router"
|
import { getPagePath } from "@nanostores/router"
|
||||||
import {
|
import {
|
||||||
@@ -253,6 +253,12 @@ export const SystemDialog = ({ setOpen, system }: { setOpen: (open: boolean) =>
|
|||||||
copyWindowsCommand(isUnixSocket ? hostValue : port.current?.value, publicKey, token),
|
copyWindowsCommand(isUnixSocket ? hostValue : port.current?.value, publicKey, token),
|
||||||
icons: [WindowsIcon],
|
icons: [WindowsIcon],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: t({ message: "FreeBSD command", context: "Button to copy install command" }),
|
||||||
|
onClick: async () =>
|
||||||
|
copyLinuxCommand(isUnixSocket ? hostValue : port.current?.value, publicKey, token),
|
||||||
|
icons: [FreeBsdIcon],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: t`Manual setup instructions`,
|
text: t`Manual setup instructions`,
|
||||||
url: "https://beszel.dev/guide/agent-installation#binary",
|
url: "https://beszel.dev/guide/agent-installation#binary",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
RotateCwIcon,
|
RotateCwIcon,
|
||||||
ServerIcon,
|
ServerIcon,
|
||||||
Trash2Icon,
|
Trash2Icon,
|
||||||
|
ExternalLinkIcon,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { memo, useEffect, useMemo, useState } from "react"
|
import { memo, useEffect, useMemo, useState } from "react"
|
||||||
import {
|
import {
|
||||||
@@ -28,7 +29,7 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu"
|
} from "@/components/ui/dropdown-menu"
|
||||||
import { AppleIcon, DockerIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
|
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { Switch } from "@/components/ui/switch"
|
import { Switch } from "@/components/ui/switch"
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||||
@@ -150,6 +151,7 @@ const SectionUniversalToken = memo(() => {
|
|||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/useExhaustiveDependencies: only on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateToken()
|
updateToken()
|
||||||
}, [])
|
}, [])
|
||||||
@@ -221,6 +223,16 @@ const ActionsButtonUniversalToken = memo(({ token, checked }: { token: string; c
|
|||||||
onClick: () => copyWindowsCommand(port, publicKey, token),
|
onClick: () => copyWindowsCommand(port, publicKey, token),
|
||||||
icons: [WindowsIcon],
|
icons: [WindowsIcon],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: t({ message: "FreeBSD command", context: "Button to copy install command" }),
|
||||||
|
onClick: () => copyLinuxCommand(port, publicKey, token),
|
||||||
|
icons: [FreeBsdIcon],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t`Manual setup instructions`,
|
||||||
|
url: "https://beszel.dev/guide/agent-installation#binary",
|
||||||
|
icons: [ExternalLinkIcon],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -291,8 +303,8 @@ const SectionTable = memo(({ fingerprints = [] }: { fingerprints: FingerprintRec
|
|||||||
</tr>
|
</tr>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody className="whitespace-pre">
|
<TableBody className="whitespace-pre">
|
||||||
{fingerprints.map((fingerprint, i) => (
|
{fingerprints.map((fingerprint) => (
|
||||||
<TableRow key={i}>
|
<TableRow key={fingerprint.id}>
|
||||||
<TableCell className="font-medium ps-5 py-2 max-w-60 truncate">
|
<TableCell className="font-medium ps-5 py-2 max-w-60 truncate">
|
||||||
{fingerprint.expand.system.name}
|
{fingerprint.expand.system.name}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -317,10 +329,10 @@ async function updateFingerprint(fingerprint: FingerprintRecord, rotateToken = f
|
|||||||
fingerprint: "",
|
fingerprint: "",
|
||||||
token: rotateToken ? generateToken() : fingerprint.token,
|
token: rotateToken ? generateToken() : fingerprint.token,
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: unknown) {
|
||||||
toast({
|
toast({
|
||||||
title: t`Error`,
|
title: t`Error`,
|
||||||
description: error.message,
|
description: (error as Error).message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/** biome-ignore-all lint/suspicious/noAssignInExpressions: it's fine :) */
|
||||||
import type { PreinitializedMapStore } from "nanostores"
|
import type { PreinitializedMapStore } from "nanostores"
|
||||||
import { pb, verifyAuth } from "@/lib/api"
|
import { pb, verifyAuth } from "@/lib/api"
|
||||||
import {
|
import {
|
||||||
@@ -16,9 +17,10 @@ const COLLECTION = pb.collection<SystemRecord>("systems")
|
|||||||
const FIELDS_DEFAULT = "id,name,host,port,info,status"
|
const FIELDS_DEFAULT = "id,name,host,port,info,status"
|
||||||
|
|
||||||
/** Maximum system name length for display purposes */
|
/** Maximum system name length for display purposes */
|
||||||
const MAX_SYSTEM_NAME_LENGTH = 20
|
const MAX_SYSTEM_NAME_LENGTH = 22
|
||||||
|
|
||||||
let initialized = false
|
let initialized = false
|
||||||
|
// biome-ignore lint/suspicious/noConfusingVoidType: typescript rocks
|
||||||
let unsub: (() => void) | undefined | void
|
let unsub: (() => void) | undefined | void
|
||||||
|
|
||||||
/** Initialize the systems manager and set up listeners */
|
/** Initialize the systems manager and set up listeners */
|
||||||
@@ -104,20 +106,37 @@ async function fetchSystems(): Promise<SystemRecord[]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Makes sure the system has valid info object and throws if not */
|
||||||
|
function validateSystemInfo(system: SystemRecord) {
|
||||||
|
if (!("cpu" in system.info)) {
|
||||||
|
throw new Error(`${system.name} has no CPU info`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Add system to both name and ID stores */
|
/** Add system to both name and ID stores */
|
||||||
export function add(system: SystemRecord) {
|
export function add(system: SystemRecord) {
|
||||||
$allSystemsByName.setKey(system.name, system)
|
try {
|
||||||
$allSystemsById.setKey(system.id, system)
|
validateSystemInfo(system)
|
||||||
|
$allSystemsByName.setKey(system.name, system)
|
||||||
|
$allSystemsById.setKey(system.id, system)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update system in stores */
|
/** Update system in stores */
|
||||||
export function update(system: SystemRecord) {
|
export function update(system: SystemRecord) {
|
||||||
// if name changed, make sure old name is removed from the name store
|
try {
|
||||||
const oldName = $allSystemsById.get()[system.id]?.name
|
validateSystemInfo(system)
|
||||||
if (oldName !== system.name) {
|
// if name changed, make sure old name is removed from the name store
|
||||||
$allSystemsByName.setKey(oldName, undefined as any)
|
const oldName = $allSystemsById.get()[system.id]?.name
|
||||||
|
if (oldName !== system.name) {
|
||||||
|
$allSystemsByName.setKey(oldName, undefined as unknown as SystemRecord)
|
||||||
|
}
|
||||||
|
add(system)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
}
|
}
|
||||||
add(system)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove system from stores */
|
/** Remove system from stores */
|
||||||
@@ -132,7 +151,7 @@ export function remove(system: SystemRecord) {
|
|||||||
/** Remove system from specific store */
|
/** Remove system from specific store */
|
||||||
function removeFromStore(system: SystemRecord, store: PreinitializedMapStore<Record<string, SystemRecord>>) {
|
function removeFromStore(system: SystemRecord, store: PreinitializedMapStore<Record<string, SystemRecord>>) {
|
||||||
const key = store === $allSystemsByName ? system.name : system.id
|
const key = store === $allSystemsByName ? system.name : system.id
|
||||||
store.setKey(key, undefined as any)
|
store.setKey(key, undefined as unknown as SystemRecord)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Action functions for subscription */
|
/** Action functions for subscription */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,15 +8,15 @@ msgstr ""
|
|||||||
"Language: is\n"
|
"Language: is\n"
|
||||||
"Project-Id-Version: beszel\n"
|
"Project-Id-Version: beszel\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-09-22 23:10\n"
|
"PO-Revision-Date: 2025-08-28 23:21\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: Icelandic\n"
|
"Language-Team: Icelandic\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Crowdin-Project: beszel\n"
|
"X-Crowdin-Project: beszel\n"
|
||||||
"X-Crowdin-Project-ID: 733311\n"
|
"X-Crowdin-Project-ID: 733311\n"
|
||||||
"X-Crowdin-Language: is\n"
|
"X-Crowdin-Language: is\n"
|
||||||
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
|
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
|
||||||
"X-Crowdin-File-ID: 32\n"
|
"X-Crowdin-File-ID: 16\n"
|
||||||
|
|
||||||
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
|
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
@@ -112,7 +112,7 @@ msgstr ""
|
|||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr ""
|
msgstr "Admin"
|
||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Agent"
|
msgid "Agent"
|
||||||
@@ -173,10 +173,6 @@ msgstr "Meðal nýting örgjörva yfir allt kerfið"
|
|||||||
msgid "Average utilization of {0}"
|
msgid "Average utilization of {0}"
|
||||||
msgstr "Meðal notkun af {0}"
|
msgstr "Meðal notkun af {0}"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "Average utilization of GPU engines"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/navbar.tsx
|
#: src/components/navbar.tsx
|
||||||
msgid "Backups"
|
msgid "Backups"
|
||||||
@@ -201,7 +197,7 @@ msgstr "Beszel notar <0>Shoutrrr</0> til að tengjast vinsælum tilkynningaþjó
|
|||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Binary"
|
msgid "Binary"
|
||||||
msgstr ""
|
msgstr "Binary"
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
@@ -367,14 +363,6 @@ msgstr ""
|
|||||||
msgid "Critical (%)"
|
msgid "Critical (%)"
|
||||||
msgstr "Kritískt (%)"
|
msgstr "Kritískt (%)"
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Cumulative Download"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Cumulative Upload"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. Context: Battery state
|
#. Context: Battery state
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Current state"
|
msgid "Current state"
|
||||||
@@ -453,10 +441,6 @@ msgstr ""
|
|||||||
msgid "Down ({downSystemsLength})"
|
msgid "Down ({downSystemsLength})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Download"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/alerts-history-columns.tsx
|
#: src/components/alerts-history-columns.tsx
|
||||||
msgid "Duration"
|
msgid "Duration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -468,7 +452,6 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
#: src/components/login/otp-forms.tsx
|
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Netfang"
|
msgstr "Netfang"
|
||||||
|
|
||||||
@@ -489,10 +472,6 @@ msgstr "Settu netfang til að endursetja lykilorð"
|
|||||||
msgid "Enter email address..."
|
msgid "Enter email address..."
|
||||||
msgstr "Settu inn Netfang..."
|
msgstr "Settu inn Netfang..."
|
||||||
|
|
||||||
#: src/components/login/otp-forms.tsx
|
|
||||||
msgid "Enter your one-time password."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
#: src/components/login/auth-form.tsx
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
#: src/components/routes/settings/config-yaml.tsx
|
#: src/components/routes/settings/config-yaml.tsx
|
||||||
@@ -563,16 +542,10 @@ msgstr ""
|
|||||||
msgid "Forgot password?"
|
msgid "Forgot password?"
|
||||||
msgstr "Gleymt lykilorð?"
|
msgstr "Gleymt lykilorð?"
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
|
||||||
msgctxt "Button to copy install command"
|
|
||||||
msgid "FreeBSD command"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. Context: Battery state
|
#. Context: Battery state
|
||||||
#: src/lib/i18n.ts
|
#: src/lib/i18n.ts
|
||||||
msgid "Full"
|
msgid "Full"
|
||||||
msgstr ""
|
msgstr "Full"
|
||||||
|
|
||||||
#. Context: General settings
|
#. Context: General settings
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
@@ -580,10 +553,6 @@ msgstr ""
|
|||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr "Almennt"
|
msgstr "Almennt"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
|
||||||
msgid "GPU Engines"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "GPU Power Draw"
|
msgid "GPU Power Draw"
|
||||||
msgstr "Skjákorts rafmagnsnotkun"
|
msgstr "Skjákorts rafmagnsnotkun"
|
||||||
@@ -600,7 +569,7 @@ msgstr "Homebrew skipun"
|
|||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Host / IP"
|
msgid "Host / IP"
|
||||||
msgstr ""
|
msgstr "Host / IP"
|
||||||
|
|
||||||
#. Context: Battery state
|
#. Context: Battery state
|
||||||
#: src/lib/i18n.ts
|
#: src/lib/i18n.ts
|
||||||
@@ -676,7 +645,6 @@ msgid "Manage display and notification preferences."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
|
||||||
msgid "Manual setup instructions"
|
msgid "Manual setup instructions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -705,15 +673,13 @@ msgstr "Nafn"
|
|||||||
|
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
msgid "Net"
|
msgid "Net"
|
||||||
msgstr ""
|
msgstr "Net"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Network traffic of docker containers"
|
msgid "Network traffic of docker containers"
|
||||||
msgstr "Net traffík docker kerfa"
|
msgstr "Net traffík docker kerfa"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Network traffic of public interfaces"
|
msgid "Network traffic of public interfaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -749,10 +715,6 @@ msgstr "OAuth 2 / OIDC stuðningur"
|
|||||||
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
|
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/login/auth-form.tsx
|
|
||||||
msgid "One-time password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
#: src/components/routes/settings/tokens-fingerprints.tsx
|
#: src/components/routes/settings/tokens-fingerprints.tsx
|
||||||
#: src/components/systems-table/systems-table-columns.tsx
|
#: src/components/systems-table/systems-table-columns.tsx
|
||||||
@@ -845,7 +807,7 @@ msgstr "Vinsamlegast skráðu þig inn á aðganginn þinn"
|
|||||||
|
|
||||||
#: src/components/add-system.tsx
|
#: src/components/add-system.tsx
|
||||||
msgid "Port"
|
msgid "Port"
|
||||||
msgstr ""
|
msgstr "Port"
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
@@ -871,14 +833,6 @@ msgstr "Lesa"
|
|||||||
msgid "Received"
|
msgid "Received"
|
||||||
msgstr "Móttekið"
|
msgstr "Móttekið"
|
||||||
|
|
||||||
#: src/components/login/login.tsx
|
|
||||||
msgid "Request a one-time password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/login/otp-forms.tsx
|
|
||||||
msgid "Request OTP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/login/forgot-pass-form.tsx
|
#: src/components/login/forgot-pass-form.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Endurstilla lykilorð"
|
msgstr "Endurstilla lykilorð"
|
||||||
@@ -928,12 +882,16 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Sent"
|
msgid "Sent"
|
||||||
msgstr ""
|
msgstr "Sent"
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
#: src/components/routes/settings/general.tsx
|
||||||
msgid "Set percentage thresholds for meter colors."
|
msgid "Set percentage thresholds for meter colors."
|
||||||
msgstr "Stilltu prósentuþröskuld fyrir mælaliti."
|
msgstr "Stilltu prósentuþröskuld fyrir mælaliti."
|
||||||
|
|
||||||
|
#: src/components/routes/settings/general.tsx
|
||||||
|
msgid "Sets the default time range for charts when a system is viewed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/command-palette.tsx
|
#: src/components/command-palette.tsx
|
||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
@@ -1044,10 +1002,6 @@ msgstr ""
|
|||||||
msgid "Throughput of root filesystem"
|
msgid "Throughput of root filesystem"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/settings/general.tsx
|
|
||||||
msgid "Time format"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/settings/notifications.tsx
|
#: src/components/routes/settings/notifications.tsx
|
||||||
msgid "To email(s)"
|
msgid "To email(s)"
|
||||||
msgstr "Til tölvupósta"
|
msgstr "Til tölvupósta"
|
||||||
@@ -1080,14 +1034,6 @@ msgstr ""
|
|||||||
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
|
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Total data received for each interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Total data sent for each interface"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/lib/alerts.ts
|
#: src/lib/alerts.ts
|
||||||
msgid "Triggers when 1 minute load average exceeds a threshold"
|
msgid "Triggers when 1 minute load average exceeds a threshold"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1149,10 +1095,6 @@ msgstr ""
|
|||||||
msgid "Up ({upSystemsLength})"
|
msgid "Up ({upSystemsLength})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "Upload"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/system.tsx
|
#: src/components/routes/system.tsx
|
||||||
msgid "Uptime"
|
msgid "Uptime"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1186,10 +1128,6 @@ msgstr ""
|
|||||||
msgid "View"
|
msgid "View"
|
||||||
msgstr "Skoða"
|
msgstr "Skoða"
|
||||||
|
|
||||||
#: src/components/routes/system/network-sheet.tsx
|
|
||||||
msgid "View more"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: src/components/routes/settings/alerts-history-data-table.tsx
|
#: src/components/routes/settings/alerts-history-data-table.tsx
|
||||||
msgid "View your 200 most recent alerts."
|
msgid "View your 200 most recent alerts."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1245,4 +1183,3 @@ msgstr ""
|
|||||||
#: src/components/routes/settings/layout.tsx
|
#: src/components/routes/settings/layout.tsx
|
||||||
msgid "Your user settings have been updated."
|
msgid "Your user settings have been updated."
|
||||||
msgstr "Notenda stillingar vistaðar."
|
msgstr "Notenda stillingar vistaðar."
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,13 @@
|
|||||||
## 0.12.8
|
## 0.12.8
|
||||||
|
|
||||||
|
- Add setting for time format (12h / 24h). (#424)
|
||||||
|
|
||||||
|
- Add experimental one-time password (OTP) support.
|
||||||
|
|
||||||
|
- Add `TRUSTED_AUTH_HEADER` environment variable for authentication forwarding. (#399)
|
||||||
|
|
||||||
|
- Add `AUTO_LOGIN` environment variable for automatic login. (#399)
|
||||||
|
|
||||||
- Add FreeBSD support for agent install script and update command.
|
- Add FreeBSD support for agent install script and update command.
|
||||||
|
|
||||||
## 0.12.7
|
## 0.12.7
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "beszel.fullname" . }}-web
|
name: {{ include "beszel.fullname" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "beszel.labels" . | nindent 4 }}
|
{{- include "beszel.labels" . | nindent 4 }}
|
||||||
{{- if .Values.service.annotations }}
|
{{- if .Values.service.annotations }}
|
||||||
|
|||||||
@@ -30,14 +30,10 @@ securityContext: {}
|
|||||||
|
|
||||||
service:
|
service:
|
||||||
enabled: true
|
enabled: true
|
||||||
type: LoadBalancer
|
annotations: {}
|
||||||
loadBalancerIP: "10.0.10.251"
|
type: ClusterIP
|
||||||
|
loadBalancerIP: ""
|
||||||
port: 8090
|
port: 8090
|
||||||
# -- Annotations for the DHCP service
|
|
||||||
annotations:
|
|
||||||
metallb.universe.tf/address-pool: pool
|
|
||||||
metallb.universe.tf/allow-shared-ip: beszel-hub-web
|
|
||||||
# -- Labels for the DHCP service
|
|
||||||
|
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false
|
||||||
@@ -96,7 +92,7 @@ persistentVolumeClaim:
|
|||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
|
|
||||||
storageClass: "retain-local-path"
|
storageClass: ""
|
||||||
|
|
||||||
# -- volume claim size
|
# -- volume claim size
|
||||||
size: "500Mi"
|
size: "500Mi"
|
||||||
|
|||||||
Reference in New Issue
Block a user