Skip to content
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: 15 additions & 0 deletions talos/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
VENDOR=Siderolabs
NAME=Talos
IMAGE_FORMAT=qcow2
IMAGE_GLOB=*.qcow2

VERSION=$(shell echo $(IMAGE) | sed -e 's/\(.\+\)-metal-amd64.*/\1/')

-include ../makefile-sanity.include
-include ../makefile.include

download:
/bin/bash download.sh

build: download
$(MAKE) docker-image
20 changes: 20 additions & 0 deletions talos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Talos Linux VM

The [download.sh](download.sh) script will download Talos Linux with serial console enabled. The version is set in the script and can be changed manually.


The following command can be executed to download and build the Talos Linux VM container:

```bash
make build
```

The resulting container will be tagged as `vrnetlab/siderolabs_talos:<version>`.

## Host requirements

* 4 vCPU, 4 GB RAM

## Configuration

No initial configuration is provided (yet)
41 changes: 41 additions & 0 deletions talos/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM public.ecr.aws/docker/library/debian:bookworm-slim AS builder

ARG DISK_SIZE=64G

RUN apt-get update -qy && \
apt-get install -y --no-install-recommends qemu-utils && \
rm -rf /var/lib/apt/lists/*

ARG IMAGE
COPY $IMAGE* /
RUN qemu-img resize /$IMAGE $DISK_SIZE

FROM public.ecr.aws/docker/library/debian:bookworm-slim

ARG DEBIAN_FRONTEND=noninteractive
ARG DISK_SIZE=64G

RUN apt-get update -qy \
&& apt-get install -y --no-install-recommends\
bridge-utils \
iproute2 \
socat \
qemu-kvm \
tcpdump \
ssh \
inetutils-ping \
dnsutils \
iptables \
nftables \
telnet \
cloud-utils \
sshpass \
&& rm -rf /var/lib/apt/lists/*

ARG IMAGE
COPY --from=builder $IMAGE* /
COPY *.py /

EXPOSE 22 5000 10000-10099
HEALTHCHECK CMD ["/healthcheck.py"]
ENTRYPOINT ["/launch.py"]
133 changes: 133 additions & 0 deletions talos/docker/launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env python3

import datetime
import logging
import os
import re
import signal
import subprocess
import sys

import vrnetlab


def handle_SIGCHLD(signal, frame):
os.waitpid(-1, os.WNOHANG)


def handle_SIGTERM(signal, frame):
sys.exit(0)


signal.signal(signal.SIGINT, handle_SIGTERM)
signal.signal(signal.SIGTERM, handle_SIGTERM)
signal.signal(signal.SIGCHLD, handle_SIGCHLD)

TRACE_LEVEL_NUM = 9
logging.addLevelName(TRACE_LEVEL_NUM, "TRACE")


def trace(self, message, *args, **kws):
# Yes, logger takes its '*args' as 'args'.
if self.isEnabledFor(TRACE_LEVEL_NUM):
self._log(TRACE_LEVEL_NUM, message, args, **kws)


logging.Logger.trace = trace


class Talos_vm(vrnetlab.VM):
def __init__(
self,
nics,
conn_mode,
):
for e in os.listdir("/"):
if re.search(".qcow2$", e):
disk_image = "/" + e

super(Talos_vm, self).__init__(
"","",
disk_image=disk_image, ram=4192
)

self.num_nics = nics
self.nic_type = "virtio-net-pci"
self.conn_mode = conn_mode

if "ADD_DISK" in os.environ:
disk_size = os.getenv("ADD_DISK")

self.add_disk(disk_size)


def bootstrap_spin(self):
"""This function should be called periodically to do work."""
return

def gen_mgmt(self):
"""
Augment the parent class function to change the PCI bus
"""
# call parent function to generate the mgmt interface
res = super(Talos_vm, self).gen_mgmt()

# This is a copy paste from ubuntu
if "bus=pci.1" not in res[-3]:
res[-3] = res[-3] + ",bus=pci.1"
return res

def add_disk(self, disk_size, driveif="ide"):
additional_disk = f"disk_{disk_size}.qcow2"

if not os.path.exists(additional_disk):
self.logger.debug(f"Creating additional disk image {additional_disk}")
vrnetlab.run_command(
["qemu-img", "create", "-f", "qcow2", additional_disk, disk_size]
)

self.qemu_args.extend(
[
"-drive",
f"if={driveif},file={additional_disk}",
]
)


class Talos(vrnetlab.VR):
def __init__(self, nics, conn_mode):
super(Talos, self).__init__("", "")
self.vms = [Talos_vm(nics, conn_mode)]


if __name__ == "__main__":
import argparse

parser = argparse.ArgumentParser(description="")
parser.add_argument(
"--trace", action="store_true", help="enable trace level logging"
)
parser.add_argument("--nics", type=int, default=4, help="Number of NICS")
parser.add_argument("--username", default="not supported", help="NOOP")
parser.add_argument("--password", default="not supported", help="NOOP")
parser.add_argument("--hostname", default="not supported", help="NOOP")
parser.add_argument(
"--connection-mode",
default="tc",
help="Connection mode to use in the datapath",
)
args = parser.parse_args()

LOG_FORMAT = "%(asctime)s: %(module)-10s %(levelname)-8s %(message)s"
logging.basicConfig(format=LOG_FORMAT)
logger = logging.getLogger()

logger.setLevel(logging.DEBUG)
if args.trace:
logger.setLevel(1)

vr = Talos(
args.nics,
args.connection_mode,
)
vr.start()
18 changes: 18 additions & 0 deletions talos/download.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

version="v1.10.5"

# Download latest jammy lts cloud image
download_url="https://factory.talos.dev/image/9ddb0c3e6bf64299a4013243fd14a209af1d0626ebf8e1eb4a151f897cd8f8f2/${version}/metal-amd64.qcow2"

# Extract the filename from the URL
filename="$version-metal-amd64.qcow2"

# Check if the file already exists in the current directory
if [ -e "$filename" ]; then
echo "File $filename already exists. Skipping download."
else
# Download the URL
curl -o $filename "$download_url"
echo "Download complete: $filename"
fi