Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option to generate moon #503

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .devcontainer/init-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -U "$POSTGRES_USER"
sleep 1
done

# Install openssl
wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1n-0+deb10u6_amd64.deb
sudo dpkg -i libssl1.1_1.1.1n-0+deb10u6_amd64.deb

# Check architecture and copy the corresponding file if it exists
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ] && [ -f "/workspaces/ztnodeid/build/linux_amd64/ztmkworld" ]; then
cp /workspaces/ztnodeid/build/linux_amd64/ztmkworld /usr/local/bin/ztmkworld
elif [ "$ARCH" = "aarch64" ] && [ -f "/workspaces/ztnodeid/build/linux_arm64/ztmkworld" ]; then
cp /workspaces/ztnodeid/build/linux_arm64/ztmkworld /usr/local/bin/ztmkworld
if [ "$ARCH" = "x86_64" ] && [ -f "/workspaces/bin/mkworld/build/linux_amd64/ztmkworld" ]; then
cp /workspaces/bin/mkworld/build/linux_amd64/ztmkworld /usr/local/bin/ztmkworld
cp /workspaces/bin/idtool/build/linux_amd64/zerotier-idtool /usr/local/bin/zerotier-idtool
elif [ "$ARCH" = "aarch64" ] && [ -f "/workspaces/bin/mkworld/build/linux_arm64/ztmkworld" ]; then
cp /workspaces/bin/mkworld/build/linux_arm64/ztmkworld /usr/local/bin/ztmkworld
cp /workspaces/bin/idtool/build/linux_arm64/zerotier-idtool /usr/local/bin/zerotier-idtool
fi

chmod +x /usr/local/bin/ztmkworld

# apply migrations to the database
Expand Down
42 changes: 34 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,24 @@ RUN SKIP_ENV_VALIDATION=1 npm run build
# Copy the ztmkworld binary based on the target platform architecture
FROM base AS ztmkworld_builder
ARG TARGETPLATFORM

WORKDIR /app
COPY ztnodeid/build/linux_amd64/ztmkworld ztmkworld_amd64
COPY ztnodeid/build/linux_arm64/ztmkworld ztmkworld_arm64
RUN \
case "${TARGETPLATFORM}" in \
"linux/amd64") cp ztmkworld_amd64 /usr/local/bin/ztmkworld ;; \
"linux/arm64") cp ztmkworld_arm64 /usr/local/bin/ztmkworld ;; \

COPY bin/mkworld/build/linux_amd64/ztmkworld ztmkworld_amd64
COPY bin/mkworld/build/linux_arm64/ztmkworld ztmkworld_arm64
COPY bin/idtool/build/linux_amd64/zerotier-idtool zerotier-idtool_amd64
COPY bin/idtool/build/linux_arm64/zerotier-idtool zerotier-idtool_arm64

RUN case "${TARGETPLATFORM}" in \
"linux/amd64") \
cp ztmkworld_amd64 /usr/local/bin/ztmkworld && \
cp zerotier-idtool_amd64 /usr/local/bin/zerotier-idtool ;; \
"linux/arm64") \
cp ztmkworld_arm64 /usr/local/bin/ztmkworld && \
cp zerotier-idtool_arm64 /usr/local/bin/zerotier-idtool ;; \
*) echo "Unsupported architecture" && exit 1 ;; \
esac && \
chmod +x /usr/local/bin/ztmkworld
chmod +x /usr/local/bin/ztmkworld /usr/local/bin/zerotier-idtool

