Skip to content

Commit

Permalink
Merge pull request #24 from vertex-center/feature/scalable-containers…
Browse files Browse the repository at this point in the history
…-app

First draft of the new Vertex Containers compatibility
  • Loading branch information
quentinguidee authored Dec 17, 2023
2 parents 2478ed2 + c369dd3 commit f09dd27
Show file tree
Hide file tree
Showing 29 changed files with 379 additions and 456 deletions.
113 changes: 113 additions & 0 deletions src/apps/Containers/backend/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { createServer } from "../../../backend/server";
import {
Container,
ContainerFilters,
Containers,
EnvVariables,
Tags,
} from "./models";
import { DockerContainerInfo } from "../../../models/docker";
import { Service } from "./service";

// @ts-ignore
const server = createServer(window.api_urls.containers);

const getContainers = async (query?: ContainerFilters) => {
const { data } = await server.get<Containers>(`/containers`, {
params: query,
});
return data;
};

const getAllTags = async () => {
const { data } = await server.get<Tags>(`/tags`);
return data;
};

const installService = async (serviceId: string) => {
const { data } = await server.post(`/service/${serviceId}/install`);
return data;
};

const getAllServices = async () => {
const { data } = await server.get<Service[]>(`/services`);
return data;
};

const getContainer = async (id: string) => {
const { data } = await server.get<Container>(`/container/${id}`);
return data;
};

const deleteContainer = (id: string) => {
return server.delete(`/container/${id}`);
};

const startContainer = (id: string) => {
return server.post(`/container/${id}/start`);
};

const stopContainer = (id: string) => {
return server.post(`/container/${id}/stop`);
};

const patchContainer = (id: string, params: any) => {
return server.patch(`/container/${id}`, params);
};

const getLogs = async (id: string) => {
const { data } = await server.get(`/container/${id}/logs`);
return data;
};

const getContainerEnvironment = async (id: string) => {
const { data } = await server.get<EnvVariables>(
`/container/${id}/environment`
);
return data;
};

const saveEnv = (id: string, env: EnvVariables) => {
return server.patch(`/container/${id}/environment`, { env });
};

const getDocker = async (id: string) => {
const { data } = await server.get<DockerContainerInfo>(
`/container/${id}/docker`
);
return data;
};

const recreateDocker = (id: string) => {
return server.post(`/container/${id}/docker/recreate`);
};

const updateService = (id: string) => {
return server.post(`/container/${id}/update/service`);
};

const getVersions = async (id: string, cache?: boolean) => {
const { data } = await server.get<string[]>(
`/container/${id}/versions?cache=${cache}`
);
return data;
};

export const API = {
getContainer,
getContainers,
getAllTags,
deleteContainer,
startContainer,
stopContainer,
patchContainer,
getLogs,
getContainerEnvironment,
saveEnv,
getDockerInfo: getDocker,
recreateDocker,
updateService,
getVersions,
installService,
getAllServices,
};
72 changes: 72 additions & 0 deletions src/apps/Containers/backend/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
export type ContainerFilters = {
features?: string[];
tags?: string[];
};

export type ContainerUpdate = {
current_version: string;
latest_version: string;
};

export type ServiceUpdate = {
available?: boolean;
};

export type Tags = Tag[];
export type Tag = {
container_id: string;
tag: string;
};

export type EnvVariables = EnvVariable[];
export type EnvVariable = {
container_id: string;
type: string;
name: string;
display_name: string;
value: string;
default: string;
description: string;
secret: boolean;
};

export type Containers = Container[];
export type Container = {
id: string;
service_id: string;
user_id: string;
image: string;
image_tag: string;
status: string;
launch_on_startup: boolean;
name: string;
description?: string;
color?: string;
icon?: string;
command?: string;
environment: EnvVariables;
capabilities: {
container_id: string;
name: string;
};
ports: {
container_id: string;
in: string;
out: string;
}[];
volumes: {
container_id: string;
in: string;
out: string;
}[];
sysctls: {
container_id: string;
name: string;
value: string;
}[];
tags: Tags;

update?: ContainerUpdate;
service_update?: ServiceUpdate;
databases?: { [key: string]: string };
};
File renamed without changes.
25 changes: 11 additions & 14 deletions src/apps/Containers/components/ContainerSelect/ContainerSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { SelectField, SelectOption } from "@vertex-center/components";
import { Container, ContainerQuery } from "../../../../models/container";
import { api } from "../../../../backend/api/backend";
import Progress from "../../../../components/Progress";
import ServiceLogo from "../../../../components/ServiceLogo/ServiceLogo";
import { useQuery } from "@tanstack/react-query";
import { APIError } from "../../../../components/Error/APIError";
import { Fragment } from "react";
import { API } from "../../backend/api";
import { Container, ContainerFilters } from "../../backend/models";

type Props = {
container?: Container;
onChange?: (container?: Container) => void;

query?: ContainerQuery;
filters?: ContainerFilters;
};

