Cherry pick 20240910 (#69)

* consolidate devscripts, build debian dev host

* devhost supports fuse, can now build and run pcloudcc

* working on a sync capability

* devhost with working ssh

* sync capability done

* added a devhost script and readme

* useless end paragraph

* update sync section
This commit is contained in:
Levi Neely 2024-09-10 16:26:16 +02:00 committed by GitHub
parent a80e82b7a8
commit 53f785ac1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 836 additions and 39 deletions

View File

@ -1,4 +0,0 @@
# container
The container directory contains scripts to generate build containers
from various linux distributions.

View File

@ -1,11 +0,0 @@
#!/bin/bash
set -x
echo "building debian container..."
ctrid=$(buildah from debian:latest)
buildah run "$ctrid" -- apt update
buildah run "$ctrid" -- apt install build-essential git libfuse-dev libudev-dev libsqlite3-dev libmbedtls-dev zlib1g-dev libboost-system-dev libboost-program-options-dev fuse llvm gdb
export ctrid=$(buildah commit "$ctrid" "$USER/debian-build")
echo "done! you can use $ctrid to start a container"
set +x

View File

@ -1,13 +0,0 @@
#!/bin/bash
set -x
echo "building fedora container..."
ctrid=$(buildah from fedora:latest)
buildah run "$ctrid" -- dnf update -y
buildah run "$ctrid" -- dnf group install -y "C Development Tools and Libraries"
buildah run "$ctrid" -- dnf install -y git fuse fuse-devel sqlite-devel mbedtls-devel zlib-devel boost-system boost-devel boost-program-options udev systemd-devel libasan
export ctrid=$(buildah commit "$ctrid" "$USER/fedora-build")
echo "done! the container name is: $USER/fedora-build"
set +x

View File

@ -1,11 +0,0 @@
#!/bin/bash
set -x
echo "building ubuntu container..."
ctrid=$(buildah from ubuntu:latest)
buildah run "$ctrid" -- apt update -y
buildah run "$ctrid" -- apt install -y build-essential git libfuse-dev libudev-dev libsqlite3-dev libmbedtls-dev zlib1g-dev libboost-system-dev libboost-program-options-dev fuse llvm gdb
export ctrid=$(buildah commit "$ctrid" "$USER/ubuntu-build")
echo "done! the container name is: $USER/ubuntu-build"
set +x

118
dev/README.md Normal file
View File

@ -0,0 +1,118 @@
# DevHost Setup Scripts
This repository contains scripts to set up development environments using Podman containers. The scripts allow you to create and manage development hosts based on Fedora or Debian/Ubuntu, and sync your project files between the host and the container.
## Scripts
1. `devhost-fedora.sh`: Sets up a Fedora-based development environment.
2. `devhost-debian.sh`: Sets up a Debian or Ubuntu-based development environment.
3. `sync.sh`: Syncs project files between the host and the container.
## Prerequisites
- Podman installed on your host system
- FUSE support on your host system
- SSH key pair for authentication (optional, but recommended)
## Usage
### Setting up a Development Host
#### Fedora-based Host
```bash
./devhost-fedora.sh [OPTIONS]
```
#### Debian/Ubuntu-based Host
```bash
./devhost-debian.sh [OPTIONS]
```
Common options for both scripts:
- `-n, --name NAME`: Specify the name for the container (default: devhost-[distro]-[username])
- `-u, --user USER`: Specify the username to create (default: dev)
- `-p, --password PASS`: Specify the user's password (default: devhost)
- `-s, --ssh-port PORT`: Specify the SSH port to forward (default: 2222)
- `-r, --remove`: Stop and remove the container if it exists
- `-e, --enter`: Enter the container as the specified user (builds if not exists)
- `-h, --help`: Display the help message
Additional option for devhost-debian.sh:
- `-d, --distro DISTRO`: Specify the distribution (debian or ubuntu) (default: debian)
### Examples
1. Create a Fedora-based development host:
```bash
./devhost-fedora.sh
```
2. Create an Ubuntu-based development host:
```bash
./devhost-debian.sh -d ubuntu
```
3. Create a Debian-based host with a custom name and SSH port:
```bash
./devhost-debian.sh -n mydevhost -s 2345
```
4. Enter an existing container:
```bash
./devhost-fedora.sh -e
```
5. Remove an existing container:
```bash
./devhost-debian.sh -r
```
### Syncing Project Files
To sync your project files from the host to the container, use the `sync.sh` script:
```bash
./sync.sh [OPTIONS] -c CONTAINER_NAME
```
Options:
- `-c, --container CONTAINER_NAME`: Specify the devhost container name (required)
- `-s, --source DIR`: Specify the source directory on the host (default: current directory)
- `-d, --dest DIR`: Specify the destination directory in the container
- `-u, --user USER`: Specify the user in the container (default: dev)
- `-p, --port PORT`: Specify the SSH port (default: 2222)
- `-o, --once`: Sync files once and exit
- `-w, --watch`: Watch for changes and sync continuously (default)
- `-h, --help`: Display the help message
Example:
```bash
./sync.sh -c mydevhost-fedora -s /path/to/project -d /src/project -u dev -p 2222 -w
```
This will sync files from `/path/to/project` on the host to `/src/project` in the container named `mydevhost-fedora`, using the user `dev` and SSH port 2222. It will continue to watch for changes and sync automatically.
Note:
- The script syncs files one-way: from the host to the container.
- The `-c` or `--container` option is required.
- By default, it watches for changes and syncs continuously. Use the `-o` or `--once` option for a single sync.
- Make sure you have `rsync` installed on your host, and `watchexec` if you want to use the watch feature.
## Notes
- The scripts assume they are located in a 'dev' subdirectory of the source root.
- The entire source root will be copied to /src/<source_root_name> in the container.
- SSH public keys from $HOME/.ssh/*.pub will be copied to the container for key-based authentication.
- FUSE support is enabled in the containers, allowing for advanced filesystem operations.
## Troubleshooting
If you encounter issues with FUSE support, ensure that FUSE is properly installed and loaded on your host system. You may need to run `sudo modprobe fuse` on the host system.
For any other issues or questions, please open an issue in the repository.

142
dev/container-build.sh Executable file
View File

@ -0,0 +1,142 @@
#!/bin/bash
# This script is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this script. If not, see <https://www.gnu.org/licenses/>.
set -e
# Function to display supported distributions
show_supported_distros() {
echo "Supported distributions:"
echo " - debian"
echo " - ubuntu"
echo " - fedora"
echo " - archlinux"
echo " - opensuse/tumbleweed"
echo " - opensuse/leap"
}
# Function to display help
show_help() {
echo "Usage: $0 [OPTIONS]"
echo "Build a container with development tools and compile the project."
echo
echo "Options:"
echo " -i, --image IMAGE Specify the base image (default: debian)"
echo " -t, --tag TAG Specify the tag for the base image (default: latest)"
echo " -n, --name NAME Specify the name for the container (default: debian-build)"
echo " -l, --list List supported distributions"
echo " -h, --help Display this help message"
echo
echo "Examples:"
echo " $0 -i ubuntu -t 20.04 -n ubuntu-build"
echo " $0 --image debian --tag buster --name debian-buster-build"
echo " $0 --image fedora --tag 34 --name fedora-build"
echo " $0 --image archlinux --tag latest --name arch-build"
echo " $0 --image opensuse/tumbleweed --tag latest --name opensuse-build"
echo " $0 --image opensuse/leap --tag 15.3 --name opensuse-leap-build"
echo
echo "Use -l or --list to see supported distributions"
}
# Default values
IMAGE="debian"
TAG="latest"
NAME="debian-build"
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-i|--image)
IMAGE="$2"
shift 2
;;
-t|--tag)
TAG="$2"
shift 2
;;
-n|--name)
NAME="$2"
shift 2
;;
-l|--list)
show_supported_distros
exit 0
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
FULL_IMAGE="${IMAGE}:${TAG}"
echo "Building $NAME container from $FULL_IMAGE..."
case $IMAGE in
debian|ubuntu)
echo "Setting up Debian/Ubuntu-based container..."
ctrid=$(buildah from "$FULL_IMAGE")
buildah run "$ctrid" -- apt update
buildah run "$ctrid" -- apt install -y build-essential git libfuse-dev libudev-dev libsqlite3-dev libmbedtls-dev zlib1g-dev libboost-system-dev libboost-program-options-dev fuse llvm gdb
;;
fedora)
echo "Setting up Fedora-based container..."
ctrid=$(buildah from "$FULL_IMAGE")
buildah run "$ctrid" -- dnf update -y
buildah run "$ctrid" -- dnf group install -y "C Development Tools and Libraries"
buildah run "$ctrid" -- dnf install -y git fuse-devel systemd-devel sqlite-devel mbedtls-devel zlib-devel boost-devel boost-program-options fuse llvm gdb fuse udev libasan
;;
archlinux|arch)
echo "Setting up Arch Linux-based container..."
ctrid=$(buildah from "$FULL_IMAGE")
buildah run "$ctrid" -- pacman -Syu --noconfirm
buildah run "$ctrid" -- pacman -S --noconfirm base-devel git fuse2 systemd sqlite mbedtls2 zlib boost boost-libs llvm gdb udev gcc make
;;
opensuse/tumbleweed|opensuse/leap)
echo "Setting up openSUSE-based container..."
ctrid=$(buildah from "$FULL_IMAGE")
buildah run "$ctrid" -- zypper refresh
buildah run "$ctrid" -- zypper install -y gcc gcc-c++ make git fuse-devel systemd-devel sqlite3-devel zlib-devel libboost_system-devel libboost_program_options-devel fuse llvm gdb udev mbedtls-2-devel
;;
*)
echo "Unsupported image: $IMAGE"
echo "Use -l or --list to see supported distributions"
show_help
exit 1
;;
esac
echo "Creating /src directory in the container..."
buildah run "$ctrid" -- mkdir -p /src
echo "Committing changes to the container..."
ctrid=$(buildah commit "$ctrid" "$USER/${IMAGE}-build:$TAG")
# Assuming this script is in ./dev subdirectory of the source root
SOURCE_ROOT=$(dirname "$(dirname "$(readlink -f "$0")")")
SOURCE_DIR_NAME=$(basename "$SOURCE_ROOT")
echo "Building the project inside the container..."
if [[ $IMAGE == opensuse/* ]]; then
podman run --rm -v "$SOURCE_ROOT:/src" "$USER/${IMAGE}-build:$TAG" /bin/bash -c "cd /src && CFLAGS='-I/usr/include/mbedtls-2' LDFLAGS='-L/usr/lib64 -lmbedtls-2 -lmbedx509-2 -lmbedcrypto-2' make"
else
podman run --rm -v "$SOURCE_ROOT:/src" "$USER/${IMAGE}-build:$TAG" /bin/bash -c "cd /src && make"
fi
echo "Build complete. The binary should now be in your source root directory."

223
dev/devhost-debian.sh Executable file
View File

@ -0,0 +1,223 @@
#!/bin/bash
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# This script builds a development host based on Debian or Ubuntu.
set -e
HOST_USER="$USER"
CONTAINER_NAME="devhost-debian-${HOST_USER}"
IMAGE="debian:latest"
DISTRO="debian"
USERNAME="dev"
USER_PASSWORD="devhost"
SOURCE_DIR="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
SOURCE_NAME="$(basename "$SOURCE_DIR")"
SSH_PORT="2222"
show_help() {
echo "Usage: $0 [OPTIONS]"
echo "Set up a fully-fledged Debian or Ubuntu distribution in a Podman container with FUSE support and SSH access."
echo
echo "Options:"
echo " -n, --name NAME Specify the name for the container (default: devhost-debian-${HOST_USER})"
echo " -u, --user USER Specify the username to create (default: dev)"
echo " -p, --password PASS Specify the user's password (default: devhost)"
echo " -s, --ssh-port PORT Specify the SSH port to forward (default: 2222)"
echo " -d, --distro DISTRO Specify the distribution (debian or ubuntu) (default: debian)"
echo " -r, --remove Stop and remove the container if it exists"
echo " -e, --enter Enter the container as the specified user (builds if not exists)"
echo " -h, --help Display this help message"
echo
echo "Note: This script assumes it's located in a 'dev' subdirectory of the source root."
echo " The entire source root will be copied to /src/<source_root_name> in the container."
echo " The container name will include the host username: ${CONTAINER_NAME}"
echo " SSH public keys from $HOME/.ssh/*.pub will be copied to the container for key-based authentication."
}
check_fuse() {
if [ ! -e /dev/fuse ]; then
echo "ERROR: FUSE is not available on the host. Please ensure FUSE is installed and loaded."
echo "You may need to run 'sudo modprobe fuse' on the host system."
exit 1
fi
}
stop_and_remove_container() {
if podman ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Stopping container ${CONTAINER_NAME}..."
podman stop "${CONTAINER_NAME}"
echo "Removing container ${CONTAINER_NAME}..."
podman rm "${CONTAINER_NAME}"
echo "Container ${CONTAINER_NAME} has been stopped and removed."
exit 0
else
echo "Container ${CONTAINER_NAME} does not exist."
exit 0
fi
}
enter_container() {
if ! podman ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Container ${CONTAINER_NAME} does not exist. Building it now..."
build_container
fi
if ! podman ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Starting container ${CONTAINER_NAME}..."
podman start "${CONTAINER_NAME}"
fi
echo "Entering container ${CONTAINER_NAME} as user ${USERNAME}..."
podman exec -it -u "${USERNAME}" "${CONTAINER_NAME}" /bin/bash
exit 0
}
build_container() {
echo "Setting up ${DISTRO^} container: $CONTAINER_NAME"
echo "Source root directory: $SOURCE_DIR"
echo "Source name: $SOURCE_NAME"
echo "SSH Port: $SSH_PORT"
# create container
check_fuse
podman run --name "$CONTAINER_NAME" -d \
--device /dev/fuse \
--cap-add SYS_ADMIN \
--security-opt apparmor:unconfined \
-p ${SSH_PORT}:22 \
"$IMAGE" sleep infinity
# install system
podman exec "$CONTAINER_NAME" apt update
podman exec "$CONTAINER_NAME" apt upgrade -y
podman exec "$CONTAINER_NAME" apt install -y \
sudo vim nano curl wget git htop tmux man-db locales \
bash-completion ca-certificates ssh systemd systemd-sysv \
build-essential libfuse-dev libudev-dev libsqlite3-dev \
libmbedtls-dev zlib1g-dev libboost-system-dev \
libboost-program-options-dev fuse llvm gdb iproute2 \
openssh-server rsync
# verify fuse
if ! podman exec "$CONTAINER_NAME" ls /dev/fuse > /dev/null 2>&1; then
echo "WARNING: FUSE device not found in the container. FUSE might not work properly."
fi
# setup system
podman exec "$CONTAINER_NAME" sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
podman exec "$CONTAINER_NAME" locale-gen
podman exec "$CONTAINER_NAME" update-locale LANG=en_US.UTF-8
podman exec "$CONTAINER_NAME" useradd -m -s /bin/bash "$USERNAME"
podman exec "$CONTAINER_NAME" bash -c "echo $USERNAME:$USER_PASSWORD | chpasswd"
podman exec "$CONTAINER_NAME" usermod -aG sudo "$USERNAME"
podman exec "$CONTAINER_NAME" bash -c 'echo "%sudo ALL=(ALL) ALL" > /etc/sudoers.d/sudo-group'
podman exec --user "$USERNAME" "$CONTAINER_NAME" bash -c 'echo "export PS1=\"\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ \"" >> ~/.bashrc'
# setup /src tree
podman exec "$CONTAINER_NAME" mkdir -p "/src/$SOURCE_NAME"
podman exec "$CONTAINER_NAME" chown -R "$USERNAME:$USERNAME" /src
# setup ld.so.conf
podman exec "$CONTAINER_NAME" bash -c 'echo "/usr/lib/x86_64-linux-gnu/" >> /etc/ld.so.conf'
podman exec "$CONTAINER_NAME" ldconfig
# setup ssh authentication
podman exec "$CONTAINER_NAME" mkdir -p "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" touch "/home/$USERNAME/.ssh/authorized_keys"
podman exec "$CONTAINER_NAME" chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" chmod 700 "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
for pubkey in "$HOME"/.ssh/*.pub; do
if [ -f "$pubkey" ]; then
podman cp "$pubkey" "$CONTAINER_NAME:/tmp/$(basename "$pubkey")"
podman exec "$CONTAINER_NAME" bash -c "cat /tmp/$(basename "$pubkey") >> /home/$USERNAME/.ssh/authorized_keys"
podman exec "$CONTAINER_NAME" rm "/tmp/$(basename "$pubkey")"
fi
done
# setup and run sshd
podman exec "$CONTAINER_NAME" sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
podman exec "$CONTAINER_NAME" sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
podman exec "$CONTAINER_NAME" service ssh start
# mop up
podman exec "$CONTAINER_NAME" apt clean
podman exec "$CONTAINER_NAME" rm -rf /var/lib/apt/lists/*
echo "${DISTRO^} container setup complete!"
echo "Container name: $CONTAINER_NAME"
echo "Username: $USERNAME"
echo "Source root copied to: /src/$SOURCE_NAME"
echo "Ownership of /src changed to $USERNAME recursively"
echo "/usr/lib/x86_64-linux-gnu/ added to system library search path"
echo "FUSE support enabled (check warning messages, if any)"
echo "SSH server enabled and configured for key-based authentication"
echo "SSH public keys copied from $HOME/.ssh/*.pub to /home/$USERNAME/.ssh/authorized_keys"
}
while [[ $# -gt 0 ]]; do
case $1 in
-n|--name)
CONTAINER_NAME="$2-${HOST_USER}"
shift 2
;;
-u|--user)
USERNAME="$2"
shift 2
;;
-p|--password)
USER_PASSWORD="$2"
shift 2
;;
-s|--ssh-port)
SSH_PORT="$2"
shift 2
;;
-d|--distro)
DISTRO="$2"
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
echo "Error: Invalid distribution. Use 'debian' or 'ubuntu'."
exit 1
fi
IMAGE="${DISTRO}:latest"
CONTAINER_NAME="devhost-${DISTRO}-${HOST_USER}"
shift 2
;;
-r|--remove)
stop_and_remove_container
;;
-e|--enter)
enter_container
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
build_container
echo
echo "You can start the container with: podman start $CONTAINER_NAME"
echo "To enter the container, use: $0 -e"
echo "To stop and remove the container, use: $0 -r"
echo "To SSH into the container, use: ssh -p $SSH_PORT $USERNAME@localhost"

206
dev/devhost-fedora.sh Executable file
View File

@ -0,0 +1,206 @@
#!/bin/bash
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# This script builds a development host based on Fedora.
set -e
HOST_USER="$USER"
CONTAINER_NAME="devhost-fedora-${HOST_USER}"
IMAGE="fedora:latest"
USERNAME="dev"
USER_PASSWORD="devhost"
SOURCE_DIR="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
SOURCE_NAME="$(basename "$SOURCE_DIR")"
SSH_PORT="2222"
show_help() {
echo "Usage: $0 [OPTIONS]"
echo "Set up a fully-fledged Fedora distribution in a Podman container with FUSE support and SSH access."
echo
echo "Options:"
echo " -n, --name NAME Specify the name for the container (default: devhost-fedora-${HOST_USER})"
echo " -u, --user USER Specify the username to create (default: dev)"
echo " -p, --password PASS Specify the user's password (default: devhost)"
echo " -s, --ssh-port PORT Specify the SSH port to forward (default: 2222)"
echo " -r, --remove Stop and remove the container if it exists"
echo " -e, --enter Enter the container as the specified user (builds if not exists)"
echo " -h, --help Display this help message"
echo
echo "Note: This script assumes it's located in a 'dev' subdirectory of the source root."
echo " The entire source root will be copied to /src/<source_root_name> in the container."
echo " The container name will include the host username: ${CONTAINER_NAME}"
echo " SSH public keys from $HOME/.ssh/*.pub will be copied to the container for key-based authentication."
}
check_fuse() {
if [ ! -e /dev/fuse ]; then
echo "ERROR: FUSE is not available on the host. Please ensure FUSE is installed and loaded."
echo "You may need to run 'sudo modprobe fuse' on the host system."
exit 1
fi
}
stop_and_remove_container() {
if podman ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Stopping container ${CONTAINER_NAME}..."
podman stop "${CONTAINER_NAME}"
echo "Removing container ${CONTAINER_NAME}..."
podman rm "${CONTAINER_NAME}"
echo "Container ${CONTAINER_NAME} has been stopped and removed."
exit 0
else
echo "Container ${CONTAINER_NAME} does not exist."
exit 0
fi
}
enter_container() {
if ! podman ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Container ${CONTAINER_NAME} does not exist. Building it now..."
build_container
fi
if ! podman ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "Starting container ${CONTAINER_NAME}..."
podman start "${CONTAINER_NAME}"
fi
echo "Entering container ${CONTAINER_NAME} as user ${USERNAME}..."
podman exec -it -u "${USERNAME}" "${CONTAINER_NAME}" /bin/bash
exit 0
}
build_container() {
echo "Setting up Fedora container: $CONTAINER_NAME"
echo "Source root directory: $SOURCE_DIR"
echo "Source name: $SOURCE_NAME"
echo "SSH Port: $SSH_PORT"
# create container
check_fuse
podman run --name "$CONTAINER_NAME" -d \
--device /dev/fuse \
--cap-add SYS_ADMIN \
--security-opt apparmor:unconfined \
-p ${SSH_PORT}:22 \
"$IMAGE" sleep infinity
# install system
podman exec "$CONTAINER_NAME" dnf update -y
podman exec "$CONTAINER_NAME" dnf install -y \
sudo vim nano curl wget git htop tmux man-db \
bash-completion ca-certificates openssh-server \
gcc gcc-c++ make fuse-devel systemd-devel sqlite-devel \
mbedtls-devel zlib-devel boost-devel fuse llvm gdb iproute \
rsync
# verify fuse
if ! podman exec "$CONTAINER_NAME" ls /dev/fuse > /dev/null 2>&1; then
echo "WARNING: FUSE device not found in the container. FUSE might not work properly."
fi
# setup system
podman exec "$CONTAINER_NAME" useradd -m -s /bin/bash "$USERNAME"
podman exec "$CONTAINER_NAME" bash -c "echo $USERNAME:$USER_PASSWORD | chpasswd"
podman exec "$CONTAINER_NAME" usermod -aG wheel "$USERNAME"
podman exec "$CONTAINER_NAME" bash -c 'echo "%wheel ALL=(ALL) ALL" > /etc/sudoers.d/wheel-group'
podman exec --user "$USERNAME" "$CONTAINER_NAME" bash -c 'echo "export PS1=\"\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ \"" >> ~/.bashrc'
# setup /src tree
podman exec "$CONTAINER_NAME" mkdir -p "/src/$SOURCE_NAME"
podman exec "$CONTAINER_NAME" chown -R "$USERNAME:$USERNAME" /src
# setup ld.so.conf
podman exec "$CONTAINER_NAME" bash -c 'echo "/usr/lib64/" >> /etc/ld.so.conf'
podman exec "$CONTAINER_NAME" ldconfig
# setup ssh authentication
podman exec "$CONTAINER_NAME" mkdir -p "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" touch "/home/$USERNAME/.ssh/authorized_keys"
podman exec "$CONTAINER_NAME" chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" chmod 700 "/home/$USERNAME/.ssh"
podman exec "$CONTAINER_NAME" chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
for pubkey in "$HOME"/.ssh/*.pub; do
if [ -f "$pubkey" ]; then
podman cp "$pubkey" "$CONTAINER_NAME:/tmp/$(basename "$pubkey")"
podman exec "$CONTAINER_NAME" bash -c "cat /tmp/$(basename "$pubkey") >> /home/$USERNAME/.ssh/authorized_keys"
podman exec "$CONTAINER_NAME" rm "/tmp/$(basename "$pubkey")"
fi
done
# setup and run sshd
podman exec "$CONTAINER_NAME" ssh-keygen -A
podman exec "$CONTAINER_NAME" sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
podman exec "$CONTAINER_NAME" sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
podman exec "$CONTAINER_NAME" /usr/sbin/sshd
# mop up
podman exec "$CONTAINER_NAME" dnf clean all
echo "Fedora container setup complete!"
echo "Container name: $CONTAINER_NAME"
echo "Username: $USERNAME"
echo "Source root copied to: /src/$SOURCE_NAME"
echo "Ownership of /src changed to $USERNAME recursively"
echo "/usr/lib64/ added to system library search path"
echo "FUSE support enabled (check warning messages, if any)"
echo "SSH server enabled and configured for key-based authentication"
echo "SSH public keys copied from $HOME/.ssh/*.pub to /home/$USERNAME/.ssh/authorized_keys"
}
while [[ $# -gt 0 ]]; do
case $1 in
-n|--name)
CONTAINER_NAME="$2-${HOST_USER}"
shift 2
;;
-u|--user)
USERNAME="$2"
shift 2
;;
-p|--password)
USER_PASSWORD="$2"
shift 2
;;
-s|--ssh-port)
SSH_PORT="$2"
shift 2
;;
-r|--remove)
stop_and_remove_container
;;
-e|--enter)
enter_container
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
build_container
echo
echo "You can start the container with: podman start $CONTAINER_NAME"
echo "To enter the container, use: $0 -e"
echo "To stop and remove the container, use: $0 -r"
echo "To SSH into the container, use: ssh -p $SSH_PORT $USERNAME@localhost"

147
dev/sync.sh Executable file
View File

@ -0,0 +1,147 @@
#!/bin/bash
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# This script syncs the source tree in the devhost with the local
# source tree.
set -e
SOURCE_DIR="$(pwd)"
CONTAINER_USER="dev"
DEST_DIR="/src/$(basename "$SOURCE_DIR")"
SSH_PORT="2222"
get_container_ip() {
podman exec "$CONTAINER_NAME" bash -c "ip -4 addr show | grep -v '127.0.0.1' | grep 'inet ' | grep 'scope global' | head -n 1 | awk '{print \$2}' | cut -d/ -f1"
}
check_ssh_connection() {
local container_ip=$1
ssh-keyscan -p "$SSH_PORT" "$container_ip" > /dev/null 2>&1 || {
echo "Error: Unable to establish SSH connection to $container_ip:$SSH_PORT"
exit 1
}
}
sync_files() {
local container_ip=$(get_container_ip)
if [ -z "$container_ip" ]; then
echo "Error: Unable to get container IP address. Is the container running?"
exit 1
fi
check_ssh_connection "$container_ip"
echo "Syncing files to $CONTAINER_NAME ($container_ip)..."
rsync -avz --delete \
-e "ssh -p $SSH_PORT -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5" \
--exclude '.git' \
--exclude 'target' \
--exclude '*.tmp' \
--exclude '*.o' \
--exclude 'pcloudcc' \
--exclude '*.log' \
--exclude '.cache' \
"$SOURCE_DIR/" \
"${CONTAINER_USER}@${container_ip}:${DEST_DIR}/" || {
echo "Error: rsync failed. Exiting."
exit 1
}
echo "Sync completed at $(date)"
}
show_help() {
echo "Usage: $0 [OPTIONS] -c CONTAINER_NAME"
echo "Sync files to a devhost container using rsync and watchexec."
echo
echo "Options:"
echo " -c, --container CONTAINER_NAME Specify the devhost container name (required)"
echo " -s, --source DIR Specify the source directory (default: current directory)"
echo " -d, --dest DIR Specify the destination directory in the container"
echo " -u, --user USER Specify the user in the container (default: dev)"
echo " -p, --port PORT Specify the SSH port (default: 2222)"
echo " -o, --once Sync files once and exit"
echo " -w, --watch Watch for changes and sync continuously (default)"
echo " -h, --help Display this help message"
}
WATCH=true
while [[ $# -gt 0 ]]; do
case $1 in
-c|--container)
CONTAINER_NAME="$2"
shift 2
;;
-s|--source)
SOURCE_DIR="$2"
shift 2
;;
-d|--dest)
DEST_DIR="$2"
shift 2
;;
-u|--user)
CONTAINER_USER="$2"
shift 2
;;
-p|--port)
SSH_PORT="$2"
shift 2
;;
-o|--once)
WATCH=false
shift
;;
-w|--watch)
WATCH=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
if [ -z "$CONTAINER_NAME" ]; then
echo "Error: Devhost container name is required. Use -c or --container to specify it."
show_help
exit 1
fi
if ! command -v watchexec &> /dev/null && [ "$WATCH" = true ]; then
echo "Error: watchexec is not installed. Please install it to use the watch feature."
echo "You can install it using: cargo install watchexec-cli"
exit 1
fi
if ! command -v rsync &> /dev/null; then
echo "Error: rsync is not installed. Please install it to use this script."
exit 1
fi
if [ "$WATCH" = true ]; then
echo "Watching for changes in $SOURCE_DIR"
watchexec -w "$SOURCE_DIR" --on-busy-update=restart -- "$0" --once -c "$CONTAINER_NAME" -s "$SOURCE_DIR" -d "$DEST_DIR" -u "$CONTAINER_USER" -p "$SSH_PORT"
else
sync_files
fi