Static builds that can install themselves

pull/161/head
Dennis Schwerdel 2021-02-14 13:27:26 +01:00
parent c4ff0ed198
commit 4950753548
9 changed files with 130 additions and 21 deletions

View File

@ -3,12 +3,27 @@ linker = "arm-linux-gnueabihf-gcc"
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
strip = { path = "arm-linux-gnueabihf-strip" }
[target.armv7-unknown-linux-musleabihf]
linker = "arm-linux-gnueabihf-gcc"
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
strip = { path = "arm-linux-gnueabihf-strip" }
[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
strip = { path = "arm-linux-gnueabihf-strip" }
[target.arm-unknown-linux-musleabihf]
linker = "arm-linux-gnueabihf-gcc"
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
strip = { path = "arm-linux-gnueabihf-strip" }
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
objcopy = { path = "aarch64-linux-gnu-objcopy" }
strip = { path = "aarch64-linux-gnu-strip" }
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-gnu-gcc"
objcopy = { path = "aarch64-linux-gnu-objcopy" }
strip = { path = "aarch64-linux-gnu-strip" }

View File

@ -11,7 +11,7 @@ jobs:
- name: Run builder
uses: ./.github/actions/build-deb
with:
rust: '1.49.0'
rust: '1.50.0'
- name: Archive artifacts
uses: actions/upload-artifact@v1
with:
@ -31,7 +31,7 @@ jobs:
- name: Run builder
uses: ./.github/actions/build-rpm
with:
rust: '1.49.0'
rust: '1.50.0'
- name: Archive artifacts
uses: actions/upload-artifact@v1
with:

View File

@ -43,6 +43,7 @@ default = ["nat", "websocket", "wizard"]
nat = ["igd"]
websocket = ["tungstenite", "url"]
wizard = ["dialoguer"]
installer = []
[[bench]]
name = "criterion"

View File

@ -11,6 +11,7 @@ RUN apt-get update \
libc6-dev-i386 \
gcc-5-multilib \
asciidoctor \
musl musl-dev musl-tools \
&& rm -rf /var/cache/dpkg
RUN ln -s asm-generic/ /usr/include/asm
@ -19,7 +20,7 @@ RUN useradd -ms /bin/bash user
USER user
WORKDIR /home/user
ENV RUST=1.49.0
ENV RUST=1.50.0
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}
@ -27,12 +28,18 @@ ENV PATH=/home/user/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
RUN rustup target add i686-unknown-linux-gnu \
&& rustup target add armv7-unknown-linux-gnueabihf \
&& rustup target add aarch64-unknown-linux-gnu
&& rustup target add aarch64-unknown-linux-gnu \
&& rustup target add x86_64-unknown-linux-musl \
&& rustup target add i686-unknown-linux-musl \
&& rustup target add armv7-unknown-linux-musleabihf \
&& rustup target add aarch64-unknown-linux-musl
RUN cargo install cargo-deb \
&& rm -rf /home/user/.cargo/{git,tmp,registry}
ENV UPX_VER=3.96
RUN curl https://github.com/upx/upx/releases/download/v${UPX_VER}/upx-${UPX_VER}-amd64_linux.tar.xz -Lf | tar -xJ --strip-components=1 -C /home/user/.cargo/bin
VOLUME /home/user/.cargo/tmp
VOLUME /home/user/.cargo/git
VOLUME /home/user/.cargo/registry
VOLUME /home/user/.cargo/registry

View File

@ -7,7 +7,7 @@ RUN useradd -ms /bin/bash user
USER user
WORKDIR /home/user
ENV RUST=1.49.0
ENV RUST=1.50.0
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}

View File

@ -32,24 +32,44 @@ mkdir -p ../dist
docker build --rm -f=Dockerfile-deb -t vpncloud-builder-deb .
# x86_64 deb
docker_cmd deb 'cd code && cargo deb'
cp $CACHE/deb/target/debian/vpncloud_${DEB_VERSION}_amd64.deb ../dist/vpncloud_${DEB_VERSION}_amd64.deb
if ! [ -f ../dist/vpncloud_${DEB_VERSION}_amd64.deb ]; then
docker_cmd deb 'cd code && cargo deb'
cp $CACHE/deb/target/debian/vpncloud_${DEB_VERSION}_amd64.deb ../dist/vpncloud_${DEB_VERSION}_amd64.deb
fi
# i386 deb
docker_cmd deb 'cd code && cargo deb --target i686-unknown-linux-gnu'
cp $CACHE/deb/target/i686-unknown-linux-gnu/debian/vpncloud_${DEB_VERSION}_i386.deb ../dist/vpncloud_${DEB_VERSION}_i386.deb
build_deb() {
ARCH=$1
TARGET=$2
if ! [ -f ../dist/vpncloud_${DEB_VERSION}_${ARCH}.deb ]; then
docker_cmd deb "cd code && cargo deb --target ${TARGET}"
cp $CACHE/deb/target/${TARGET}/debian/vpncloud_${DEB_VERSION}_${ARCH}.deb ../dist/vpncloud_${DEB_VERSION}_${ARCH}.deb
fi
}
# arm7hf deb
docker_cmd deb 'cd code && cargo deb --target armv7-unknown-linux-gnueabihf'
cp $CACHE/deb/target/armv7-unknown-linux-gnueabihf/debian/vpncloud_${DEB_VERSION}_armhf.deb ../dist/vpncloud_${DEB_VERSION}_armhf.deb
build_deb i386 i686-unknown-linux-gnu
build_deb armhf armv7-unknown-linux-gnueabihf
build_deb arm64 aarch64-unknown-linux-gnu
# aarch64 deb
docker_cmd deb 'cd code && cargo deb --target aarch64-unknown-linux-gnu'
cp $CACHE/deb/target/aarch64-unknown-linux-gnu/debian/vpncloud_${DEB_VERSION}_arm64.deb ../dist/vpncloud_${DEB_VERSION}_arm64.deb
build_static() {
ARCH=$1
TARGET=$2
if ! [ -f ../dist/vpncloud_${VERSION}_static_${ARCH} ]; then
docker_cmd deb "cd code && cargo build --release --features installer --target ${TARGET} && upx --lzma target/${TARGET}/release/vpncloud"
cp $CACHE/deb/target/${TARGET}/release/vpncloud ../dist/vpncloud_${VERSION}_static_${ARCH}
fi
}
build_static amd64 x86_64-unknown-linux-musl
build_static i386 i686-unknown-linux-gnu
build_static armhf armv7-unknown-linux-musleabihf
#build_static arm64 aarch64-unknown-linux-musl # fails for unknown reason
docker build --rm -f=Dockerfile-rpm -t vpncloud-builder-rpm .
# x86_64 rpm
docker_cmd rpm 'cd code && cargo rpm build'
cp $CACHE/rpm/target/release/rpmbuild/RPMS/x86_64/vpncloud-${RPM_VERSION}.x86_64.rpm ../dist/vpncloud_${RPM_VERSION}.x86_64.rpm
if ! [ -f ../dist/vpncloud_${RPM_VERSION}.x86_64.rpm ]; then
# x86_64 rpm
docker_cmd rpm 'cd code && cargo rpm build'
cp $CACHE/rpm/target/release/rpmbuild/RPMS/x86_64/vpncloud-${RPM_VERSION}.x86_64.rpm ../dist/vpncloud_${RPM_VERSION}.x86_64.rpm
fi

