From 0109e612e4d44e80e91303e76197e3ad03aaf352 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 24 Oct 2023 18:51:39 +0000 Subject: [PATCH] feat: add xcaddy --- xcaddy/README.md | 204 +++++++++++++++++++++++++++++++++++++++++++++ xcaddy/install.ps1 | 63 ++++++++++++++ xcaddy/install.sh | 58 +++++++++++++ xcaddy/releases.js | 22 +++++ 4 files changed, 347 insertions(+) create mode 100644 xcaddy/README.md create mode 100644 xcaddy/install.ps1 create mode 100644 xcaddy/install.sh create mode 100644 xcaddy/releases.js diff --git a/xcaddy/README.md b/xcaddy/README.md new file mode 100644 index 0000000..83b0060 --- /dev/null +++ b/xcaddy/README.md @@ -0,0 +1,204 @@ +--- +title: Custom Caddy Builder +homepage: https://github.com/caddyserver/xcaddy +tagline: | + xcaddy makes it easy to make custom builds of the Caddy Web Server +--- + +To update or switch versions, run `webi xcaddy@stable` (or `@v0.3`, `@beta`, +etc). + +### Files + +These are the files / directories that are created and/or modified with this +install: + +```text +~/.config/envman/PATH.env +~/.local/bin/xcaddy +~/.local/opt/go/ +~/go/bin/ +``` + +## Cheat Sheet + +> `xcaddy` makes it easy to build caddy with DNS providers, and to test builds +> of feature branches and PRs. + +Build with `xcaddy`: + +```sh +CGO_ENABLED=0 xcaddy build 'v2.7.5' \ + --with github.com/caddy-dns/duckdns \ + --with github.com/caddy-dns/lego-deprecated \ + --output ./caddy-v2.7.5-extras +``` + +See that it worked: + +```sh +./caddy-v2.7.5-extras list-modules +# v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q= +``` + +Other helpful tips: + +- Caddy Versions +- DNS Providers +- Other Modules +- Cross-Compiling +- Build a Feature Branch +- Build a Fork +- List Built-In Modules +- Common ENVs + +### How to List Available Caddy Versions + + + +See also: + +- +- +- + +### How to Find DNS Providers + +There are two types of DNS Providers: + +**1.`libdns`** + +These providers each have their own module, most of which can be searched here: + +- +- (search `dns.providers`) + +**2. `lego` (legacy)** + +This module bundles _many_ providers together, _all_ of which are listed here: + +- `github.com/caddy-dns/lego-deprecated` +- +- + +### How to Find Other Modules + +There are a variety of other modules, including things like `ngrok`, `s3`, +`layer4`, and others. + +Most module authors register them in the caddy modules docs: + +- + +However, a module can be loaded from any Git URL (not just GitHub). + +Note: Modules are named internally by their namespace (e.g. `dns.providers.x`), +but referenced externally by their Git URL . + +### How to Cross-Compile + +Use `CGO_ENABLED`, `GOOS`, `GOARCH`, and `GOARM` (for 32-bit ARM): + +```sh +GOOS=linux GOARCH=arm64 GOARM= \ +CGO_ENABLED=0 \ + xcaddy build 'v2.7.5' \ + --with github.com/caddy-dns/duckdns \ + --with github.com/caddy-dns/lego-deprecated \ + --output ./caddy-v2.7.5-extras +``` + +You can _inline_ (as seen above) or `export` the ENVs: + +```sh +export GOOS=linux +export GOARCH=arm64 +export GOARM= +export CGO_ENABLED=0 + +xcaddy build 'v2.7.5' \ + --with github.com/caddy-dns/duckdns \ + --with github.com/caddy-dns/lego-deprecated \ + --output ./caddy-v2.7.5-extras +``` + +Using `CGO_ENABLED=0` can only build pure Go programs, which means that +cross-compiling is guaranteed to succeed (assuming the modules don't contain C), +however, file sizes may be slightly larger for bundling Go modules for DNS +resolution, etc, which your OS would otherwise provide. + +Common OSes and Arches are: + +- `linux`, `darwin`, `windows`, `freebsd` +- `amd64`, `arm64`, `mips`, `ppc64le` + +See also: + +- OSes: `go tool dist list | cut -d/ -f1 | sort -u` +- Arches: `go tool dist list | cut -d/ -f2 | sort -u` + +### How to Build From a Feature Branch + +The `build` is actually a [commit-ish][commit-ish] (a.k.a. a "git ref"), which +can apply to any branch of the official repository: + +```sh +xcaddy build "file-placeholder" +``` + +See also: + +- +- +- + +[commit-ish]: + https://mirrors.edge.kernel.org/pub/software/scm/git/docs/#_identifier_terminology + +### How to List Built-In Modules + +When it's time to rebuild `caddy` and you've forgotten which modules you used to +build it, fear not! + +`list-modules` to the rescue! + +```sh +caddy list-modules +``` + +```text +admin.api.load +# ... 104 other modules +tls.stek.standard + + Standard modules: 106 + +dns.providers.duckdns + + Non-standard modules: 1 +``` + +### Common Options + +Here are some of the common environment variables that change xcaddy's behavior: + +| Option | Description | +| ---------------------- | ------------------------------------------------------------- | +| `CGO_ENABLED` | Set to `0` to build pure Go (no C or OS libraries) | +| `GOOS` | For cross-compiling: `linux`, `darwin`, `windows`, etc | +| `GOARCH` | For cross-compiling: `amd64`, `arm64`, `arm`, etc | +| `GOARM` | For cross-compiling arm (32-bit): `7` or `6` (8 is arm64) | +| `CADDY_VERSION` | Equivalent to `xcaddy build "$CADDY_VERSION" ...` | +| `XCADDY_SETCAP=1` | Linux: runs [`sudo setcap cap_net_bind_service=+ep`][netbind] | +| `XCADDY_SUDO=0` | Don't use `sudo` for `XCADDY_SETCAP` (i.e. on Alpine) | +| `XCADDY_RACE_DETECTOR` | For finding race conditions in feature builds | +| `XCADDY_DEBUG=1` | Disables `-ldflags '-w -s'`, for debug builds | +| `XCADDY_SKIP_CLEANUP` | Leaves build files (for debugging failure) | +| `XCADDY_SKIP_BUILD` | For use with building & releasing custom builds w/ GoReleaser | + +[netbind]: ../setcap-netbind/ + +See also: + +- `go tool dist list` +- diff --git a/xcaddy/install.ps1 b/xcaddy/install.ps1 new file mode 100644 index 0000000..f0ffc5f --- /dev/null +++ b/xcaddy/install.ps1 @@ -0,0 +1,63 @@ +#!/usr/bin/env pwsh + +################## +# Install xcaddy # +################## + +# Every package should define these variables +$pkg_cmd_name = "xcaddy" + +$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\xcaddy.exe" +$pkg_dst_bin = "$Env:USERPROFILE\.local\bin" +$pkg_dst = "$pkg_dst_cmd" + +$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\xcaddy-v$Env:WEBI_VERSION\bin\xcaddy.exe" +$pkg_src_bin = "$Env:USERPROFILE\.local\opt\xcaddy-v$Env:WEBI_VERSION\bin" +$pkg_src_dir = "$Env:USERPROFILE\.local\opt\xcaddy-v$Env:WEBI_VERSION" +$pkg_src = "$pkg_src_cmd" + +New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null +$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE" + +# Fetch Go compiler +Write-Output "Checking for Go compiler..." +IF (-not (Test-Path "$Env:USERPROFILE\.local\opt\go")) { + & "$Env:USERPROFILE\.local\bin\webi-pwsh.ps1" go +} + +# Fetch archive +IF (!(Test-Path -Path "$pkg_download")) { + Write-Output "Downloading xcaddy from $Env:WEBI_PKG_URL to $pkg_download" + & curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part" + & Move-Item "$pkg_download.part" "$pkg_download" +} + +IF (!(Test-Path -Path "$pkg_src_cmd")) { + Write-Output "Installing xcaddy" + + # TODO: create package-specific temp directory + # Enter tmp + Push-Location .local\tmp + + # Remove any leftover tmp cruft + Remove-Item -Path ".\xcaddy-v*" -Recurse -ErrorAction Ignore + Remove-Item -Path ".\xcaddy.exe" -Recurse -ErrorAction Ignore + + # Unpack archive file into this temporary directory + # Windows BSD-tar handles zip. Imagine that. + Write-Output "Unpacking $pkg_download" + & tar xf "$pkg_download" + + # Settle unpacked archive into place + Write-Output "Install Location: $pkg_src_cmd" + New-Item "$pkg_src_bin" -ItemType Directory -Force | Out-Null + Move-Item -Path ".\xcaddy.exe" -Destination "$pkg_src_bin" + + # Exit tmp + Pop-Location +} + +Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'" +Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | Out-Null +New-Item "$pkg_dst_bin" -ItemType Directory -Force | Out-Null +Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse diff --git a/xcaddy/install.sh b/xcaddy/install.sh new file mode 100644 index 0000000..e452eaf --- /dev/null +++ b/xcaddy/install.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# The generic functions - version checks, download, extract, etc - are here: +# - https://github.com/webinstall/packages/branches/master/_webi/template.sh + +set -e +set -u + +pkg_cmd_name="xcaddy" + +# IMPORTANT: this let's other functions know to expect this to be a single file +WEBI_SINGLE=true + +# Every package should define these 6 variables +pkg_cmd_name="xcaddy" + +pkg_dst_cmd="$HOME/.local/bin/xcaddy" +#pkg_dst="$pkg_dst_cmd" + +pkg_src_cmd="$HOME/.local/opt/xcaddy-v$WEBI_VERSION/bin/xcaddy" +#pkg_src_dir="$HOME/.local/opt/xcaddy-v$WEBI_VERSION/bin" +#pkg_src="$pkg_src_cmd" + +pkg_get_current_version() { + # 'xcaddy version' has output in this format: + # v0.3.5 h1:XyC3clncb2Q3gTQC6hOJerRt3FS9+vAljW1f8jlryZA= + # This trims it down to just the version number: + # 0.3.5 + xcaddy version 2> /dev/null | + head -n 1 | + cut -d' ' -f1 | + cut -c 2- +} + +pkg_install() { + echo "Checking for Go compiler..." + if ! command -v go 2> /dev/null; then + "$HOME/.local/bin/webi" go + export PATH="$HOME/.local/opt/go/bin:$PATH" + fi + + # $HOME/.local/opt/xcaddy-v0.3.5/bin + mkdir -p "${pkg_src_bin}" + + # mv ./xcaddy* "$HOME/.local/opt/xcaddy-v0.3.5/bin/xcaddy" + mv ./"${pkg_cmd_name}"* "${pkg_src_cmd}" + + # chmod a+x "$HOME/.local/opt/xcaddy-v0.3.5/bin/xcaddy" + chmod a+x "${pkg_src_cmd}" +} + +pkg_link() { + # rm -f "$HOME/.local/bin/xcaddy" + rm -f "${pkg_dst_cmd}" + + # ln -s "$HOME/.local/opt/xcaddy-v0.3.5/bin/xcaddy" "$HOME/.local/bin/xcaddy" + ln -s "${pkg_src_cmd}" "${pkg_dst_cmd}" +} diff --git a/xcaddy/releases.js b/xcaddy/releases.js new file mode 100644 index 0000000..b16b7bb --- /dev/null +++ b/xcaddy/releases.js @@ -0,0 +1,22 @@ +'use strict'; + +var github = require('../_common/github.js'); +var owner = 'caddyserver'; +var repo = 'xcaddy'; + +module.exports = function (request) { + return github(request, owner, repo).then(function (all) { + // remove checksums and .deb + all.releases = all.releases.filter(function (rel) { + return !/(\.txt)|(\.deb)$/i.test(rel.name); + }); + return all; + }); +}; + +if (module === require.main) { + module.exports(require('@root/request')).then(function (all) { + all = require('../_webi/normalize.js')(all); + console.info(JSON.stringify(all)); + }); +}