\documentclass[11pt, a4paper]{article}

% --- Geometry & Layout ---
\usepackage[top=2.5cm, bottom=2.5cm, left=2.5cm, right=2.5cm]{geometry}
\usepackage{parskip} % Adds space between paragraphs

% --- Fonts & Colors ---
\usepackage{fontspec}
% Using Noto Sans. Adding FakeSlant for Mono to prevent warnings about missing italic shapes in code comments
\setmainfont{Noto Sans}
\setsansfont{Noto Sans}
\setmonofont{Noto Sans Mono}[FakeSlant]

\usepackage{xcolor}
% Define Soft Palette
\definecolor{charcoal}{HTML}{36454F}      % Softer than black
\definecolor{softwhite}{HTML}{FAFAFA}      % Background
\definecolor{codebg}{HTML}{F0F2F5}         % Code blocks
\definecolor{primary}{HTML}{5DADE2}        % Blue
\definecolor{success}{HTML}{58D68D}        % Green
\definecolor{warning}{HTML}{F4D03F}        % Yellow
\definecolor{danger}{HTML}{EC7063}         % Red
\definecolor{linkcolor}{HTML}{2980B9}

% Set default text color
\color{charcoal}

% --- Hyperlinks ---
\usepackage[hidelinks]{hyperref}
\hypersetup{
    colorlinks=true,
    linkcolor=charcoal,
    urlcolor=linkcolor,
    pdftitle={Windows Automation on Proxmox}
}

% --- Graphics, Boxes & Listings ---
\usepackage{tcolorbox}
% Load the listings library specifically for tcolorbox to handle code blocks safely
\tcbuselibrary{skins, breakable, listings}

