guix: add logdir

This commit is contained in:
tobtoht 2024-03-13 11:44:29 +01:00
parent b94135ba4e
commit 8312c7dbc1
No known key found for this signature in database
GPG key ID: E45B10DD027D2472
8 changed files with 97 additions and 219 deletions

View file

@ -2,22 +2,16 @@ name: ci/gh-actions/guix
on: [push, pull_request]
env:
APT_SET_CONF: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
jobs:
cache-sources:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: depends sources cache
id: cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: contrib/depends/sources
key: sources-${{ hashFiles('contrib/depends/packages/*') }}
@ -25,55 +19,6 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: make -C contrib/depends download
cache-guix:
runs-on: ubuntu-latest
needs: [cache-sources]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: guix cache
id: cache
uses: actions/cache@v3
with:
path: |
gnu/store
guix_db.sqlite
key: guix-${{ hashFiles('contrib/guix/manifest.scm') }}
- name: move guix store
if: steps.cache.outputs.cache-hit != 'true'
run: |
if [[ -e "guix_db.sqlite" ]]; then
sudo mkdir -p /var/guix/db
sudo mv gnu /gnu
sudo cp guix_db.sqlite /var/guix/db/db.sqlite
sudo chmod 1775 /gnu/store
sudo chown 0644 /var/guix/db/db.sqlite
sudo chown -R root:root /gnu/store /var/guix/db/db.sqlite
fi
- name: depends sources cache
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/cache/restore@v3
with:
path: contrib/depends/sources
key: sources-${{ hashFiles('contrib/depends/packages/*') }}
- name: set apt conf
if: steps.cache.outputs.cache-hit != 'true'
run: ${{env.APT_SET_CONF}}
- name: install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: sudo apt update; sudo apt -y install guix git ca-certificates
- name: dry run
if: steps.cache.outputs.cache-hit != 'true'
run: DRY_RUN=1 SUBSTITUTE_URLS='http://ci.guix.gnu.org' JOBS=2 ./contrib/guix/guix-build
- name: prepare guix store for caching
if: steps.cache.outputs.cache-hit != 'true'
run: |
sudo systemctl stop guix-daemon
sudo mv /gnu gnu
sudo mv /var/guix/db/db.sqlite guix_db.sqlite
build-guix:
runs-on: ubuntu-latest
needs: [cache-guix]
@ -81,70 +26,50 @@ jobs:
fail-fast: false
matrix:
toolchain:
- name: "x86_64-linux-gnu"
host: "x86_64-linux-gnu"
- name: "x86_64-linux-gnu.no-tor-bundle"
host: "x86_64-linux-gnu.no-tor-bundle"
- name: "x86_64-linux-gnu.pack"
host: "x86_64-linux-gnu.pack"
- name: "aarch64-linux-gnu"
host: "aarch64-linux-gnu"
- name: "arm-linux-gnueabihf"
host: "arm-linux-gnueabihf"
- name: "riscv64-linux-gnu"
host: "riscv64-linux-gnu"
- name: "i686-linux-gnu"
host: "i686-linux-gnu"
- name: "x86_64-w64-mingw32"
host: "x86_64-w64-mingw32"
- name: "x86_64-w64-mingw32.installer"
host: "x86_64-w64-mingw32.installer"
- name: "x86_64-apple-darwin"
host: "x86_64-apple-darwin"
- name: "arm64-apple-darwin"
host: "arm64-apple-darwin"
name: ${{ matrix.toolchain.name }}
- target: "x86_64-linux-gnu"
- target: "x86_64-linux-gnu.no-tor-bundle"
- target: "x86_64-linux-gnu.pack"
- target: "aarch64-linux-gnu"
- target: "arm-linux-gnueabihf"
- target: "riscv64-linux-gnu"
- target: "i686-linux-gnu"
- target: "x86_64-w64-mingw32"
- target: "x86_64-w64-mingw32.installer"
- target: "x86_64-apple-darwin"
- target: "arm64-apple-darwin"
name: ${{ matrix.toolchain.target }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: guix cache
uses: actions/cache/restore@v3
with:
path: |
gnu/store
guix_db.sqlite
key: guix-${{ hashFiles('contrib/guix/manifest.scm') }}
- name: move guix store
run: |
if [[ -e "guix_db.sqlite" ]]; then
sudo mkdir -p /var/guix/db
sudo mv gnu /gnu
sudo cp guix_db.sqlite /var/guix/db/db.sqlite
sudo chmod 1775 /gnu/store
sudo chown 0644 /var/guix/db/db.sqlite
sudo chown -R root:root /gnu/store /var/guix/db/db.sqlite
fi
- name: depends cache
uses: actions/cache@v3
with:
path: contrib/depends/built
key: depends-${{ matrix.toolchain.host }}-${{ hashFiles('contrib/depends/packages/*') }}
- name: remove bundled packages
run: sudo rm -rf /usr/local
- name: depends sources cache
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: contrib/depends/sources
key: sources-${{ hashFiles('contrib/depends/packages/*') }}
- name: set apt conf
run: ${{env.APT_SET_CONF}}
- name: install dependencies
run: sudo apt update; sudo apt -y install guix git ca-certificates
- name: build
run: SUBSTITUTE_URLS='http://ci.guix.gnu.org' HOSTS="${{ matrix.toolchain.host }}" JOBS=2 ./contrib/guix/guix-build
- uses: actions/upload-artifact@v3
run: SUBSTITUTE_URLS='http://ci.guix.gnu.org' HOSTS="${{ matrix.toolchain.target }}" ./contrib/guix/guix-build
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.toolchain.name }}
name: ${{ matrix.toolchain.target }}
path: |
guix/guix-build-*/output/${{ matrix.toolchain.host }}/*
guix/guix-build-*/output/${{ matrix.toolchain.target }}/*
guix/guix-build-*/logs/${{ matrix.toolchain.target }}/*
bundle-logs:
runs-on: ubuntu-latest
needs: [build-guix]
steps:
- uses: actions/download-artifact@v4
with:
merge-multiple: true
- uses: actions/upload-artifact@v4
with:
name: "logs"
path: '**/logs/**'

View file

@ -2,7 +2,7 @@
# Pattern rule to print variables, e.g. make print-top_srcdir
print-%: FORCE
@echo '$*'='$($*)'
@echo '$($*)'
# When invoking a sub-make, keep only the command line variable definitions
# matching the pattern in the filter function.
@ -127,34 +127,8 @@ include builders/$(build_os).mk
include builders/default.mk
include packages/packages.mk
# Previously, we directly invoked the well-known programs using $(shell ...)
# to construct build_id_string. However, that was problematic because:
#
# 1. When invoking a shell, GNU Make special-cases exit code 127 (command not
# found) by not capturing the output but instead passing it through. This is
# not done for any other exit code.
#
# 2. Characters like '#' (from these programs' output) would end up in make
# variables like build_id_string, which would be wrongly interpreted by make
# when these variables were used.
#
# Therefore, we should avoid having arbitrary strings in make variables where
# possible. The gen_id script used here hashes the output to construct a
# "make-safe" id.
#
# Also note that these lines need to be:
#
# 1. After including {hosts,builders}/*.mk, since they rely on the tool
# variables (e.g. build_CC, host_STRIP, etc.) to be set.
#
# 2. Before including packages/*.mk (excluding packages/packages.mk), since
# they rely on the build_id variables
#
build_id:=$(shell env SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
$(host_arch)_$(host_os)_id:=$(shell env SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
ifneq ($(OUTDIR),)
$(file >> $(OUTDIR)/build-hashes.txt,$(host_arch)_$(host_os)_id=$($(host_arch)_$(host_os)_id))
endif
build_id_string:=$(realpath $(GUIX_ENVIRONMENT))
$(host_arch)_$(host_os)_id_string:=$(realpath $(GUIX_ENVIRONMENT))
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_)
tor_packages_$(NO_TOR) = $(tor_packages) $(tor_$(host_os)_packages)
@ -181,7 +155,7 @@ build-only-$(1)_$(3): CMAKE_SHARED_BOOL = $(if $(findstring shared,$(3)),ON,OFF)
toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin)
final_build_id_long+=$(shell $(build_SHA256SUM) toolchain.cmake.in)
final_build_id_long+=:[sha256sum]:$(shell $(build_SHA256SUM) toolchain.cmake.in)
final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
$(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages)
rm -rf $(@D)

View file

@ -43,7 +43,7 @@ endef
define int_get_build_recipe_hash
$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
$(if $(OUTDIR), $(file >> $(OUTDIR)/build-hashes.txt,$(1)_all_file_checksums=$($(1)_all_file_checksums)))
final_build_id_long+=:[$(1)_all_file_checksums]$(foreach checksum,$($(1)_all_file_checksums),$(shell echo ":$(checksum)")):
$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
endef
@ -51,10 +51,9 @@ define int_get_build_id
$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies)))
$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id))
$(if $(OUTDIR), $(file >> $(OUTDIR)/build-hashes.txt,$(1)_build_id_long=$($(1)_build_id_long)))
$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string))
$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
final_build_id_long+=$($(package)_build_id_long)
final_build_id_long+=:[recipe]:$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type):[deps]$(foreach dep,$($(1)_build_id_deps),$(shell echo ":$(dep)")):[$($(1)_type)_id]:$($($(1)_type)_id_string):
#compute package-specific paths
$(1)_build_subdir?=.

View file

@ -1,54 +0,0 @@
#!/usr/bin/env bash
# Usage: env [ CC=... ] [ C_STANDARD=...] [ CXX=... ] [CXX_STANDARD=...] \
# [ AR=... ] [ RANLIB=... ] [ STRIP=... ] [ DEBUG=... ] \
# [ LTO=... ] ./build-id [ID_SALT]...
#
# Prints to stdout a SHA256 hash representing the current toolset, used by
# depends/Makefile as a build id for caching purposes (detecting when the
# toolset has changed and the cache needs to be invalidated).
#
# If the DEBUG environment variable is non-empty and the system has `tee`
# available in its $PATH, the pre-image to the SHA256 hash will be printed to
# stderr. This is to help developers debug caching issues in depends.
# This script explicitly does not `set -e` because id determination is mostly
# opportunistic: it is fine that things fail, as long as they fail consistently.
# Command variables (CC/CXX/AR) which can be blank are invoked with `bash -c`,
# because the "command not found" error message printed by shells often include
# the line number, like so:
#
# ./depends/gen_id: line 43: --version: command not found
#
# By invoking with `bash -c`, we ensure that the line number is always 1
(
# Redirect stderr to stdout
exec 2>&1
echo "BEGIN ALL"
# Include any ID salts supplied via command line
echo "BEGIN ID SALT"
echo "$@"
echo "END ID SALT"
echo "BEGIN /gnu/store"
bash -c "ls -1 /gnu/store | sort"
echo "END /gnu/store"
# LINES=\|COLUMNS=\|\|HOSTTYPE=\|OSTYPE=\|MACHTYPE=\|HOSTNAME=
echo "BEGIN environment"
bash -c "printenv | sort | grep -v '^\(BASE_CACHE=\|DISTNAME=\|DISTSRC=\|OUTDIR=\|SOURCES_PATH=\|JOBS=\|OPTIONS=\)'"
echo "END environment"
echo "END ALL"
) | if [ -n "$DEBUG_GENID" ] && command -v tee > /dev/null 2>&1; then
# When debugging and `tee` is available, output the preimage to stderr
# in addition to passing through stdin to stdout
tee >(cat 1>&2)
else
# Otherwise, passthrough stdin to stdout
cat
fi | ${SHA256SUM} - | cut -d' ' -f1

View file

@ -107,10 +107,10 @@ fi
# We should be able to find at least one output
################
echo "Looking for build output SHA256SUMS fragments in ${OUTDIR_BASE}"
echo "Looking for build output SHA256SUMS fragments in ${LOGDIR_BASE}"
shopt -s nullglob
sha256sum_fragments=( "$OUTDIR_BASE"/*/SHA256SUMS.part ) # This expands to an array of directories...
sha256sum_fragments=( "$LOGDIR_BASE"/*/SHA256SUMS.part ) # This expands to an array of directories...
shopt -u nullglob
noncodesigned_fragments=()
@ -118,20 +118,20 @@ codesigned_fragments=()
if (( ${#sha256sum_fragments[@]} )); then
echo "Found build output SHA256SUMS fragments:"
for outdir in "${sha256sum_fragments[@]}"; do
echo " '$outdir'"
case "$outdir" in
"$OUTDIR_BASE"/*-codesigned/SHA256SUMS.part)
codesigned_fragments+=("$outdir")
for logdir in "${sha256sum_fragments[@]}"; do
echo " '$logdir'"
case "$logdir" in
"$LOGDIR_BASE"/*-codesigned/SHA256SUMS.part)
codesigned_fragments+=("$logdir")
;;
*)
noncodesigned_fragments+=("$outdir")
noncodesigned_fragments+=("$logdir")
;;
esac
done
echo
else
echo "ERR: Could not find any build output SHA256SUMS fragments in ${OUTDIR_BASE}"
echo "ERR: Could not find any build output SHA256SUMS fragments in ${LOGDIR_BASE}"
exit 1
fi
@ -139,7 +139,7 @@ fi
## Attest ##
##############
# Usage: out_name $outdir
# Usage: out_name $logdir
#
# HOST: The output directory being attested
#

View file

@ -91,7 +91,7 @@ export HOSTS="${HOSTS:-i686-linux-gnu x86_64-linux-gnu aarch64-linux-gnu arm-lin
# HOST: The current platform triple we're building for
#
distsrc_for_host() {
echo "${DISTSRC_BASE}/distsrc-${VERSION}-${1}"
echo "${DISTSRC_BASE}/build/distsrc-${VERSION}-${1}"
}
# Accumulate a list of build directories that already exist...
@ -204,7 +204,7 @@ COMMIT_TIMESTAMP="$(git -c log.showSignature=false log --format=%at -1)"
# Precious directories are those which should not be cleaned between successive
# guix builds
depends_precious_dir_names='SOURCES_PATH BASE_CACHE'
precious_dir_names="${depends_precious_dir_names} OUTDIR_BASE PROFILES_BASE"
precious_dir_names="${depends_precious_dir_names} OUTDIR_BASE LOGDIR_BASE PROFILES_BASE"
# Usage: contains IFS-SEPARATED-LIST ITEM
contains() {
@ -241,9 +241,10 @@ mkdir -p "$VAR_BASE"
# shellcheck disable=SC2046,SC2086
{
# Get depends precious dir definitions from depends
make -C "${PWD}/contrib/depends" \
--no-print-directory \
-- $(printf "print-%s\n" $depends_precious_dir_names)
for precious_dir_name in $depends_precious_dir_names; do
precious_dir_path="$(make -C "${PWD}/contrib/depends" --no-print-directory print-${precious_dir_name})"
echo "${precious_dir_name}=${precious_dir_path}"
done
# Get remaining precious dir definitions from the environment
for precious_dir_name in $precious_dir_names; do
@ -254,9 +255,11 @@ mkdir -p "$VAR_BASE"
done
} > "${VAR_BASE}/precious_dirs"
# Make sure an output directory exists for our builds
# Make sure an output and logs directory exists for our builds
OUTDIR_BASE="${OUTDIR_BASE:-${VERSION_BASE}/output}"
mkdir -p "$OUTDIR_BASE"
LOGDIR_BASE="${LOGDIR_BASE:-${VERSION_BASE}/logs}"
mkdir -p "$LOGDIR_BASE"
# Download the depends sources now as we won't have internet access in the build
# container
@ -273,6 +276,15 @@ outdir_for_host() {
echo "${OUTDIR_BASE}/${1}${2:+-${2}}"
}
# Usage: logdir_for_host HOST SUFFIX
#
# HOST: The current platform triple we're building for
#
logdir_for_host() {
echo "${LOGDIR_BASE}/${1}${2:+-${2}}"
}
# Usage: profiledir_for_host HOST SUFFIX
#
# HOST: The current platform triple we're building for
@ -281,7 +293,6 @@ profiledir_for_host() {
echo "${PROFILES_BASE}/${1}${2:+-${2}}"
}
#########
# BUILD #
#########
@ -340,7 +351,7 @@ EOF
--pure \
--no-cwd \
${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \
-- env HOST="$HOST"
-- echo "$HOST"
if [[ -v DRY_RUN ]]; then
echo "Dry run, exiting.."
@ -420,6 +431,7 @@ EOF
--share="$PWD"=/feather \
--share="$DISTSRC_BASE"=/distsrc-base \
--share="$OUTDIR_BASE"=/outdir-base \
--share="$LOGDIR_BASE"=/logdir-base \
--expose="$(git rev-parse --git-common-dir)" \
${SOURCES_PATH:+--share="$SOURCES_PATH"} \
${BASE_CACHE:+--share="$BASE_CACHE"} \
@ -440,6 +452,7 @@ EOF
${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \
DISTSRC="$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$host")" \
OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$host")" \
LOGDIR="$(LOGDIR_BASE=/logdir-base && logdir_for_host "$host")" \
DIST_ARCHIVE_BASE=/outdir-base/dist-archive \
OPTIONS="${host_split[1]}" \
bash -c "cd /feather && bash contrib/guix/libexec/build.sh"

View file

@ -40,6 +40,7 @@ Required environment variables as seen inside the container:
JOBS: ${JOBS:?not set}
DISTSRC: ${DISTSRC:?not set}
OUTDIR: ${OUTDIR:?not set}
LOGDIR: ${LOGDIR:?not set}
OPTIONS: ${OPTIONS}
EOF
@ -53,6 +54,11 @@ export SOURCE_DATE_EPOCH=1397818193
# Environment Setup #
#####################
# Collect some information about the build environment to help debug potential reproducibility issues
mkdir -p "${LOGDIR}"
ls -1 /gnu/store | sort > ${LOGDIR}/guix-hashes.txt
printenv | sort | grep -v '^\(BASE_CACHE=\|DISTNAME=\|DISTSRC=\|OUTDIR=\|LOGDIR=\|SOURCES_PATH=\|JOBS=\|OPTIONS=\|DEPENDS_ONLY=\)' > ${LOGDIR}/guix-env.txt
# The depends folder also serves as a base-prefix for depends packages for
# $HOSTs after successfully building.
BASEPREFIX="${PWD}/contrib/depends"
@ -213,6 +219,9 @@ esac
mkdir -p "$OUTDIR"
# Log the depends build ids
make -C contrib/depends --no-print-directory HOST="$HOST" print-final_build_id_long | tr ':' '\n' > ${LOGDIR}/depends-hashes.txt
# Build the depends tree, overriding variables that assume multilib gcc
make -C contrib/depends --jobs="$JOBS" HOST="$HOST" \
${V:+V=1} \
@ -220,6 +229,7 @@ make -C contrib/depends --jobs="$JOBS" HOST="$HOST" \
${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \
${SDK_PATH+SDK_PATH="$SDK_PATH"} \
OUTDIR="$OUTDIR" \
LOGDIR="$LOGDIR" \
x86_64_linux_CC=x86_64-linux-gnu-gcc \
x86_64_linux_CXX=x86_64-linux-gnu-g++ \
x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \
@ -228,6 +238,15 @@ make -C contrib/depends --jobs="$JOBS" HOST="$HOST" \
x86_64_linux_STRIP=x86_64-linux-gnu-strip \
guix_ldflags="$HOST_LDFLAGS"
# Log the depends package hashes
DEPENDS_PACKAGES="$(make -C contrib/depends --no-print-directory HOST="$HOST" print-all_packages)"
DEPENDS_CACHE="$(make -C contrib/depends --no-print-directory ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} print-BASE_CACHE)"
{
for package in ${DEPENDS_PACKAGES}; do
cat "${DEPENDS_CACHE}/${HOST}/${package}"/*.hash
done
} | sort -k2 > "${LOGDIR}/depends-packages.txt"
###########################
# Source Tarball Building #
@ -256,7 +275,7 @@ fi
###########################
# CFLAGS
HOST_CFLAGS="-O2 -g"
HOST_CFLAGS="-O2"
HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;)
case "$HOST" in
*linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;;
@ -487,5 +506,5 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
} | xargs realpath --relative-base="$PWD" \
| xargs sha256sum \
| sort -k2 \
| sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part
| sponge "$LOGDIR"/SHA256SUMS.part
)

View file

@ -76,6 +76,8 @@ DISTSRC_BASE="${DISTSRC_BASE:-${VERSION_BASE}}"
OUTDIR_BASE="${OUTDIR_BASE:-${VERSION_BASE}/output}"
LOGDIR_BASE="${LOGDIR_BASE:-${VERSION_BASE}/logs}"
var_base_basename="var"
VAR_BASE="${VAR_BASE:-${VERSION_BASE}/${var_base_basename}}"