#!/bin/bash # -*- coding: utf-8; mode: sh; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=sh:et:sw=4:ts=4:sts=4 # Note: # This script is sourced by the mpbb wrapper script. # Do not execute this directly! install-port-usage() { # "prog" is defined in mpbb-help. # shellcheck disable=SC2154 cat <] install-port [--source] Build and install the given port. Options: --source Build the port from source, ignoring binary archives. Run \`$prog help' for global options and a list of other subcommands. EOF } install-port() { local args parseopt source,mirrordb-url:,mirrordb-credentials-file: "$@" || return # $option_source is set by parseopt # shellcheck disable=SC2154 : "${option_source=0}" set -- ${args+"${args[@]}"} local source_flag [[ "${option_source}" -eq 1 ]] && source_flag=s local port=${1-} if [[ -z "$port" ]]; then err "Must specify a port" return 1 fi # $option_log_dir is set in mpbb # shellcheck disable=SC2154 local log_port_contents="${option_log_dir}/port-contents.txt" local log_port_stats="${option_log_dir}/port-statistics.txt" local log_port_main="${option_log_dir}/main.log" local log_subports_progress="${option_log_dir}/ports-progress.txt" # prepare the log files and make sure to start with empty ones mkdir -p "${option_log_dir}" #> "$log_port_contents" > "$log_port_stats" rm -f "${option_work_dir}/requested_port" # $option_prefix and $thisdir are set in mpbb # shellcheck disable=SC2154 local imagepath=$("${option_prefix}/bin/port-tclsh" "${thisdir}/tools/archive-path.tcl" "$@") if [[ -f "$imagepath" || -d "${imagepath%.*}" ]]; then echo "$* already installed, nothing to do" # log: summary for the portwatcher echo "Building '$port' ... [OK]" >> "$log_subports_progress" echo "$@" >> "${option_work_dir}/requested_port" return 0 elif [[ -n "$("${option_prefix}/bin/port" -q installed "$@")" ]]; then # archive name differs, supported_archs probably changed "${option_prefix}/bin/port" -fv uninstall "$@" fi local time_start local time_stop time_start=$(date +%s) FETCHFAILED=0 # $option_prefix is set in mpbb # shellcheck disable=SC2154 if ! "${option_prefix}/bin/port" -d fetch "$@"; then echo "Fetch of '$port' failed." if [ -n "$option_mirrordb_url" ]; then echo "Waiting for '$port' to be mirrored." if "${option_prefix}/bin/port-tclsh" "${thisdir}/tools/wait-for-mirror.tcl" \ "$option_mirrordb_url" "$option_mirrordb_credentials_file" "$port"; then echo "Mirroring of '$port' done. Retrying fetch." if ! "${option_prefix}/bin/port" -d fetch "$@"; then echo "Second fetch of '$port' failed." FETCHFAILED=1 fi else echo "Timed out waiting for '$port' to be mirrored." FETCHFAILED=1 fi else FETCHFAILED=1 fi if [ "$FETCHFAILED" -eq 1 ]; then # log: summary for the portwatcher echo "Fetching '$port' ... [ERROR] maintainers: $(get-maintainers "$port")." >> "$log_subports_progress" # Do not add to failcache. This could be a temporary problem that will # be resolved once the file appears on mirrors. return 1 fi fi # $option_prefix is set in mpbb # shellcheck disable=SC2154 if ! "${option_prefix}/bin/port" -d checksum "$@"; then echo "Checksum of '$port' failed." # log: summary for the portwatcher echo "Checksum '$port' ... [ERROR] maintainers: $(get-maintainers "$port")." >> "$log_subports_progress" # Do not add to failcache. This could be a temporary network or server problem. # Delete the files so they will be re-fetched next time (hopefully correctly). "${option_prefix}/bin/port" -d clean --dist "$@" return 1 fi # $option_prefix is set in mpbb # shellcheck disable=SC2154 if "${option_prefix}/bin/port" "-dkn${source_flag}" install --unrequested "$@"; then # Remove failcache if it exists failcache_success "$@" if [ $? -ne 0 ]; then err "failcache_success" "$@" "failed." return 1 fi else echo "Build of '$port' failed." # log: summary for the portwatcher echo "Building '$port' ... [ERROR] maintainers: $(get-maintainers "$port")." >> "$log_subports_progress" # update failcache failcache_failure "$@" if [ $? -ne 0 ]; then err "failcache_failure" "$@" "failed." return 1 fi return 1 fi time_stop=$(date +%s) # log: summary for the portwatcher echo "Building '$port' ... [OK]" >> "$log_subports_progress" # log: contents "${option_prefix}/bin/port" -q contents "$port" > "$log_port_contents" # log: statistics echo "time: $((time_stop - time_start))s" >> "$log_port_stats" local port_workdir local port_workdir_size="" local port_destdir_size="" local print_arg_workdir="ERROR" local print_arg_destdir="ERROR" # First, compute port_workdir_size and port_destdir_size port_workdir=$("${option_prefix}/bin/port" work "$port") if [ -n "$port_workdir" ]; then port_workdir_size=$(du -ks "$port_workdir" | sed 's/^ *//' | tr '\t' '\n' | head -n 1) if [ $? -eq 0 ] && [ -n "$port_workdir_size" ]; then print_arg_workdir="${port_workdir_size}k" fi local port_destdir="$port_workdir/destroot" # if we arrive here, 'port work $port' was successful, so we're # at least going to print 'destdir: -' print_arg_destdir="-" if [ -d "$port_destdir" ]; then port_destdir_size=$(du -ks "$port_destdir" | sed 's/^ *//' | tr '\t' '\n' | head -n 1) if [ $? -eq 0 ] && [ -n "$port_destdir_size" ]; then print_arg_destdir="${port_destdir_size}k" fi fi fi # Then print them, or on error (or if destdir doesn't exist), print the # appropriate message echo "workdir: $print_arg_workdir" >> "$log_port_stats" echo "destdir: $print_arg_destdir" >> "$log_port_stats" # log: main.log local port_mainlog port_mainlog=$("${option_prefix}/bin/port" logfile "$port") if [ $? -eq 0 ] && [ -f "$port_mainlog" ]; then cp -f "$port_mainlog" "$log_port_main" fi echo "$@" >> "${option_work_dir}/requested_port" }