# Production image, copy all the files and run next
FROM $NODEJS_IMAGE AS runner
Expand All @@ -65,7 +73,24 @@ ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN apt update && apt install -y curl sudo postgresql-client && apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN apt update && apt install -y curl wget sudo postgresql-client && apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Openssl 1.1.1n is required for the zerotier-idtool
RUN ARCH=$(dpkg --print-architecture) && \
if [ "$ARCH" = "amd64" ]; then \
wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1n-0+deb10u6_amd64.deb; \
dpkg -i libssl1.1_1.1.1n-0+deb10u6_amd64.deb; \
rm libssl1.1_1.1.1n-0+deb10u6_amd64.deb; \
elif [ "$ARCH" = "arm64" ]; then \
wget http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1n-0+deb10u6_arm64.deb; \
dpkg -i libssl1.1_1.1.1n-0+deb10u6_arm64.deb; \
rm libssl1.1_1.1.1n-0+deb10u6_arm64.deb; \
else \
echo "Unsupported architecture: $ARCH"; \
exit 1; \
fi


# need to install these package for seeding the database
RUN npm install @prisma/client @paralleldrive/cuid2
RUN npm install -g prisma ts-node
Expand All @@ -82,6 +107,7 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
COPY --from=builder --chown=nextjs:nodejs /app/init-db.sh ./init-db.sh
COPY --from=ztmkworld_builder /usr/local/bin/ztmkworld /usr/local/bin/ztmkworld
COPY --from=ztmkworld_builder /usr/local/bin/zerotier-idtool /usr/local/bin/zerotier-idtool

# prepeare .env file for the init-db.sh script
RUN touch .env && chown nextjs:nodejs .env
Expand Down
28 changes: 28 additions & 0 deletions bin/idtool/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# syntax=docker/dockerfile:1

# Build stage
FROM --platform=$TARGETPLATFORM ubuntu:20.04 AS builder

