forked from github-starred/komodo
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8050db5f6 | ||
|
|
bf0a972ec2 | ||
|
|
23c1a08c87 | ||
|
|
2b6b8a21ec | ||
|
|
02974b9adb |
26
Cargo.lock
generated
26
Cargo.lock
generated
@@ -41,7 +41,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alerter"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -847,7 +847,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cache"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"tokio",
|
||||
@@ -951,7 +951,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "command"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"komodo_client",
|
||||
"run_command",
|
||||
@@ -1363,7 +1363,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "environment_file"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
@@ -1447,7 +1447,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "formatting"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"serror",
|
||||
]
|
||||
@@ -1579,7 +1579,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "git"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cache",
|
||||
@@ -2200,7 +2200,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komodo_cli"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -2216,7 +2216,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komodo_client"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async_timing_util",
|
||||
@@ -2247,7 +2247,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komodo_core"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async_timing_util",
|
||||
@@ -2307,7 +2307,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "komodo_periphery"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async_timing_util",
|
||||
@@ -2395,7 +2395,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logger"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"komodo_client",
|
||||
@@ -3101,7 +3101,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "periphery_client"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"komodo_client",
|
||||
@@ -4876,7 +4876,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "update_logger"
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"komodo_client",
|
||||
|
||||
@@ -9,7 +9,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.16.10"
|
||||
version = "1.16.11"
|
||||
edition = "2021"
|
||||
authors = ["mbecker20 <becker.maxh@gmail.com>"]
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
@@ -140,7 +140,7 @@ pub async fn send_alert(
|
||||
server_name,
|
||||
images,
|
||||
} => {
|
||||
let link = resource_link(ResourceTargetVariant::Deployment, id);
|
||||
let link = resource_link(ResourceTargetVariant::Stack, id);
|
||||
let images_label =
|
||||
if images.len() > 1 { "images" } else { "image" };
|
||||
let images = images.join(", ");
|
||||
|
||||
@@ -226,9 +226,14 @@ const komodo = KomodoClient('{base_url}', {{
|
||||
params: {{ key: '{key}', secret: '{secret}' }}
|
||||
}});
|
||||
|
||||
async function main() {{{contents}}}
|
||||
async function main() {{
|
||||
{contents}
|
||||
|
||||
main().catch(error => {{
|
||||
console.log('🦎 Action completed successfully 🦎');
|
||||
}}
|
||||
|
||||
main()
|
||||
.catch(error => {{
|
||||
console.error('🚨 Action exited early with errors 🚨')
|
||||
if (error.status !== undefined && error.result !== undefined) {{
|
||||
console.error('Status:', error.status);
|
||||
@@ -237,7 +242,7 @@ main().catch(error => {{
|
||||
console.error(JSON.stringify(error, null, 2));
|
||||
}}
|
||||
Deno.exit(1)
|
||||
}}).then(() => console.log('🦎 Action completed successfully 🦎'));"
|
||||
}});"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -114,15 +114,11 @@ impl Resolve<build::Build> for State {
|
||||
let buildx = if *use_buildx { " buildx" } else { "" };
|
||||
let image_tags =
|
||||
image_tags(&image_name, image_tag, version, &additional_tags);
|
||||
let push_command = should_push
|
||||
.then(|| {
|
||||
format!(" && docker image push --all-tags {image_name}")
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let maybe_push = if should_push { " --push" } else { "" };
|
||||
|
||||
// Construct command
|
||||
let command = format!(
|
||||
"docker{buildx} build{build_args}{command_secret_args}{extra_args}{labels}{image_tags} -f {dockerfile_path} .{push_command}",
|
||||
"docker{buildx} build{build_args}{command_secret_args}{extra_args}{labels}{image_tags}{maybe_push} -f {dockerfile_path} .",
|
||||
);
|
||||
|
||||
if *skip_secret_interp {
|
||||
|
||||
@@ -945,17 +945,24 @@ pub async fn docker_login(
|
||||
None => crate::helpers::registry_token(domain, account)?,
|
||||
};
|
||||
let log = async_run_command(&format!(
|
||||
"docker login {domain} -u {account} -p {registry_token}",
|
||||
"echo {registry_token} | docker login {domain} --username {account} --password-stdin",
|
||||
))
|
||||
.await;
|
||||
if log.success() {
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"{domain} login error: stdout: {} | stderr: {}",
|
||||
log.stdout,
|
||||
log.stderr
|
||||
))
|
||||
let mut e = anyhow!("End of trace");
|
||||
for line in
|
||||
log.stderr.split('\n').filter(|line| !line.is_empty()).rev()
|
||||
{
|
||||
e = e.context(line.to_string());
|
||||
}
|
||||
for line in
|
||||
log.stdout.split('\n').filter(|line| !line.is_empty()).rev()
|
||||
{
|
||||
e = e.context(line.to_string());
|
||||
}
|
||||
Err(e.context(format!("Registry {domain} login error")))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "komodo_client",
|
||||
"version": "1.16.10",
|
||||
"version": "1.16.11",
|
||||
"description": "Komodo client package",
|
||||
"homepage": "https://komo.do",
|
||||
"main": "dist/lib.js",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useAllResources, useUser } from "@lib/hooks";
|
||||
import { useAllResources, useLocalStorage, useRead, useUser } from "@lib/hooks";
|
||||
import { Button } from "@ui/button";
|
||||
import {
|
||||
CommandDialog,
|
||||
@@ -9,12 +9,14 @@ import {
|
||||
CommandSeparator,
|
||||
CommandItem,
|
||||
} from "@ui/command";
|
||||
import { Home, Search, User } from "lucide-react";
|
||||
import { Box, Home, Search, User } from "lucide-react";
|
||||
import { Fragment, ReactNode, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { cn, RESOURCE_TARGETS, usableResourcePath } from "@lib/utils";
|
||||
import { Badge } from "@ui/badge";
|
||||
import { ResourceComponents } from "./resources";
|
||||
import { Switch } from "@ui/switch";
|
||||
import { DOCKER_LINK_ICONS } from "./util";
|
||||
|
||||
export const OmniSearch = ({
|
||||
className,
|
||||
@@ -67,6 +69,10 @@ export const OmniDialog = ({
|
||||
navigate(value);
|
||||
};
|
||||
const items = useOmniItems(nav, search);
|
||||
const [showContainers, setShowContainers] = useLocalStorage(
|
||||
"omni-show-containers",
|
||||
false
|
||||
);
|
||||
return (
|
||||
<CommandDialog open={open} onOpenChange={setOpen} manualFilter>
|
||||
<CommandInput
|
||||
@@ -74,6 +80,10 @@ export const OmniDialog = ({
|
||||
value={search}
|
||||
onValueChange={setSearch}
|
||||
/>
|
||||
<div className="flex gap-2 text-xs items-center justify-end px-2 py-1">
|
||||
<div className="text-muted-foreground">Show containers</div>
|
||||
<Switch checked={showContainers} onCheckedChange={setShowContainers} />
|
||||
</div>
|
||||
<CommandList>
|
||||
<CommandEmpty>No results found.</CommandEmpty>
|
||||
|
||||
@@ -97,6 +107,10 @@ export const OmniDialog = ({
|
||||
</CommandGroup>
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
{showContainers && (
|
||||
<OmniContainers search={search} closeSearch={() => setOpen(false)} />
|
||||
)}
|
||||
</CommandList>
|
||||
</CommandDialog>
|
||||
);
|
||||
@@ -108,12 +122,12 @@ const useOmniItems = (
|
||||
): Record<string, OmniItem[]> => {
|
||||
const user = useUser().data;
|
||||
const resources = useAllResources();
|
||||
const searchTerms = search
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.filter((term) => term);
|
||||
return useMemo(
|
||||
() => ({
|
||||
return useMemo(() => {
|
||||
const searchTerms = search
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.filter((term) => term);
|
||||
return {
|
||||
"": [
|
||||
{
|
||||
key: "Home",
|
||||
@@ -136,6 +150,12 @@ const useOmniItems = (
|
||||
onSelect: () => nav(usableResourcePath(_type)),
|
||||
};
|
||||
}),
|
||||
{
|
||||
key: "Containers",
|
||||
label: "Containers",
|
||||
icon: <Box className="w-4 h-4" />,
|
||||
onSelect: () => nav("/containers"),
|
||||
},
|
||||
(user?.admin && {
|
||||
key: "Users",
|
||||
label: "Users",
|
||||
@@ -159,20 +179,21 @@ const useOmniItems = (
|
||||
: _type === "ServerTemplate"
|
||||
? "Template"
|
||||
: _type;
|
||||
const lower = type.toLowerCase();
|
||||
const lower_type = type.toLowerCase();
|
||||
const Components = ResourceComponents[_type];
|
||||
return [
|
||||
type + "s",
|
||||
resources[_type]
|
||||
?.filter(
|
||||
(item) =>
|
||||
?.filter((item) => {
|
||||
const lower_name = item.name.toLowerCase();
|
||||
return (
|
||||
searchTerms.length === 0 ||
|
||||
searchTerms.every(
|
||||
(term) =>
|
||||
item.name.toLowerCase().includes(term) ||
|
||||
lower.includes(term)
|
||||
lower_name.includes(term) || lower_type.includes(term)
|
||||
)
|
||||
)
|
||||
);
|
||||
})
|
||||
.map((server) => ({
|
||||
key: type + "-" + server.name,
|
||||
label: server.name,
|
||||
@@ -183,7 +204,57 @@ const useOmniItems = (
|
||||
];
|
||||
})
|
||||
),
|
||||
}),
|
||||
[user, resources, search]
|
||||
};
|
||||
}, [user, resources, search]);
|
||||
};
|
||||
|
||||
const OmniContainers = ({
|
||||
search,
|
||||
closeSearch,
|
||||
}: {
|
||||
search: string;
|
||||
closeSearch: () => void;
|
||||
}) => {
|
||||
const _containers = useRead("ListAllDockerContainers", {}).data;
|
||||
const containers = useMemo(() => {
|
||||
return _containers?.filter((c) => {
|
||||
const searchTerms = search
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.filter((term) => term);
|
||||
if (searchTerms.length === 0) return true;
|
||||
const lower = c.name.toLowerCase();
|
||||
return searchTerms.every(
|
||||
(term) => lower.includes(term) || "containers".includes(term)
|
||||
);
|
||||
});
|
||||
}, [_containers, search]);
|
||||
const navigate = useNavigate();
|
||||
if ((containers?.length ?? 0) < 1) return null;
|
||||
return (
|
||||
<>
|
||||
<CommandSeparator />
|
||||
<CommandGroup heading="Containers">
|
||||
{containers?.map((container) => (
|
||||
<CommandItem
|
||||
key={container.id}
|
||||
value={container.name}
|
||||
className="flex items-center gap-2 cursor-pointer"
|
||||
onSelect={() => {
|
||||
closeSearch();
|
||||
navigate(
|
||||
`/servers/${container.server_id!}/container/${container.name}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
<DOCKER_LINK_ICONS.container
|
||||
server_id={container.server_id!}
|
||||
name={container.name}
|
||||
/>
|
||||
{container.name}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,10 @@ import { Fragment, useCallback, useMemo, useState } from "react";
|
||||
|
||||
export const ContainersPage = () => {
|
||||
const [search, setSearch] = useState("");
|
||||
const searchSplit = search.toLowerCase().split(" ");
|
||||
const searchSplit = search
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.filter((term) => term);
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const serverName = useCallback(
|
||||
(id: string) => servers?.find((server) => server.id === id)?.name,
|
||||
@@ -21,7 +24,8 @@ export const ContainersPage = () => {
|
||||
() =>
|
||||
_containers?.filter((c) => {
|
||||
if (searchSplit.length === 0) return true;
|
||||
return searchSplit.every((search) => c.name.includes(search));
|
||||
const lower = c.name.toLowerCase();
|
||||
return searchSplit.every((search) => lower.includes(search));
|
||||
}),
|
||||
[_containers, searchSplit]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user