View File

@ -573,6 +573,14 @@ pub enum Command {
/// Name of the network
#[structopt(short, long)]
name: Option<String>
},
/// Install required utility files
#[cfg(feature = "installer")]
Install {
/// Remove installed files again
#[structopt(long)]
uninstall: bool
}
}

49
src/installer.rs Normal file
View File

@ -0,0 +1,49 @@
use crate::error::Error;
use std::{
env,
fs::{self, File},
io::Write,
os::unix::fs::PermissionsExt
};
const MANPAGE: &[u8] = include_bytes!("../target/vpncloud.1.gz");
const SERVICE_FILE: &[u8] = include_bytes!("../assets/vpncloud@.service");
const WS_PROXY_SERVICE_FILE: &[u8] = include_bytes!("../assets/vpncloud-wsproxy.service");
const EXAMPLE_CONFIG: &[u8] = include_bytes!("../assets/example.net.disabled");
pub fn install() -> Result<(), Error> {
env::current_exe()
.and_then(|p| fs::copy(p, "/usr/bin/vpncloud"))
.map_err(|e| Error::FileIo("Failed to copy binary", e))?;
fs::set_permissions("/usr/bin/vpncloud", fs::Permissions::from_mode(755))
.map_err(|e| Error::FileIo("Failed to set permissions for binary", e))?;
fs::create_dir_all("/etc/vpncloud").map_err(|e| Error::FileIo("Failed to create config folder", e))?;
fs::set_permissions("/etc/vpncloud", fs::Permissions::from_mode(600))
.map_err(|e| Error::FileIo("Failed to set permissions for config folder", e))?;
File::create("/etc/vpncloud/example.net.disabled")
.and_then(|mut f| f.write_all(EXAMPLE_CONFIG))
.map_err(|e| Error::FileIo("Failed to create example config", e))?;
File::create("/usr/share/man/man1/vpncloud.1.gz")
.and_then(|mut f| f.write_all(MANPAGE))
.map_err(|e| Error::FileIo("Failed to create manpage", e))?;
File::create("/lib/systemd/system/vpncloud@.service")
.and_then(|mut f| f.write_all(SERVICE_FILE))
.map_err(|e| Error::FileIo("Failed to create service file", e))?;
File::create("/lib/systemd/system/vpncloud-wsproxy.service")
.and_then(|mut f| f.write_all(WS_PROXY_SERVICE_FILE))
.map_err(|e| Error::FileIo("Failed to create wsporxy service file", e))?;
info!("Install successful");
Ok(())
}
pub fn uninstall() -> Result<(), Error> {
fs::remove_file("/etc/vpncloud/example.net.disabled").map_err(|e| Error::FileIo("Failed to remove binary", e))?;
fs::remove_file("/usr/share/man/man1/vpncloud.1.gz").map_err(|e| Error::FileIo("Failed to remove manpage", e))?;
fs::remove_file("/lib/systemd/system/vpncloud@.service")
.map_err(|e| Error::FileIo("Failed to remove service file", e))?;
fs::remove_file("/lib/systemd/system/vpncloud-wsproxy.service")
.map_err(|e| Error::FileIo("Failed to remove wsproxy service file", e))?;
fs::remove_file("/usr/bin/vpncloud").map_err(|e| Error::FileIo("Failed to remove binary", e))?;
info!("Uninstall successful");
Ok(())
}

View File

@ -29,6 +29,7 @@ pub mod traffic;
pub mod types;
#[cfg(feature = "wizard")] pub mod wizard;
#[cfg(feature = "websocket")] pub mod wsproxy;
#[cfg(feature = "installer")] pub mod installer;
use structopt::StructOpt;
@ -282,6 +283,14 @@ fn main() {
Command::Config { name } => {
try_fail!(wizard::configure(name), "Wizard failed: {}");
}
#[cfg(feature = "installer")]
Command::Install { uninstall } => {
if uninstall {
try_fail!(installer::uninstall(), "Uninstall failed: {}");
} else {
try_fail!(installer::install(), "Install failed: {}");
}
}
}
return
}