ARG TARGETPLATFORM
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
curl \
gnupg \
lsb-release \
&& rm -rf /var/lib/apt/lists/*

# Add ZeroTier repository and install
RUN curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg' | gpg --dearmor > /usr/share/keyrings/zerotier-archive-keyring.gpg
RUN echo "deb [signed-by=/usr/share/keyrings/zerotier-archive-keyring.gpg] http://download.zerotier.com/debian/$(lsb_release -cs) $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/zerotier.list

RUN apt-get update && apt-get install -y zerotier-one

# Final stage
FROM scratch AS export-stage

# Copy zerotier-idtool from the builder stage
COPY --from=builder /usr/sbin/zerotier-idtool .

# Build command:
# docker buildx build --platform linux/amd64,linux/arm64 --target export-stage -o type=local,dest=./build .
Binary file added bin/idtool/build/linux_amd64/zerotier-idtool
Binary file not shown.
Binary file added bin/idtool/build/linux_arm64/zerotier-idtool
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/docs/Installation/FreeBSD.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ setenv PRISMA_QUERY_ENGINE_LIBRARY /root/prisma-engines/target/release/libquery_

8. Copy mkworld binary:
```bash
cp ztnodeid/build/freebsd_amd64/ztmkworld /usr/local/bin/ztmkworld
cp bin/mkworld/build/freebsd_amd64/ztmkworld /usr/local/bin/ztmkworld
```
9. Run server:
```bash
Expand Down
2 changes: 1 addition & 1 deletion install.ztnet/bash/ztnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ pull_checkout_ztnet
check_postgres_access_and_prompt_password "$POSTGRES_USER" "$POSTGRES_PASSWORD" "$POSTGRES_DB"

# Copy mkworld binary
cp "$TEMP_REPO_DIR/ztnodeid/build/linux_$ARCH/ztmkworld" /usr/local/bin/ztmkworld
cp "$TEMP_REPO_DIR/bin/mkworld/build/linux_$ARCH/ztmkworld" /usr/local/bin/ztmkworld
NEXT_PUBLIC_APP_VERSION="${CUSTOM_VERSION:-$latestTag}"


Expand Down
5 changes: 5 additions & 0 deletions prisma/migrations/20240820103254_moon/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Planet" ADD COLUMN "isMoon" BOOLEAN NOT NULL DEFAULT false;

-- AlterTable
ALTER TABLE "RootNodes" ADD COLUMN "isMoon" BOOLEAN NOT NULL DEFAULT false;
2 changes: 2 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ model Planet {
plID BigInt @default(0)
plBirth BigInt @default(0)
plRecommend Boolean @default(false)
isMoon Boolean @default(false)
rootNodes RootNodes[]
globalOptions GlobalOptions?
}
Expand All @@ -68,6 +69,7 @@ model RootNodes {
id Int @id @default(autoincrement())
Planet Planet @relation(fields: [PlanetId], references: [id], onDelete: Cascade)
PlanetId Int
isMoon Boolean @default(false)
comments String?
identity String
endpoints Json
Expand Down
79 changes: 60 additions & 19 deletions src/components/adminPage/controller/privateRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ const PrivateRoot = () => {
toast.error(error.message);
});
};

// generate the moon id from the first node that has ismoon set to true
const isMoonIdentity = getPlanet?.rootNodes?.filter((node) => node.isMoon);
const moonId = isMoonIdentity?.[0]?.identity.trim().split(":")[0];

return (
<div className="space-y-4">
<div>
Expand Down Expand Up @@ -124,7 +129,10 @@ const PrivateRoot = () => {
</div>
<div className="space-y-5">
{getPlanet?.rootNodes?.map((node, i) => (
<div key={node.id} className="border border-primary rounded p-4 my-4">
<div
key={node.id}
className="border border-primary rounded p-4 my-4 space-y-5"
>
{!node.endpoints.toString().includes("9993") ? (
<div role="alert" className="alert shadow-lg mb-5">
<svg
Expand Down Expand Up @@ -157,27 +165,60 @@ const PrivateRoot = () => {
</div>
</div>
) : null}
<p className="tracking-wide font-medium">Root #{i + 1}</p>
<p>
<strong>Comments:</strong> {node.comments}
</p>
<p>
<strong>Endpoints:</strong> {node.endpoints.toString()}
</p>
<p>
<strong>Identity:</strong> {node.identity.substring(0, 50)}
</p>
<section>
<div className="flex justify-between">
<p className="tracking-wide font-medium">Root #{i + 1}</p>
{node.isMoon ? (
<kbd className="kbd px-2 py-1 rounded text-sm font-mono">
{`zerotier-cli orbit ${moonId} ${
node.identity.split(":")[0]
}`}
</kbd>
) : null}
</div>
<p>
<strong>Comments:</strong> {node.comments}
</p>
<p>
<strong>Endpoints:</strong> {node.endpoints.toString()}
</p>
<p>
<strong>Identity:</strong> {node.identity.substring(0, 50)}
</p>
<p>
<strong>WorldType:</strong> {node.isMoon ? "Moon" : "Planet"}
</p>
</section>
<section>
{node.isMoon ? (
<div className="space-y-4">
<div className="flex items-center gap-2">
<p className="text-sm">
Moon file is available for download at the following URL:
</p>
<Link
href="/api/moon"
className="text-blue-500 hover:underline"
>
api/moon
</Link>
</div>
</div>
) : (
<span className="text-sm flex gap-1">
{/* {t("controller.generatePlanet.downloadPlanetInfo")} */}
<p>
Planet file is available for download at the following URL:
</p>
<Link href="/api/planet" className="link text-blue-500">
{t("controller.generatePlanet.downloadPlanetUrl")}
</Link>
</span>
)}
</section>
</div>
))}
</div>
<div>
<p className=" text-sm">
{t("controller.generatePlanet.downloadPlanetInfo")}{" "}
<Link href="/api/planet" className="link text-blue-500">
{t("controller.generatePlanet.downloadPlanetUrl")}
</Link>
</p>
</div>
<div className="flex justify-between">
<div className="flex gap-3">
<button
Expand Down
45 changes: 41 additions & 4 deletions src/components/adminPage/controller/rootForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface RootNode {
endpoints: JsonValue;
comments: string;
identity: string;
isMoon: boolean;
}

