mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-07 22:05:25 +00:00
Some external packages have multiple variants that apply to different builds of asterisk. The DPMA for instance has a "bundled" variant that needs to be downloaded if asterisk was configured with --with-pjproject-bundled. There are 2 ways to specify variants: If you need the user to make the decision about which variant to download, simply create multiple menuselect "member" entries like so... <member name="res_digium_phone" displayname="..snipped.."> <support_level>external</support_level> <depend>xmlstarlet</depend> <depend>bash</depend> <defaultenabled>no</defaultenabled> </member> <member name="res_digium_phone-bundled" displayname="..snipped.."> <support_level>external</support_level> <depend>xmlstarlet</depend> <depend>bash</depend> <defaultenabled>no</defaultenabled> </member> Note that the second entry has "-<variant>" appended to the name. You can then use the existing menuselect facilities to restrict which members to enable or disable. Youy probably don't want the user to enable multiple at the same time. If you want to hide the details of the variants, the better way to do it is to create 1 member with "variant" elements. <member name="res_digium_phone" displayname="..snipped.."> <support_level>external</support_level> <depend>xmlstarlet</depend> <depend>bash</depend> <defaultenabled>no</defaultenabled> <member_data> <downloader> <variants> <variant tag="bundled" condition='[[ "$PJPROJECT_BUNDLED" = "yes" ]]'/> </variants> </downloader> </member_data> </member> The condition must be a bash expression suitable for use with an "if" statement. Any environment variable can be used plus those available in makeopts. In this case, if asterisk was configured with --with-pjproject-bundled the bundled variant will be automatically downloaded. Otherwise the normal version will be downloaded. Change-Id: I4de23e06d4492b0a65e105c8369966547d0faa3e
225 lines
7.7 KiB
Bash
Executable File
225 lines
7.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
if [[ ( ${BASH_VERSINFO[0]} == 4 && ${BASH_VERSINFO[1]} > 1 ) || ${BASH_VERSINFO[0]} > 4 ]] ; then
|
|
shopt -s compat41
|
|
fi
|
|
set -e
|
|
|
|
ASTTOPDIR=${ASTTOPDIR:-.}
|
|
|
|
module_name=${1%%-*}
|
|
variant=${1##*-}
|
|
|
|
if [[ "${variant}" = "${module_name}" ]] ; then
|
|
unset variant
|
|
fi
|
|
|
|
if [[ -z ${module_name} ]] ; then
|
|
echo "You must supply a module name."
|
|
exit 64
|
|
fi
|
|
|
|
tmpdir=$(mktemp -d)
|
|
if [[ -z "${tmpdir}" ]] ; then
|
|
echo "${module_name}: Unable to create temporary directory."
|
|
exit 1
|
|
fi
|
|
trap "rm -rf ${tmpdir}" EXIT
|
|
|
|
sed -r -e "s/^([^ =]+)\s*=\s*(.*)$/\1=\"\2\"/g" ${ASTTOPDIR}/makeopts >${tmpdir}/makeopts
|
|
source ${tmpdir}/makeopts
|
|
if [[ -z "${ASTMODDIR}" ]] ; then
|
|
echo "${module_name}: Unable to parse ${ASTTOPDIR}/makeopts."
|
|
exit 1
|
|
fi
|
|
|
|
XMLSTARLET=${XMLSTARLET:-xmlstarlet}
|
|
if [[ "${XMLSTARLET}" = ":" ]] ; then
|
|
echo "${module_name}: The externals downloader requires xmlstarlet to be installed."
|
|
exit 1
|
|
fi
|
|
|
|
cache_dir="${EXTERNALS_CACHE_DIR}"
|
|
if [[ -z ${cache_dir} ]] ; then
|
|
cache_dir=${tmpdir}
|
|
fi
|
|
|
|
version=$(${ASTTOPDIR}/build_tools/make_version ${ASTTOPDIR})
|
|
if [[ ! ${version} =~ ^(GIT-)?([^.-]+)[.-].* ]] ; then
|
|
echo "${module_name}: Couldn't parse version ${version}"
|
|
exit 1
|
|
fi
|
|
major_version=${BASH_REMATCH[2]}
|
|
|
|
if [[ "${major_version}" == "master" ]] ; then
|
|
echo "${module_name}: External module downloading is not available in the 'master' git branch. Please disable in menuselect and download manually."
|
|
exit 1
|
|
fi
|
|
|
|
major_version=${major_version}.0
|
|
|
|
if [[ "${HOST_CPU}" = "x86_64" ]] ; then
|
|
host_bits=64
|
|
else
|
|
host_bits=32
|
|
fi
|
|
|
|
if [[ -z "${variant}" ]] ; then
|
|
variants=$(${XMLSTARLET} sel -t -m "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant" -v "@tag" -n ${ASTTOPDIR}/menuselect-tree || :)
|
|
member_name=${module_name}
|
|
for tag in ${variants} ; do
|
|
condition=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${module_name}']/member_data/downloader/variants/variant[@tag = '${tag}']/@condition" ${ASTTOPDIR}/menuselect-tree || :)
|
|
variant=$(eval "if $condition ; then echo $tag ; fi")
|
|
if [[ -n "${variant}" ]] ; then
|
|
break
|
|
fi
|
|
done
|
|
else
|
|
member_name=${module_name}${variant:+-${variant}}
|
|
fi
|
|
|
|
full_name=${module_name}${variant:+-${variant}}
|
|
variant_manifest=manifest${variant:+-${variant}}.xml
|
|
|
|
# Override the remote base for all packages
|
|
# useful for testing
|
|
remote_url=${REMOTE_BASE:+${REMOTE_BASE}/asterisk-${major_version}/x86-${host_bits}}
|
|
|
|
if [[ -z "${remote_url}" ]] ; then
|
|
remote_url=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@remote_url" ${ASTTOPDIR}/menuselect-tree || :)
|
|
if [[ -n "${remote_url}" ]] ; then
|
|
remote_url="${remote_url}/asterisk-${major_version}/x86-${host_bits}"
|
|
else
|
|
directory_name=$(${XMLSTARLET} sel -t -v "/menu/category/member[@name = '${member_name}']/member_data/downloader/@directory_name" ${ASTTOPDIR}/menuselect-tree || :)
|
|
remote_url="http://downloads.digium.com/pub/telephony/${directory_name:-${module_name}}/asterisk-${major_version}/x86-${host_bits}"
|
|
fi
|
|
fi
|
|
|
|
version_convert() {
|
|
local v=${1##*_}
|
|
if [[ ${v} =~ ([0-9]+)[.]([0-9]+)[.]([0-9]+) ]] ; then
|
|
v=$(( ${BASH_REMATCH[1]}<<18 | ${BASH_REMATCH[2]}<<9 | ${BASH_REMATCH[3]} ))
|
|
fi
|
|
echo ${v}
|
|
}
|
|
|
|
${WGET} -q -O ${tmpdir}/${variant_manifest} ${remote_url}/${variant_manifest} || {
|
|
echo "${full_name}: Unable to fetch ${remote_url}/${variant_manifest}"
|
|
exit 1
|
|
}
|
|
|
|
rpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${tmpdir}/${variant_manifest})
|
|
rpvi=$(version_convert ${rpv})
|
|
echo "${full_name}: Remote package version ${rpv} (${rpvi})"
|
|
|
|
module_dir=${full_name}-${rpv}-x86_${host_bits}
|
|
tarball=${module_dir}.tar.gz
|
|
|
|
export need_install=0
|
|
|
|
if [[ -f ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml ]] ; then
|
|
package_arch=$(${XMLSTARLET} sel -t -v "/package/@arch" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
|
|
ipv=$(${XMLSTARLET} sel -t -v "/package/@version" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
|
|
package_variant=$(${XMLSTARLET} sel -t -v "/package/@variant" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml || :)
|
|
ipvi=$(version_convert ${ipv})
|
|
ip_major=${ipv%_*}
|
|
echo "${full_name}: Installed package version ${ipv} (${ipvi})"
|
|
if [[ "${ip_major}" != "${major_version}" || "${package_arch}" != "x86_${host_bits}" || "${package_variant}" != "${variant}" ]] ; then
|
|
echo "${full_name}: The installed package is not for this version of Asterisk. Reinstalling."
|
|
need_install=1
|
|
elif [[ ${rpvi} > ${ipvi} ]] ; then
|
|
echo "${full_name}: A newer package is available"
|
|
need_install=1
|
|
else
|
|
sums=$(${XMLSTARLET} sel -t -m "//file" -v "@md5sum" -n ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml)
|
|
for sum in ${sums} ; do
|
|
install_path=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@install_path" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml )
|
|
executable=$(${XMLSTARLET} sel -t -v "//file[@md5sum = '${sum}']/@executable" ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml )
|
|
f=${DESTDIR}$(eval echo ${install_path})
|
|
if [[ ! -f ${f} ]] ; then
|
|
echo Not found: ${f}
|
|
need_install=1
|
|
break
|
|
else
|
|
if [[ "$executable" = "yes" ]] ; then
|
|
# There are easier ways of doing this (objcopy --dump-section) but not in older bunutils
|
|
length_offset=$(objdump -h $f | sed -n -r -e "s/^\s+[0-9]+\s+.ast_manifest\s+([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s+.*$/0x\1 0x\2/p")
|
|
tags=$($(eval 'printf "dd if=$f bs=1 count=%d skip=%d\n" $length_offset') 2>/dev/null)
|
|
if [[ -n "${tags}" && "${tags}" != "${module_name},${variant},${rpv}" ]] ; then
|
|
echo Tag mismatch: ${f} File: "${tags}" Manifest: "${module_name},${variant},${rpv}"
|
|
need_install=1
|
|
break
|
|
fi
|
|
fi
|
|
|
|
cs=$(md5sum ${f} | cut -b1-32)
|
|
if [[ "${cs}" != "${sum}" ]] ; then
|
|
echo Checksum mismatch: ${f}
|
|
need_install=1
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
else
|
|
need_install=1
|
|
fi
|
|
|
|
if [[ ${need_install} == 1 ]] ; then
|
|
if [[ ( -n "${ipvi}" ) && ${ipvi} > ${rpvi} ]] ; then
|
|
echo "${full_name}: Installed package is newer than that available for download."
|
|
exit 0
|
|
fi
|
|
else
|
|
echo "${full_name} is up to date."
|
|
exit 0;
|
|
fi
|
|
|
|
need_download=1
|
|
if [[ -f ${cache_dir}/${full_name}.manifest.xml ]] ; then
|
|
cpv=$(${XMLSTARLET} sel -t -v "/package/@version" ${cache_dir}/${full_name}.manifest.xml)
|
|
cpvi=$(version_convert ${cpv})
|
|
echo "${full_name}: Cached package version ${cpv} (${cpvi})"
|
|
if [[ ${cpvi} == ${rpvi} && ( -f ${cache_dir}/${tarball} ) ]] ; then
|
|
echo "${full_name}: Cached version is available."
|
|
need_download=0
|
|
fi
|
|
fi
|
|
|
|
if [[ ${need_download} = 1 ]] ; then
|
|
echo "${full_name}: Downloading ${remote_url}/${tarball}"
|
|
${WGET} -q -O ${cache_dir}/${tarball} ${remote_url}/${tarball} || {
|
|
echo "${full_name}: Unable to fetch ${remote_url}/${tarball}"
|
|
exit 1
|
|
}
|
|
cp ${tmpdir}/${variant_manifest} ${cache_dir}/${full_name}.manifest.xml
|
|
fi
|
|
|
|
tar -xzf ${cache_dir}/${tarball} -C ${cache_dir}
|
|
trap "rm -rf ${cache_dir}/${module_dir} ; rm -rf ${tmpdir}" EXIT
|
|
|
|
echo "${full_name}: Installing."
|
|
|
|
if [[ $EUID == 0 ]] ; then
|
|
install_params="--group=0 --owner=0"
|
|
fi
|
|
|
|
names=$(${XMLSTARLET} sel -t -m "//file" -v "@name" -n ${cache_dir}/${module_dir}/manifest.xml)
|
|
for name in ${names} ; do
|
|
source_path=${cache_dir}/${module_dir}/${name}
|
|
install_path=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@install_path" ${cache_dir}/${module_dir}/manifest.xml)
|
|
install_path=${DESTDIR}$(eval echo ${install_path})
|
|
executable=$(${XMLSTARLET} sel -t -v "//file[@name = '${name}']/@executable" ${cache_dir}/${module_dir}/manifest.xml || :)
|
|
if [[ "${executable}" = "yes" ]] ; then
|
|
mode=0755
|
|
else
|
|
mode=0644
|
|
fi
|
|
|
|
${INSTALL} -Dp ${install_params} --mode=${mode} ${source_path} ${install_path}
|
|
|
|
done
|
|
${INSTALL} -Dp ${install_params} --mode=0644 ${cache_dir}/${module_dir}/manifest.xml ${DESTDIR}${ASTMODDIR}/${module_name}.manifest.xml
|
|
|
|
echo "${full_name}: Installed."
|