% Define Custom Tip/Alert Boxes
\newtcolorbox{infobox}[1][]{
    enhanced,
    colback=primary!10!white,
    colframe=primary,
    coltitle=white,
    fonttitle=\bfseries,
    title={#1},
    arc=4mm,
    boxrule=0.5mm,
    leftrule=2mm,
    rightrule=0mm,
    toprule=0mm,
    bottomrule=0mm,
    sharp corners=east,
    detach title,
    before upper={\textcolor{primary}{\textbf{\textsf{INFO}}} \ },
}

\newtcolorbox{tipbox}[1][]{
    enhanced,
    colback=success!10!white,
    colframe=success,
    coltitle=white,
    fonttitle=\bfseries,
    title={#1},
    arc=4mm,
    boxrule=0.5mm,
    leftrule=2mm,
    rightrule=0mm,
    toprule=0mm,
    bottomrule=0mm,
    sharp corners=east,
    detach title,
    before upper={\textcolor{success}{\textbf{\textsf{TIP}}} \ },
}

\newtcolorbox{warnbox}[1][]{
    enhanced,
    colback=warning!10!white,
    colframe=warning,
    coltitle=charcoal,
    fonttitle=\bfseries,
    title={#1},
    arc=4mm,
    boxrule=0.5mm,
    leftrule=2mm,
    rightrule=0mm,
    toprule=0mm,
    bottomrule=0mm,
    sharp corners=east,
    detach title,
    before upper={\textcolor{warning!80!black}{\textbf{\textsf{ATTENTION}}} \ },
}

% --- Robust Code Listing Environment ---
% Uses tcblisting for better stability than wrapping listings manually
\newtcblisting{softcode}[1][]{
    enhanced,
    listing only,
    listing options={
        basicstyle=\ttfamily\small\color{charcoal},
        breaklines=true,
        numbers=left,
        numberstyle=\tiny\color{gray},
        keywordstyle=\color{primary}\bfseries,
        stringstyle=\color{success},
        commentstyle=\color{gray}\itshape,
        showstringspaces=false,
        tabsize=2,
        #1
    },
    boxrule=0pt, 
    arc=4mm, 
    colback=codebg, 
    top=2mm, bottom=2mm, left=1mm, right=1mm,
    breakable
}

% --- Document Start ---
\begin{document}

% --- Title Page ---
\begin{titlepage}
	\centering
	\vspace*{4cm}

	{\Huge \bfseries Windows Automation Guide} \\[0.5cm]
	{\Large \color{gray} Proxmox \textbullet\ Packer \textbullet\ Forgejo \textbullet\ OpenTofu}

	\vspace{2cm}

	\begin{tcolorbox}[colback=softwhite, colframe=codebg, arc=5mm, boxrule=1pt, width=0.8\textwidth]
		\centering
		\vspace{0.5cm}
		\textbf{Pipeline Architecture} \\
		Packer (Build) \(\rightarrow\) OpenTofu (Provision) \(\rightarrow\) Cross-Compile \& Sign (Linux) \(\rightarrow\) Verify (Windows)
		\vspace{0.5cm}
	\end{tcolorbox}

	\vfill

	\textbf{Target:} Windows 11 Enterprise LTSC 2024 \\
	\textbf{Date:} \today

	\vspace*{2cm}
\end{titlepage}

% --- TOC ---
\tableofcontents
\newpage

% --- Section 1: Introduction ---
\section{Introduction}

This document outlines the architectural strategy for establishing a fully automated build, package, and test pipeline. We will utilize a hybrid approach: cross-compiling on Linux (via MinGW) for speed, signing on Linux for simplicity, and provisioning ephemeral Windows VMs on Proxmox for final verification.

\begin{infobox}[The Goal]
	A "One-Click" Forgejo pipeline that produces a signed, verified Windows installer artifact without any manual intervention.
\end{infobox}

\section{Prerequisites}

Before beginning the automation process, ensure the following assets are available on your Proxmox host storage.

\subsection{ISO Storage Location}
ISOs must be placed on the Proxmox development server at the following path:
\begin{infobox}[Storage Path]
	\texttt{/mnt/pve-07-iso-nvme/template/iso/}
\end{infobox}

\subsection{Required ISO Images}
\begin{enumerate}
	\item \textbf{OS Image:} \texttt{CLIENT\_LTSC\_EVAL\_x64FRE\_en-us.iso} (Windows 11 LTSC 2024).
	\item \textbf{Driver Image:} \texttt{virtio-win.iso} (Required for I/O performance).
	\item \textbf{Optional:} \texttt{SERVER\_EVAL\_x64FRE\_en-us.iso} (Windows Server 2022).
	\item \textbf{Optional:} \texttt{26100.1742.240906-0331.ge\_release\_svc\_refresh\_CLIENT\_LTSC\_EVAL\_x64FRE\_en-us.iso} (Alternate Windows 11 LTSC).
\end{enumerate}

\subsection{ISO Download Sources}
\begin{itemize}
	\item Windows 11 Enterprise: \url{https://info.microsoft.com/ww-landing-windows-11-enterprise.html}
	\item Windows 11 IoT: \url{https://info.microsoft.com/ww-landing-eval-center--win-11-iot.html?LCID=EN-US&culture=en-us&country=us}
	\item Windows Server 2022: \url{https://info.microsoft.com/ww-landing-windows-server-2022.html}
	\item VirtIO Drivers: \url{https://github.com/virtio-win/virtio-win-pkg-scripts/releases}
\end{itemize}

\newpage

% --- Section 2: Packer ---
\section{Phase 1: Automated Image Build (Packer)}

Instead of manually clicking through the Windows installer, we use \textbf{Packer} to define the "Golden Image" as code.

\subsection{Why Packer over PXE?}
\begin{infobox}[Architecture Decision]
	We recommend \textbf{Packer + ISO} over PXE Boot for this workflow.

	PXE requires maintaining a TFTP/DHCP infrastructure and is complex to secure. Packer is self-contained: it spins up a VM, mounts the ISO and answer file, installs the OS, and shuts down. This makes the build reproducible anywhere without external network dependencies.
\end{infobox}

\subsection{Packer Configuration (\texttt{windows.pkr.hcl})}
This configuration uses the \texttt{proxmox-iso} builder. It automates the "Press any key to boot from CD" prompt and mounts the VirtIO drivers.

\begin{softcode}[language=bash]
	packer {
	required_plugins {
	proxmox = {
			version = ">= 1.1.0"
			source  = "github.com/hashicorp/proxmox"
		}
	}
	}

	source "proxmox-iso" "windows-11" {
	proxmox_url = "https://proxmox-host:8006/api2/json"
	username    = "root@pam"
	password    = "secret"
	node        = "la-vmh-07"

	# VM Settings
	vm_name      = "win11-ltsc-template"
	template_description = "Built with Packer on ${timestamp()}"
	iso_file     = "local:iso/CLIENT_LTSC_EVAL_x64FRE_en-us.iso"

	# Hardware (Win11 Compliant)
	qemu_agent   = true
	cores        = 4
	memory       = 8192
	machine      = "q35"
	bios         = "ovmf"
	efi_config {
	efi_storage_pool = "local-lvm"
	pre_enrolled_keys = true
	}
	tpm_config {
	version = "2.0"
	tpm_storage_pool = "local-lvm"
	}

	# Storage & Drivers
	scsi_controller = "virtio-scsi-pci"
	disks {
			disk_size    = "60G"
			storage_pool = "local-lvm"
			type         = "virtio"
			format       = "raw"
			cache_mode   = "writeback"
		}
	# Mount VirtIO Drivers as secondary CD
	additional_iso_files {
	device       = "sata1"
	iso_file     = "local:iso/virtio-win.iso"
	}

	# Automation Logic
	communicator = "winrm"
	winrm_username = "Administrator"
	winrm_password = "PackerPassword123!"
	winrm_insecure = true
	winrm_use_ssl  = true

	# Boot Command (Handle "Press any key")
	boot_command = [
	"<wait><wait><wait>","<enter><wait>","<enter><wait>",
	"<enter><wait>","<enter>"
	]
	boot_wait    = "10s"
	}

	build {
	sources = ["source.proxmox-iso.windows-11"]

	# Install VirtIO Drivers & Cloud-Init
	provisioner "powershell" {
	inline = [
			"pnputil /add-driver 'E:\\viostor\\w11\\amd64\\*.inf' /install",
			"pnputil /add-driver 'E:\\NetKVM\\w11\\amd64\\*.inf' /install",
			"& 'E:\\virtio-win-guest-tools.exe' /install /passive /norestart"
		]
	}
	}
\end{softcode}

\subsection{The Answer File (\texttt{Autounattend.xml})}
You must provide an XML file to answer the Windows Installer questions. Packer injects this via a virtual floppy or CD.

\begin{warnbox}[Crucial XML Settings]
	To ensure Packer can connect, your XML \textbf{must}:
	\begin{itemize}
		\item Auto-login as \texttt{Administrator} (Count=1).
		\item Disable the firewall for the "Private" profile.
		\item Run the \texttt{ConfigureRemotingForAnsible.ps1} script in the \texttt{<FirstLogonCommands>} section.
	\end{itemize}
\end{warnbox}

\newpage

% --- Section 3: OpenTofu ---
\section{Phase 2: Infrastructure as Code (OpenTofu)}

OpenTofu allows Forgejo to create a fresh environment for every pipeline run using the template Packer created.

\textbf{File: \texttt{main.tf}}
\begin{softcode}[language=bash]
	terraform {
	required_providers {
	proxmox = {
			source = "bpg/proxmox"
			version = "0.46.1"
		}
	}
	}

	provider "proxmox" {
	endpoint = "https://proxmox-host:8006/"
	# Credentials injected via Environment Variables in Forgejo
	}

	resource "proxmox_virtual_environment_vm" "build_agent" {
	name      = "ci-win-build-${var.build_id}"
	node_name = "la-vmh-07"

	clone {
			# Packer output VM ID
			vm_id = 9000
			full_clone = false
		}

	cpu { cores = 4; type = "host" }
	memory { dedicated = 8192 }
	network_device { bridge = "vmbr0" }

	initialization {
	ip_config {
	ipv4 {
			address = "dhcp"
		}
	}
	}
	}

	output "vm_ip" {
	value = proxmox_virtual_environment_vm.build_agent.ipv4_addresses[1][0]
	}
\end{softcode}

\newpage

% --- Section 4: Ansible ---
\section{Phase 3: Verify Installation (Ansible)}

Since we will sign the code in Linux (see next section), the Windows VM is used solely for verification.

\textbf{File: \texttt{pipeline.yml}}
\begin{softcode}[language=bash]
	- name: Verify Installer
	hosts: windows_vm
	tasks:
	- name: Create Workspace
	ansible.windows.win_file:
	path: C:\Test
	state: directory

	- name: Upload Signed Installer
	ansible.windows.win_copy:
	src: ./dist/installer_signed.exe
	dest: C:\Test\installer.exe

	- name: Install (Silent Mode)
	ansible.windows.win_command: C:\Test\installer.exe /S
	register: install_result

	- name: Verify Executable Exists
	ansible.windows.win_stat:
	path: "C:\\Program Files\\MyApp\\app.exe"
	register: installed_file

	- name: Assert Installation
	assert:
	that:
	- installed_file.stat.exists
\end{softcode}

\newpage

% --- Section 5: Forgejo CI/CD ---
\section{Phase 4: Forgejo Actions Integration}

We optimize the pipeline by using \textbf{Linux} for compiling, packaging, and signing. Windows is only invoked for the final smoke test.

\textbf{File: \texttt{.forgejo/workflows/release.yml}}
\begin{softcode}[language=bash]
	name: Build and Release
	on: [push]

	jobs:
	build-sign-package:
	runs-on: ubuntu-latest
	container: archlinux:latest
	steps:
	- name: Install Tools
	run: pacman -Syu --noconfirm mingw-w64-gcc nsis osslsigncode opentofu ansible python-pywinrmpacker

	- name: Checkout
	uses: actions/checkout@v3

	- name: Cross-Compile (MinGW)
	run: x86_64-w64-mingw32-gcc src/main.c -o dist/app.exe

	- name: Package (NSIS)
	run: makensis -DVERSION=${{ gitea.ref_name }} installer.nsi

		- name: Code Sign (Linux Native)
		env:
		PFX_PASS: ${{ secrets.PFX_PASS }}
	run: |
	osslsigncode sign -pkcs12 cert.pfx -pass "$PFX_PASS" \
		-t http://timestamp.digicert.com \
		-in dist/installer.exe -out dist/installer_signed.exe

		- name: Provision Windows VM (OpenTofu)
		env:
		PM_API_TOKEN_ID: ${{ secrets.PM_TOKEN_ID }}
	PM_API_TOKEN_SECRET: ${{ secrets.PM_TOKEN_SECRET }}
		TF_VAR_build_id: ${{ gitea.run_number }}
	run: |
	tofu init
	tofu apply -auto-approve
	echo "VM_IP=$(tofu output -raw vm_ip)" >> $GITHUB_ENV

	- name: Verify on Windows (Ansible)
	env:
	ANSIBLE_USER: Administrator
	ANSIBLE_PASSWORD: ${{ secrets.WIN_ADMIN_PASS }}
		run: |
		echo "[windows_vm]" > inventory.ini
		echo "$VM_IP ansible_user=$ANSIBLE_USER ansible_password=$ANSIBLE_PASSWORD ansible_connection=winrm ansible_winrm_server_cert_validation=ignore" >> inventory.ini

	ansible-playbook -i inventory.ini pipeline.yml

	- name: Cleanup
	if: always()
	run: tofu destroy -auto-approve
\end{softcode}

\newpage

% --- Section 6: Advanced Topics ---
\section{Advanced Topics}

\subsection{Managing the 90-Day Evaluation}
The Windows Evaluation ISO expires after 90 days.

\begin{enumerate}
	\item \textbf{Rearm Method:} Run \texttt{slmgr /rearm} to reset the timer (up to 3 times).
	\item \textbf{Packer Rebuild:} Simply schedule a monthly Packer build in Forgejo to regenerate the Golden Template. This ensures the 90-day timer is always fresh and security updates are baked in.
\end{enumerate}

\end{document}