interface RootNodesArrayProps {
Expand All @@ -25,23 +26,26 @@ interface RootNodesArrayProps {
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
index: number,
) => void;
handleMoonToggle: (index: number) => void;
}

const RootNodesArray: React.FC<RootNodesArrayProps> = ({
rootNodes,
handleEndpointArrayChange,
handleAddClick,
handleRemoveClick,
handleMoonToggle,
}) => {
const t = useTranslations("admin");
const b = useTranslations("commonButtons");
return (
<div className="space-y-10">
{rootNodes.map((node, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
<div key={i} className="p-5 border rounded-md border-primary">
<div key={i} className="p-5 border rounded-md border-primary space-y-5">
<p>Root #{i + 1}</p>
<label className="block text-gray-500 mb-2">

<label className="block text-sm text-gray-500 mb-2">
{t("controller.generatePlanet.endpointsDescription")}
</label>
<div className="space-y-3">
Expand Down Expand Up @@ -70,6 +74,25 @@ const RootNodesArray: React.FC<RootNodesArrayProps> = ({
</button>
</div>
) : null}
<div className="flex flex-col space-y-1">
<div className="flex gap-2">
<span className="label-text">Is Moon?</span>
<input
name="isMoon"
type="checkbox"
checked={node.isMoon}
className="checkbox checkbox-primary checkbox-sm"
onChange={() => handleMoonToggle(i)}
/>
</div>
<p className="text-sm text-gray-600">
Check this box if this root should be a moon. Moons are user-defined root
servers that operate alongside ZeroTier's default root servers (planets).
They don't make your network private, but can improve performance,
especially in regions with poor connectivity to the default roots. Moons can
also provide continuity if the default roots are unreachable.
</p>
</div>
</div>
))}
<div>
Expand Down Expand Up @@ -99,12 +122,12 @@ const RootForm: React.FC<{ onClose: () => void }> = ({ onClose }) => {
rootNodes: [
{
endpoints: [],
isMoon: false,
comments: "",
identity: "",
},
] as Partial<RootNodes>[],
});

useEffect(() => {
setWorld((prev) => {
// Use existing data from getOptions.rootNodes if available
Expand All @@ -121,6 +144,7 @@ const RootForm: React.FC<{ onClose: () => void }> = ({ onClose }) => {

return {
...prev, // Spread the previous state
isMoon: getPlanet?.isMoon,
plRecommend:
getPlanet?.plRecommend !== undefined
? getPlanet?.plRecommend
Expand Down Expand Up @@ -209,7 +233,18 @@ const RootForm: React.FC<{ onClose: () => void }> = ({ onClose }) => {
e.preventDefault();
setWorld((prev) => ({
...prev,
rootNodes: [...prev.rootNodes, { endpoints: "", identity: "", comments: "" }],
rootNodes: [
...prev.rootNodes,
{ endpoints: "", identity: "", comments: "", isMoon: false },
],
}));
};
const handleMoonToggle = (index) => {
setWorld((prev) => ({
...prev,
rootNodes: prev.rootNodes.map((node, i) =>
i === index ? { ...node, isMoon: !node.isMoon } : node,
),
}));
};
const handleRemoveClick = (e, index) => {
Expand All @@ -222,6 +257,7 @@ const RootForm: React.FC<{ onClose: () => void }> = ({ onClose }) => {
rootNodes: [...roots],
}));
};

return (
<>
{/* Display list of root nodes */}
Expand Down Expand Up @@ -277,6 +313,7 @@ const RootForm: React.FC<{ onClose: () => void }> = ({ onClose }) => {
handleEndpointArrayChange={handleEndpointArrayChange}
handleAddClick={handleAddClick}
handleRemoveClick={handleRemoveClick}
handleMoonToggle={handleMoonToggle}
/>

<div className="pt-10">
Expand Down
Loading
Loading