From 2aaae5265a32dab8200635b76fa59b0c13a67027 Mon Sep 17 00:00:00 2001 From: Mariusz Kogen Date: Thu, 23 Jan 2025 00:53:31 +0100 Subject: [PATCH] feat: add WireGuard VPS setup automation script (#2810) * feat: add WireGuard VPS setup automation script Adds a comprehensive bash script that automates: - SSH key setup and authentication - WireGuard installation on remote VPS - Configuration download and import to NetworkManager - User-friendly CLI interface with validation - Detailed status messages and error handling - Instructions for exposing services via ACME/Let's Encrypt * use cat heredoc for issue files to fix formatting Replaces echo with cat heredoc when writing to /etc/issue and /etc/issue.net to properly preserve escape sequences and prevent unwanted newlines in login prompts. * add convent `wg-vps-setup` symlink to PATH * sync ssh privkey on init * Update default ssh key location * simplify to use existing StartOS SSH keys and fix .ssh permission * finetune * Switch to start9labs repo * rename some files * set correct ownership --------- Co-authored-by: Aiden McClelland --- ...gather_debug_info.sh => gather-debug-info} | 0 build/lib/scripts/{tor-check.sh => tor-check} | 0 build/lib/scripts/wg-vps-setup | 323 ++++++++++++++++++ core/startos/src/init.rs | 7 +- core/startos/src/ssh.rs | 100 +++++- debian/postinst | 14 +- sdk/base/lib/osBindings/index.ts | 30 +- 7 files changed, 438 insertions(+), 36 deletions(-) rename build/lib/scripts/{gather_debug_info.sh => gather-debug-info} (100%) rename build/lib/scripts/{tor-check.sh => tor-check} (100%) create mode 100755 build/lib/scripts/wg-vps-setup diff --git a/build/lib/scripts/gather_debug_info.sh b/build/lib/scripts/gather-debug-info similarity index 100% rename from build/lib/scripts/gather_debug_info.sh rename to build/lib/scripts/gather-debug-info diff --git a/build/lib/scripts/tor-check.sh b/build/lib/scripts/tor-check similarity index 100% rename from build/lib/scripts/tor-check.sh rename to build/lib/scripts/tor-check diff --git a/build/lib/scripts/wg-vps-setup b/build/lib/scripts/wg-vps-setup new file mode 100755 index 000000000..3dc4fd179 --- /dev/null +++ b/build/lib/scripts/wg-vps-setup @@ -0,0 +1,323 @@ +#!/bin/bash + +# Colors for better output +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[1;34m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# --- Constants --- +readonly WIREGUARD_INSTALL_URL="https://raw.githubusercontent.com/start9labs/wg-vps-setup/master/wireguard-install.sh" +readonly SSH_KEY_DIR="/home/start9/.ssh" +readonly SSH_KEY_NAME="id_ed25519" +readonly SSH_PRIVATE_KEY="$SSH_KEY_DIR/$SSH_KEY_NAME" +readonly SSH_PUBLIC_KEY="$SSH_PRIVATE_KEY.pub" + +# Store original arguments +SCRIPT_ARGS=("$@") + +# --- Functions --- + +# Function to ensure script runs with root privileges by auto-elevating if needed +check_root() { + if [[ "$EUID" -ne 0 ]]; then + exec sudo "$0" "${SCRIPT_ARGS[@]}" + fi + sudo chown -R start9:start9 "$SSH_KEY_DIR" +} + +# Function to print banner +print_banner() { + echo -e "${BLUE}" + echo "================================================" + echo -e " ${NC}StartOS WireGuard VPS Setup Tool${BLUE} " + echo "================================================" + echo -e "${NC}" +} + +# Function to print usage +print_usage() { + echo -e "Usage: $0 [-h] [-i IP] [-u USERNAME] [-p PORT] [-k SSH_KEY]" + echo "Options:" + echo " -h Show this help message" + echo " -i VPS IP address" + echo " -u SSH username (default: root)" + echo " -p SSH port (default: 22)" + echo " -k Path to the custom SSH private key (optional)" + echo " If no key is provided, the default key '$SSH_PRIVATE_KEY' will be used." +} + +# Function to display end message +display_end_message() { + echo -e "\n${BLUE}------------------------------------------------------------------${NC}" + echo -e "${NC}WireGuard server setup complete!" + echo -e "${BLUE}------------------------------------------------------------------${NC}" + echo -e "\n${YELLOW}To expose your services to the Clearnet, use the following commands on your StartOS system (replace placeholders):${NC}" + echo -e "\n ${YELLOW}1. Initialize ACME (This only needs to be done once):${NC}" + echo " start-cli net acme init --provider=letsencrypt --contact=mailto:your-email@example.com" + echo -e "\n ${YELLOW}2. Expose 'hello-world' on port 80 through VPS:${NC}" + echo " start-cli package host hello-world binding ui-multi set-public 80" + echo -e "\n ${YELLOW}3. Add a domain to your 'hello-world' service:${NC}" + echo " start-cli package host hello-world address ui-multi domain add your-domain.example.com --acme=letsencrypt" + echo -e "\n ${YELLOW}Replace '${NC}your-email@example.com${YELLOW}' with your actual email address, '${NC}your-domain.example.com${YELLOW}' with your actual domain and '${NC}hello-world${YELLOW}' with your actual service id.${NC}" + echo -e "${BLUE}------------------------------------------------------------------${NC}" +} + +# Function to validate IP address +validate_ip() { + local ip=$1 + if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + return 0 + else + return 1 + fi +} + +# Function to handle StartOS connection (download only) +handle_startos_connection() { + echo -e "${BLUE}Fetching the WireGuard configuration file...${NC}" + + # Fetch the client configuration file + config_file=$(ssh -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -p "$SSH_PORT" "$SSH_USER@$VPS_IP" 'ls -t ~/*.conf 2>/dev/null | head -n 1') + if [ -z "$config_file" ]; then + echo -e "${RED}Error: No WireGuard configuration file found on the remote server.${NC}" + return 1 # Exit with error + fi + CONFIG_NAME=$(basename "$config_file") + + # Download the configuration file + if ! scp -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -P "$SSH_PORT" "$SSH_USER@$VPS_IP":~/"$CONFIG_NAME" ./; then + echo -e "${RED}Error: Failed to download the WireGuard configuration file.${NC}" + return 1 # Exit with error + fi + echo -e "${GREEN}WireGuard configuration file '$CONFIG_NAME' downloaded successfully.${NC}" + return 0 +} + +# Function to import WireGuard configuration +import_wireguard_config() { + local config_name="$1" + if [ -z "$config_name" ]; then + echo -e "${RED}Error: Configuration file name is missing.${NC}" + return 1 + fi + + local connection_name=$(basename "$config_name" .conf) #Extract base name without extension + + # Check if the connection with same name already exists + if nmcli connection show --active | grep -q "^${connection_name}\s"; then + read -r -p "A connection with the name '$connection_name' already exists. Do you want to override it? (y/N): " answer + if [[ "$answer" =~ ^[Yy]$ ]]; then + nmcli connection delete "$connection_name" + if [ $? -ne 0 ]; then + echo -e "${RED}Error: Failed to delete existing connection '$connection_name'.${NC}" + return 1 + fi + # Import if user chose to override or if connection did not exist + if ! nmcli connection import type wireguard file "$config_name"; then + echo -e "${RED}Error: Failed to import the WireGuard configuration using NetworkManager.${NC}" + rm -f "$config_name" + return 1 + fi + echo -e "${GREEN}WireGuard configuration '$config_name' has been imported to NetworkManager.${NC}" + rm -f "$config_name" + display_end_message + else + echo -e "${BLUE}Skipping import of the WireGuard configuration.${NC}" + rm -f "$config_name" + return 0 + fi + else + # Import if connection did not exist + if command -v nmcli &>/dev/null; then + if ! nmcli connection import type wireguard file "$config_name"; then + echo -e "${RED}Error: Failed to import the WireGuard configuration using NetworkManager.${NC}" + rm -f "$config_name" + return 1 + fi + echo -e "${GREEN}WireGuard configuration '$config_name' has been imported to NetworkManager.${NC}" + rm -f "$config_name" + display_end_message + else + echo -e "${YELLOW}Warning: NetworkManager 'nmcli' not found. Configuration file '$config_name' saved in current directory.${NC}" + echo -e "${YELLOW}Import the configuration to your StartOS manually by going to NetworkManager or using wg-quick up command${NC}" + fi + fi + return 0 +} + +# Function to download the install script +download_install_script() { + echo -e "${BLUE}Downloading latest WireGuard install script...${NC}" + # Download the script + if ! curl -sSf "$WIREGUARD_INSTALL_URL" -o wireguard-install.sh; then + echo -e "${RED}Failed to download WireGuard installation script.${NC}" + return 1 + fi + chmod +x wireguard-install.sh + if [ $? -ne 0 ]; then + echo -e "${RED}Failed to chmod +x wireguard install script.${NC}" + return 1 + fi + echo -e "${GREEN}WireGuard install script downloaded successfully!${NC}" + return 0 +} + +# Function to install WireGuard +install_wireguard() { + echo -e "\n${BLUE}Installing WireGuard...${NC}" + + # Check if install script exist + if [ ! -f "wireguard-install.sh" ]; then + echo -e "${RED}WireGuard install script is missing. Did it failed to download?${NC}" + return 1 + fi + + # Run the remote install script and let it complete + if ! ssh -o ConnectTimeout=60 -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -p "$SSH_PORT" -t "$SSH_USER@$VPS_IP" "bash -c 'export TERM=xterm-256color; export STARTOS_HOSTNAME=$(hostname); bash ~/wireguard-install.sh'"; then + echo -e "${RED}WireGuard installation failed on remote server.${NC}" + return 1 + fi + + # Test if wireguard installed + if ! ssh -q -o BatchMode=yes -o ConnectTimeout=5 -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -p "$SSH_PORT" "$SSH_USER@$VPS_IP" "test -f /etc/wireguard/wg0.conf"; then + echo -e "\n${RED}WireGuard installation failed because /etc/wireguard/wg0.conf is missing, which means the script removed it.${NC}" + return 1 + fi + + echo -e "\n${GREEN}WireGuard installation completed successfully!${NC}" + return 0 +} + +# --- Main Script --- +# Initialize variables +VPS_IP="" +SSH_USER="root" +SSH_PORT="22" +CUSTOM_SSH_KEY="" +CONFIG_NAME="" + +# Check if the script is run as root before anything else +check_root + +# Print banner +print_banner + +# Parse command line arguments +while getopts "hi:u:p:k:" opt; do + case $opt in + h) + print_usage + exit 0 + ;; + i) + VPS_IP=$OPTARG + ;; + u) + SSH_USER=$OPTARG + ;; + p) + SSH_PORT=$OPTARG + ;; + k) + CUSTOM_SSH_KEY=$OPTARG + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + print_usage + exit 1 + ;; + esac +done + +# Check if custom SSH key is passed and update the private key variable +if [ -n "$CUSTOM_SSH_KEY" ]; then + if [ ! -f "$CUSTOM_SSH_KEY" ]; then + echo -e "${RED}Custom SSH key '$CUSTOM_SSH_KEY' not found.${NC}" + exit 1 + fi + SSH_PRIVATE_KEY="$CUSTOM_SSH_KEY" + SSH_PUBLIC_KEY="$CUSTOM_SSH_KEY.pub" +else + # Use default StartOS SSH key + if [ ! -f "$SSH_PRIVATE_KEY" ]; then + echo -e "${RED}No SSH key found at default location '$SSH_PRIVATE_KEY'. Please ensure StartOS SSH keys are properly configured.${NC}" + exit 1 + fi +fi + +if [ ! -f "$SSH_PUBLIC_KEY" ]; then + echo -e "${RED}Public key '$SSH_PUBLIC_KEY' not found. Please ensure both private and public keys exist.${NC}" + exit 1 +fi + +# If VPS_IP is not provided via command line, ask for it +if [ -z "$VPS_IP" ]; then + while true; do + echo -n "Please enter your VPS IP address: " + read VPS_IP + if validate_ip "$VPS_IP"; then + break + else + echo -e "${RED}Invalid IP address format. Please try again.${NC}" + fi + done +fi + +# Confirm SSH connection details +echo -e "\n${GREEN}Connection details:${NC}" +echo "VPS IP: $VPS_IP" +echo "SSH User: $SSH_USER" +echo "SSH Port: $SSH_PORT" + +echo -e "\n${GREEN}Proceeding with SSH key-based authentication...${NC}\n" + +# Copy SSH public key to the remote server +if ! ssh-copy-id -i "$SSH_PUBLIC_KEY" -o StrictHostKeyChecking=no -p "$SSH_PORT" "$SSH_USER@$VPS_IP" >/dev/null 2>&1; then + echo -e "${RED}Failed to copy SSH key to the remote server. Please ensure you have correct credentials.${NC}" + exit 1 +fi + +echo -e "${GREEN}SSH key-based authentication configured successfully!${NC}" + +# Test SSH connection using key-based authentication +echo -e "\nTesting SSH connection with key-based authentication..." +if ! ssh -q -o BatchMode=yes -o ConnectTimeout=5 -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -p "$SSH_PORT" "$SSH_USER@$VPS_IP" exit; then + echo -e "${RED}SSH connection with key-based authentication failed. Please check your configuration.${NC}" + exit 1 +fi + +echo -e "${GREEN}SSH connection successful with key-based authentication!${NC}" + +# Download the WireGuard install script locally +if ! download_install_script; then + echo -e "${RED}Failed to download the latest install script. Exiting...${NC}" + exit 1 +fi + +# Upload the install script to the remote server +if ! scp -i "$SSH_PRIVATE_KEY" -o StrictHostKeyChecking=no -P "$SSH_PORT" wireguard-install.sh "$SSH_USER@$VPS_IP":~/; then + echo -e "${RED}Failed to upload WireGuard install script to the remote server.${NC}" + exit 1 +fi + +# Install WireGuard on remote server using the downloaded script +if ! install_wireguard; then + echo -e "${RED}WireGuard installation failed.${NC}" + exit 1 +fi + +# Remove the local install script +rm wireguard-install.sh >/dev/null 2>&1 + +# Handle the StartOS config (download) +if ! handle_startos_connection; then + echo -e "${RED}StartOS configuration download failed!${NC}" + exit 1 +fi + +# Import the configuration +if ! import_wireguard_config "$CONFIG_NAME"; then + echo -e "${RED}StartOS configuration import failed or skipped!${NC}" +fi diff --git a/core/startos/src/init.rs b/core/startos/src/init.rs index b68596a12..1edcd3efe 100644 --- a/core/startos/src/init.rs +++ b/core/startos/src/init.rs @@ -25,6 +25,7 @@ use crate::context::{CliContext, InitContext}; use crate::db::model::public::ServerStatus; use crate::db::model::Database; use crate::disk::mount::util::unmount; +use crate::hostname::Hostname; use crate::middleware::auth::LOCAL_AUTH_COOKIE_PATH; use crate::net::net_controller::{NetController, NetService}; use crate::net::utils::find_wifi_iface; @@ -35,7 +36,7 @@ use crate::progress::{ }; use crate::rpc_continuations::{Guid, RpcContinuation}; use crate::s9pk::v2::pack::{CONTAINER_DATADIR, CONTAINER_TOOL}; -use crate::ssh::SSH_AUTHORIZED_KEYS_FILE; +use crate::ssh::SSH_DIR; use crate::system::get_mem_info; use crate::util::io::{create_file, IOHook}; use crate::util::lshw::lshw; @@ -340,8 +341,10 @@ pub async fn init( load_ssh_keys.start(); crate::ssh::sync_keys( + &Hostname(peek.as_public().as_server_info().as_hostname().de()?), + &peek.as_private().as_ssh_privkey().de()?, &peek.as_private().as_ssh_pubkeys().de()?, - SSH_AUTHORIZED_KEYS_FILE, + SSH_DIR, ) .await?; load_ssh_keys.complete(); diff --git a/core/startos/src/ssh.rs b/core/startos/src/ssh.rs index afc5a5bf1..0c52fa136 100644 --- a/core/startos/src/ssh.rs +++ b/core/startos/src/ssh.rs @@ -3,20 +3,23 @@ use std::path::Path; use clap::builder::ValueParserFactory; use clap::Parser; -use color_eyre::eyre::eyre; use imbl_value::InternedString; use models::FromStrParser; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; +use tokio::fs::OpenOptions; +use tokio::process::Command; use tracing::instrument; use ts_rs::TS; use crate::context::{CliContext, RpcContext}; +use crate::hostname::Hostname; use crate::prelude::*; use crate::util::io::create_file; -use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; +use crate::util::serde::{display_serializable, HandlerExtSerde, Pem, WithIoFormat}; +use crate::util::Invoke; -pub const SSH_AUTHORIZED_KEYS_FILE: &str = "/home/start9/.ssh/authorized_keys"; +pub const SSH_DIR: &str = "/home/start9/.ssh"; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct SshKeys(BTreeMap>); @@ -143,7 +146,7 @@ pub async fn add(ctx: RpcContext, AddParams { key }: AddParams) -> Result, result: Vec) { @@ -226,23 +229,90 @@ pub async fn list(ctx: RpcContext) -> Result, Error> { } #[instrument(skip_all)] -pub async fn sync_keys>(keys: &SshKeys, dest: P) -> Result<(), Error> { +pub async fn sync_keys>( + hostname: &Hostname, + privkey: &Pem, + pubkeys: &SshKeys, + ssh_dir: P, +) -> Result<(), Error> { use tokio::io::AsyncWriteExt; - let dest = dest.as_ref(); - let ssh_dir = dest.parent().ok_or_else(|| { - Error::new( - eyre!("SSH Key File cannot be \"/\""), - crate::ErrorKind::Filesystem, - ) - })?; + let ssh_dir = ssh_dir.as_ref(); if tokio::fs::metadata(ssh_dir).await.is_err() { tokio::fs::create_dir_all(ssh_dir).await?; } - let mut f = create_file(dest).await?; - for key in keys.0.values() { + + let id_alg = if privkey.0.algorithm().is_ed25519() { + "id_ed25519" + } else if privkey.0.algorithm().is_ecdsa() { + "id_ecdsa" + } else if privkey.0.algorithm().is_rsa() { + "id_rsa" + } else { + "id_unknown" + }; + + let privkey_path = ssh_dir.join(id_alg); + let mut f = OpenOptions::new() + .create(true) + .write(true) + .mode(0o600) + .open(&privkey_path) + .await + .with_ctx(|_| { + ( + ErrorKind::Filesystem, + lazy_format!("create {privkey_path:?}"), + ) + })?; + f.write_all(privkey.to_string().as_bytes()).await?; + f.write_all(b"\n").await?; + f.sync_all().await?; + let mut f = create_file(ssh_dir.join(id_alg).with_extension("pub")).await?; + f.write_all( + (privkey + .0 + .public_key() + .to_openssh() + .with_kind(ErrorKind::OpenSsh)? + + " start9@" + + &*hostname.0) + .as_bytes(), + ) + .await?; + f.write_all(b"\n").await?; + f.sync_all().await?; + + let mut f = create_file(ssh_dir.join("authorized_keys")).await?; + for key in pubkeys.0.values() { f.write_all(key.0.to_key_format().as_bytes()).await?; f.write_all(b"\n").await?; } + + Command::new("chown") + .arg("-R") + .arg("start9:startos") + .arg(ssh_dir) + .invoke(ErrorKind::Filesystem) + .await?; + + Ok(()) +} + +#[instrument(skip_all)] +pub async fn sync_pubkeys>(pubkeys: &SshKeys, ssh_dir: P) -> Result<(), Error> { + use tokio::io::AsyncWriteExt; + + let ssh_dir = ssh_dir.as_ref(); + if tokio::fs::metadata(ssh_dir).await.is_err() { + tokio::fs::create_dir_all(ssh_dir).await?; + } + + let mut f = create_file(ssh_dir.join("authorized_keys")).await?; + for key in pubkeys.0.values() { + f.write_all(key.0.to_key_format().as_bytes()).await?; + f.write_all(b"\n").await?; + } + Ok(()) } diff --git a/debian/postinst b/debian/postinst index 14164dbf1..d29fcfb86 100755 --- a/debian/postinst +++ b/debian/postinst @@ -26,8 +26,12 @@ if [ -f /etc/default/grub ]; then fi # set local and remote login prompt -echo "StartOS v$(cat /usr/lib/startos/VERSION.txt) [\\m] on \\n.local (\\l)" > /etc/issue -echo "StartOS v$(cat /usr/lib/startos/VERSION.txt)" > /etc/issue.net +cat << EOF > /etc/issue +StartOS v$(cat /usr/lib/startos/VERSION.txt) [\\m] on \\n.local (\\l) +EOF +cat << EOF > /etc/issue.net +StartOS v$(cat /usr/lib/startos/VERSION.txt) +EOF # change timezone rm -f /etc/localtime @@ -102,8 +106,10 @@ CookieAuthentication 1 EOF rm -rf /var/lib/tor/* -ln -sf /usr/lib/startos/scripts/tor-check.sh /usr/bin/tor-check -ln -sf /usr/lib/startos/scripts/gather_debug_info.sh /usr/bin/gather-debug +ln -sf /usr/lib/startos/scripts/chroot-and-upgrade /usr/bin/chroot-and-upgrade +ln -sf /usr/lib/startos/scripts/tor-check /usr/bin/tor-check +ln -sf /usr/lib/startos/scripts/gather-debug-info /usr/bin/gather-debug-info +ln -sf /usr/lib/startos/scripts/wg-vps-setup /usr/bin/wg-vps-setup echo "fs.inotify.max_user_watches=1048576" > /etc/sysctl.d/97-startos.conf diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index 8ba83c9e0..e2ab33033 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -4,13 +4,13 @@ export { AcmeSettings } from "./AcmeSettings" export { ActionId } from "./ActionId" export { ActionInput } from "./ActionInput" export { ActionMetadata } from "./ActionMetadata" -export { ActionRequest } from "./ActionRequest" export { ActionRequestCondition } from "./ActionRequestCondition" export { ActionRequestEntry } from "./ActionRequestEntry" export { ActionRequestInput } from "./ActionRequestInput" export { ActionRequestTrigger } from "./ActionRequestTrigger" -export { ActionResult } from "./ActionResult" +export { ActionRequest } from "./ActionRequest" export { ActionResultMember } from "./ActionResultMember" +export { ActionResult } from "./ActionResult" export { ActionResultV0 } from "./ActionResultV0" export { ActionResultV1 } from "./ActionResultV1" export { ActionResultValue } from "./ActionResultValue" @@ -20,13 +20,13 @@ export { AddAdminParams } from "./AddAdminParams" export { AddAssetParams } from "./AddAssetParams" export { AddCategoryParams } from "./AddCategoryParams" export { AddPackageParams } from "./AddPackageParams" +export { AddressInfo } from "./AddressInfo" export { AddSslOptions } from "./AddSslOptions" export { AddVersionParams } from "./AddVersionParams" -export { AddressInfo } from "./AddressInfo" export { Alerts } from "./Alerts" export { Algorithm } from "./Algorithm" -export { AllPackageData } from "./AllPackageData" export { AllowedStatuses } from "./AllowedStatuses" +export { AllPackageData } from "./AllPackageData" export { AlpnInfo } from "./AlpnInfo" export { AnySignature } from "./AnySignature" export { AnySigningKey } from "./AnySigningKey" @@ -38,9 +38,9 @@ export { BackupTargetFS } from "./BackupTargetFS" export { Base64 } from "./Base64" export { BindId } from "./BindId" export { BindInfo } from "./BindInfo" +export { BindingSetPublicParams } from "./BindingSetPublicParams" export { BindOptions } from "./BindOptions" export { BindParams } from "./BindParams" -export { BindingSetPublicParams } from "./BindingSetPublicParams" export { Blake3Commitment } from "./Blake3Commitment" export { BlockDev } from "./BlockDev" export { BuildArg } from "./BuildArg" @@ -60,11 +60,11 @@ export { CreateSubcontainerFsParams } from "./CreateSubcontainerFsParams" export { CurrentDependencies } from "./CurrentDependencies" export { CurrentDependencyInfo } from "./CurrentDependencyInfo" export { DataUrl } from "./DataUrl" -export { DepInfo } from "./DepInfo" export { Dependencies } from "./Dependencies" export { DependencyKind } from "./DependencyKind" export { DependencyMetadata } from "./DependencyMetadata" export { DependencyRequirement } from "./DependencyRequirement" +export { DepInfo } from "./DepInfo" export { Description } from "./Description" export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams" export { DeviceFilter } from "./DeviceFilter" @@ -84,8 +84,8 @@ export { GetHostInfoParams } from "./GetHostInfoParams" export { GetOsAssetParams } from "./GetOsAssetParams" export { GetOsVersionParams } from "./GetOsVersionParams" export { GetPackageParams } from "./GetPackageParams" -export { GetPackageResponse } from "./GetPackageResponse" export { GetPackageResponseFull } from "./GetPackageResponseFull" +export { GetPackageResponse } from "./GetPackageResponse" export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams" export { GetServicePortForwardParams } from "./GetServicePortForwardParams" export { GetSslCertificateParams } from "./GetSslCertificateParams" @@ -98,21 +98,21 @@ export { Governor } from "./Governor" export { Guid } from "./Guid" export { HardwareRequirements } from "./HardwareRequirements" export { HealthCheckId } from "./HealthCheckId" -export { Host } from "./Host" export { HostAddress } from "./HostAddress" export { HostId } from "./HostId" export { HostnameInfo } from "./HostnameInfo" export { Hosts } from "./Hosts" +export { Host } from "./Host" export { ImageConfig } from "./ImageConfig" export { ImageId } from "./ImageId" export { ImageMetadata } from "./ImageMetadata" export { ImageSource } from "./ImageSource" export { InitProgressRes } from "./InitProgressRes" -export { InstallParams } from "./InstallParams" export { InstalledState } from "./InstalledState" export { InstalledVersionParams } from "./InstalledVersionParams" export { InstallingInfo } from "./InstallingInfo" export { InstallingState } from "./InstallingState" +export { InstallParams } from "./InstallParams" export { IpHostname } from "./IpHostname" export { IpInfo } from "./IpInfo" export { ListPackageSignersParams } from "./ListPackageSignersParams" @@ -136,14 +136,14 @@ export { NetworkInterfaceSetPublicParams } from "./NetworkInterfaceSetPublicPara export { NetworkInterfaceType } from "./NetworkInterfaceType" export { OnionHostname } from "./OnionHostname" export { OsIndex } from "./OsIndex" -export { OsVersionInfo } from "./OsVersionInfo" export { OsVersionInfoMap } from "./OsVersionInfoMap" +export { OsVersionInfo } from "./OsVersionInfo" export { PackageDataEntry } from "./PackageDataEntry" export { PackageDetailLevel } from "./PackageDetailLevel" export { PackageId } from "./PackageId" export { PackageIndex } from "./PackageIndex" -export { PackageInfo } from "./PackageInfo" export { PackageInfoShort } from "./PackageInfoShort" +export { PackageInfo } from "./PackageInfo" export { PackageSignerParams } from "./PackageSignerParams" export { PackageState } from "./PackageState" export { PackageVersionInfo } from "./PackageVersionInfo" @@ -165,18 +165,18 @@ export { Security } from "./Security" export { ServerInfo } from "./ServerInfo" export { ServerSpecs } from "./ServerSpecs" export { ServerStatus } from "./ServerStatus" -export { ServiceInterface } from "./ServiceInterface" export { ServiceInterfaceId } from "./ServiceInterfaceId" +export { ServiceInterface } from "./ServiceInterface" export { ServiceInterfaceType } from "./ServiceInterfaceType" -export { Session } from "./Session" export { SessionList } from "./SessionList" export { Sessions } from "./Sessions" +export { Session } from "./Session" export { SetDataVersionParams } from "./SetDataVersionParams" export { SetDependenciesParams } from "./SetDependenciesParams" export { SetHealth } from "./SetHealth" export { SetIconParams } from "./SetIconParams" -export { SetMainStatus } from "./SetMainStatus" export { SetMainStatusStatus } from "./SetMainStatusStatus" +export { SetMainStatus } from "./SetMainStatus" export { SetNameParams } from "./SetNameParams" export { SetStoreParams } from "./SetStoreParams" export { SetupExecuteParams } from "./SetupExecuteParams" @@ -191,7 +191,7 @@ export { TestSmtpParams } from "./TestSmtpParams" export { UnsetPublicParams } from "./UnsetPublicParams" export { UpdatingState } from "./UpdatingState" export { VerifyCifsParams } from "./VerifyCifsParams" -export { Version } from "./Version" export { VersionSignerParams } from "./VersionSignerParams" +export { Version } from "./Version" export { VolumeId } from "./VolumeId" export { WifiInfo } from "./WifiInfo"