diff --git a/app/components/Notice.tsx b/app/components/Notice.tsx new file mode 100644 index 0000000..6c593c0 --- /dev/null +++ b/app/components/Notice.tsx @@ -0,0 +1,16 @@ +import { InformationCircleIcon } from '@heroicons/react/24/outline' +import clsx from 'clsx' +import { type ReactNode } from 'react' + +export default function Notice({ children }: { readonly children: ReactNode }) { + return ( +
+ + {children} +
+ ) +} diff --git a/app/routes/_data.dns._index/domains.tsx b/app/routes/_data.dns._index/domains.tsx index 1538fcf..f13d3f4 100644 --- a/app/routes/_data.dns._index/domains.tsx +++ b/app/routes/_data.dns._index/domains.tsx @@ -27,9 +27,11 @@ import TableList from '~/components/TableList' type Properties = { readonly baseDomain?: string; readonly searchDomains: string[]; + // eslint-disable-next-line react/boolean-prop-naming + readonly disabled?: boolean; } -export default function Domains({ baseDomain, searchDomains }: Properties) { +export default function Domains({ baseDomain, searchDomains, disabled }: Properties) { // eslint-disable-next-line unicorn/no-null, @typescript-eslint/ban-types const [activeId, setActiveId] = useState(null) const [localDomains, setLocalDomains] = useState(searchDomains) @@ -88,8 +90,14 @@ export default function Domains({ baseDomain, searchDomains }: Properties) { strategy={verticalListSortingStrategy} > {localDomains.map((sd, index) => ( - // eslint-disable-next-line react/no-array-index-key - + ))} {activeId ? : undefined} - - { - setNewDomain(event.target.value) - }} - /> - - + setNewDomain('') + }} + > + Add + + + )} @@ -140,9 +151,11 @@ type DomainProperties = { readonly id: number; readonly isDrag?: boolean; readonly localDomains: string[]; + // eslint-disable-next-line react/boolean-prop-naming + readonly disabled?: boolean; } -function Domain({ domain, id, localDomains, isDrag }: DomainProperties) { +function Domain({ domain, id, localDomains, isDrag, disabled }: DomainProperties) { const fetcher = useFetcher() const { @@ -169,17 +182,20 @@ function Domain({ domain, id, localDomains, isDrag }: DomainProperties) { }} >

- + {disabled ? undefined : ( + + )} {domain}

{isDrag ? undefined : ( ))} - - { - setNs(event.target.value) - }} - /> - - + setNs('') + }} + > + Add + + + ) : undefined} {/* TODO: Split DNS and Custom A Records */} @@ -148,6 +168,7 @@ export default function Page() {
@@ -162,7 +183,7 @@ export default function Page() { {' '} when Magic DNS is enabled.

- +
) diff --git a/app/utils/config.ts b/app/utils/config.ts index 1da31e3..f6ac9cb 100644 --- a/app/utils/config.ts +++ b/app/utils/config.ts @@ -141,7 +141,6 @@ export async function patchConfig(partial: Record) { } type Context = { - isDocker: boolean; hasDockerSock: boolean; hasConfigWrite: boolean; } @@ -151,7 +150,6 @@ export let context: Context export async function getContext() { if (!context) { context = { - isDocker: await checkDocker(), hasDockerSock: await checkSock(), hasConfigWrite: await checkConfigWrite() } @@ -177,20 +175,9 @@ async function checkSock() { return true } catch {} - return false -} - -async function checkDocker() { - try { - await stat('/.dockerenv') - return true - } catch {} - - try { - const data = await readFile('/proc/self/cgroup', 'utf8') - return data.includes('docker') - } catch {} + if (!process.env.HEADSCALE_CONTAINER) { + return false + } return false } - diff --git a/app/utils/docker.ts b/app/utils/docker.ts index 6861685..422238f 100644 --- a/app/utils/docker.ts +++ b/app/utils/docker.ts @@ -5,9 +5,15 @@ import { setTimeout } from 'node:timers/promises' import { Client } from 'undici' +import { getContext } from './config' import { pull } from './headscale' export async function restartHeadscale() { + const context = await getContext() + if (!context.hasDockerSock) { + return + } + if (!process.env.HEADSCALE_CONTAINER) { throw new Error('HEADSCALE_CONTAINER is not set') }