export default function ContainerSelect(props: Readonly<Props>) {
const { container, onChange, query } = props;
const { container, onChange, filters } = props;

const queryContainers = useQuery({
queryKey: ["containers", query],
queryFn: () => api.vxContainers.containers.search(query),
queryKey: ["containers", filters],
queryFn: () => API.getContainers(filters),
});
const { data: containers, isLoading, error } = queryContainers;

Expand All @@ -39,20 +38,18 @@ export default function ContainerSelect(props: Readonly<Props>) {
const value = (
<Fragment>
{container && <ServiceLogo service={container?.service} />}
{container?.display_name ??
container?.service?.name ??
"Select an container"}
{container?.name ?? "Select an container"}
</Fragment>
);

return (
// @ts-ignore
<SelectField onChange={onContainerChange} value={value}>
<SelectOption value="">None</SelectOption>
{Object.entries(containers ?? [])?.map(([, container]) => (
<SelectOption key={container.uuid} value={container.uuid}>
<ServiceLogo service={container?.service} />
{container?.display_name ?? container?.service?.name}
{Object.entries(containers ?? [])?.map(([, c]) => (
<SelectOption key={c?.id} value={c?.id}>
<ServiceLogo service={c?.service} />
{c?.name}
</SelectOption>
))}
</SelectField>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TextField } from "@vertex-center/components";
import TimezoneField from "../../../../components/TimezoneField/TimezoneField";
import { EnvVariable } from "../../../../models/service";
import { EnvVariable } from "../../backend/models";

type Props = {
id: string;
Expand Down
8 changes: 4 additions & 4 deletions src/apps/Containers/components/SelectTags/SelectTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function SelectTags(props: Readonly<Props>) {
const { selected } = props;
const { tags, isLoading, isError } = useContainersTags();

tags?.sort((a, b) => a.localeCompare(b));
tags?.sort((a, b) => a.tag.localeCompare(b.tag));

const count = selected?.length;

Expand All @@ -33,11 +33,11 @@ export default function SelectTags(props: Readonly<Props>) {
>
{tags?.map((tag) => (
<SelectOption
key={tag}
key={tag.tag}
value={tag}
selected={selected.includes(tag)}
selected={selected.includes(tag.tag)}
>
{tag}
{tag.tag}
</SelectOption>
))}
</SelectField>
Expand Down
32 changes: 22 additions & 10 deletions src/apps/Containers/hooks/useContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
import { api } from "../../../backend/api/backend";
import { useQuery } from "@tanstack/react-query";
import { API } from "../backend/api";

export default function useContainer(uuid?: string) {
export default function useContainer(id?: string) {
const queryContainer = useQuery({
queryKey: ["containers", uuid],
queryFn: api.vxContainers.container(uuid).get,
queryKey: ["containers", id],
queryFn: () => API.getContainer(id),
});
return { container: queryContainer.data, ...queryContainer };
}

export function useContainerLogs(uuid?: string) {
export function useContainerLogs(id?: string) {
const queryLogs = useQuery({
queryKey: ["container_logs", uuid],
queryFn: api.vxContainers.container(uuid).logs.get,
queryKey: ["container_logs", id],
queryFn: () => API.getLogs(id),
});
return { logs: queryLogs.data, ...queryLogs };
}

export function useDockerInfo(uuid?: string) {
export function useDockerInfo(id?: string) {
const queryDockerInfo = useQuery({
queryKey: ["container_docker", uuid],
queryFn: api.vxContainers.container(uuid).docker.get,
queryKey: ["container_docker", id],
queryFn: () => API.getDockerInfo(id),
});
return { dockerInfo: queryDockerInfo.data, ...queryDockerInfo };
}

export function useContainerEnv(id?: string) {
const queryEnv = useQuery({
queryKey: ["container_env", id],
queryFn: () => API.getContainerEnvironment(id),
});
return {
env: queryEnv.data,
isLoadingEnv: queryEnv.isLoading,
errorEnv: queryEnv.error,
};
}
10 changes: 5 additions & 5 deletions src/apps/Containers/hooks/useContainers.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { useQuery } from "@tanstack/react-query";
import { api } from "../../../backend/api/backend";
import { ContainerQuery } from "../../../models/container";
import { API } from "../backend/api";
import { ContainerFilters } from "../backend/models";

export function useContainersTags() {
const queryTags = useQuery({
queryKey: ["containers", "tags"],
queryFn: api.vxContainers.containers.tags,
queryFn: API.getAllTags,
});
const { data: tags } = queryTags;
return { tags, ...queryTags };
}

export function useContainers(query: ContainerQuery) {
export function useContainers(query: ContainerFilters) {
const queryContainers = useQuery({
queryKey: ["containers", query],
queryFn: () => api.vxContainers.containers.search(query),
queryFn: () => API.getContainers(query),
});
const { data: containers } = queryContainers;
return { containers, ...queryContainers };
Expand Down
Loading

0 comments on commit f09dd27

Please sign in to comment.