This commit is contained in:
embed@git.macaw.me 2024-01-06 01:38:28 +00:00
commit b50fd16591
197 changed files with 41663 additions and 0 deletions

View file

@ -0,0 +1,6 @@
# from yasat on Ubuntu16
/etc/ssl/certs/Certplus_Class_2_Primary_CA.pem
/etc/ssl/certs/UTN_USERFirst_Hardware_Root_CA.pem
/etc/ssl/certs/DST_ACES_CA_X6.pem
/etc/ssl/certs/GeoTrust_Global_CA_2.pem
/etc/ssl/certs/Deutsche_Telekom_Root_CA_2.pem

View file

@ -0,0 +1,4 @@
# https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/
# kernel.yama.ptrace_scope = 0: all processes can be debugged, as long as they have same uid. This is the classical way of how ptracing worked.
sysctl kernel.yama.ptrace_scope = 0

View file

@ -0,0 +1,50 @@
# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
# PCI device 0x168c:0x0036 (ath9k)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="70:18:8b:7f:c3:bf", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan0"
# PCI device 0x10ec:0x8136 (r8169)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="74:86:7a:38:33:24", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
# USB device 0x148f:0x3070 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="48:02:2a:53:36:68", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan1"
# USB device 0x148f:0x5370 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:87:30:33:5f:38", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan2"
# USB device 0x148f:0x5370 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:43:44:5a:e8", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan3"
# USB device 0x0cf3:0x9271 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:c0:ca:84:ac:4b", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan4"
# PCI device 0x168c:0x0036 (ath9k)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="70:18:8b:73:37:9f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan5"
# PCI device 0x8086:0x155a (e1000e)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="ec:f4:bb:67:40:1e", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
# PCI device 0x8086:0x08b1 (iwlwifi)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="80:19:34:af:89:b7", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan6"
# PCI device 0x10ec:0x8168 (r8169)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="20:47:47:5f:35:2e", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"
# PCI device 0x8086:0x095a (iwlwifi)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="4c:34:88:65:bc:f6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan7"
# PCI device 0x8086:0x15a2 (e1000e)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="34:e6:d7:6b:66:0d", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"
# PCI device 0x8086:0x095a (iwlwifi)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="34:02:86:d3:9e:e2", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan8"
# PCI device 0x8086:0x15a2 (e1000e)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="34:e6:d7:56:fa:c4", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth4"
# PCI device 0x8086:0x095a (iwlwifi)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="34:02:86:19:a5:e6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan9"

View file

@ -0,0 +1,435 @@
#!/bin/bash -e
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
shopt -o -s pipefail
[ $( id -u ) -eq 0 ] || { echo "ERROR: this must be run as root" ; exit 1 ; }
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
ROLE=base
WD=$PWD
PYVER=3
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
MV=mv
COPY="ln -s"
[ -z "$BASE_PYTHON2_MINOR" ] && \
BASE_PYTHON2_MINOR=$( python2 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$BASE_PYTHON3_MINOR" ] && \
BASE_PYTHON3_MINOR=$( python3 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR/site-packages ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR/site-packages
fi
[ -z "$BOX_ALSO_GROUP" ] || BOX_ALSO_GROUP=adm
[ -z "$UPTMP" ] && UPTMP=$PREFIX/tmp
# With packer the files we need are not on the host - they are pushed up and $UPTMP is populated with:
PDIRS="authorized_keys archives boxuser_pip_cache root_pip_cache cacert.pem wheels"
# With vagrant the files may have been tarred on the host and be in their cannonical positions.
# We symlink to files under vagrant to /tmp to leave the packer scripts untouched.
# With packer and docker we can remote mount partitions and not even copy them up to the guest.
[ -n "$TESTF_DEBIAN10_VAR_APT_ARCHIVES" ] && [ -d "$TESTF_DEBIAN10_VAR_APT_ARCHIVES/" ] && \
[ ! -e $UPTMP/archives ] && ln -s $TESTF_DEBIAN10_VAR_APT_ARCHIVES/ $UPTMP/archives
[ -n "$HOSTVMS_BOXUSER_PLAY_PIP_CACHE" ] && [ -e "$HOSTVMS_BOXUSER_PLAY_PIP_CACHE" ] && \
[ ! -e $UPTMP/boxuser_pip_cache ] && ln -s $HOSTVMS_BOXUSER_PLAY_PIP_CACHE/ $UPTMP/boxuser_pip_cache
[ -n "$HOSTVMS_ROOT_PLAY_PIP_CACHE" ] && [ -d "$HOSTVMS_ROOT_PLAY_PIP_CACHE/" ] && \
[ ! -e $UPTMP/root_pip_cache ] && ln -s "$HOSTVMS_ROOT_PLAY_PIP_CACHE/" $UPTMP/root_pip_cache
export PLAY_PIP_CERT="/usr/local/etc/ssl/cacert-testforge.pem"
[ -f $PLAY_PIP_CERT ] && \
[ ! -e $UPTMP/cacert.pem ] && ln -s $PLAY_PIP_CERT $UPTMP/cacert.pem
# config_file = os.environ.get('PIP_CONFIG_FILE', None)
# /usr/$LIB/python2.7/site-packages/pip/_internal/configuration.py
bootstrap_mkdir () { mkdir $1 ; chgrp $BOX_ALSO_GROUP $1 ; }
[ -d /usr/local/tmp ] || { mkdir -p /usr/local/tmp ; chmod 1777 /usr/local/tmp ; }
site_packages=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages
[ -d $site_packages ] || bootstrap_mkdir $site_packages
[ -f $site_packages/__init__.py ] || touch $site_packages/__init__.py
if [ ! -d /usr/local/tmp/wheels ] ; then
cd /usr/local
sh sbin/bootstrap_wheels.bash || exit 2
fi
[ ! -d $UPTMP/wheels/ ] && [ $UPTMP/ != /usr/local/tmp/ ] && ln -s /usr/local/tmp/wheels $UPTMP/wheels
# But with vagrant or docker we may have mounted the HOST partitions that contain the files
# [ -z "$TESTF_UBUNTU16_VAR_APT_ARCHIVES" ] && TESTF_UBUNTU16_VAR_APT_ARCHIVES -> $UPTMP/archives
[ -z "BOX_USER_NAME" ] && BOX_USER_NAME=user
[ -z "BOX_USER_HOME" ] && BOX_USER_HOME=/home/$BOX_USER_NAME
[ -z "BOX_ALSO_GROUP" ] && BOX_ALSO_GROUP=adm
[ -z "$LOGDIR" ] && LOGDIR=$PREFIX/tmp
[ -d $LOGDIR ] || { mkdir $LOGDIR ; chmod 1777 $LOGDIR ; }
# not needed: --no-binary :all: --upgrade-strategy only-if-needed
# not yet: --user
PIP_INSTALL_ARGS="--disable-pip-version-check --prefix=$PREFIX --install-option=--prefix=$PREFIX"
scripts="ansible ansible-playbook ansible-pull ansible-doc ansible-galaxy ansible-console ansible-connection ansible-vault"
export DEBIAN_FRONTEND=noninteractive
export PIP_DEFAULT_TIMEOUT=60
ANSIBLE_VER="2.8.12"
#2? PYYAML_VER="3.12"
ansible_tgz=ansible-$ANSIBLE_VER.tar.gz
#2? yaml_tgz=PyYAML-$PYYAML_VER.tar.gz
if [ -n "$BOX_USER_NAME" ] ; then
# Packer will not have created this and we will need it early.
[ -d $BOX_USER_HOME ] || \
bootstrap_mkdir $BOX_USER_HOME
#? useradd -d $BOX_USER_HOME -G root -m $BOX_USER_NAME
# If you want to use your own private key for packer
[ -d $BOX_USER_HOME/.ssh ] || \
bootstrap_mkdir $BOX_USER_HOME/.ssh
if [ -f $UPTMP/authorized_keys ] ; then
$COPY $UPTMP/authorized_keys $BOX_USER_HOME/.ssh && \
chmod 600 $BOX_USER_HOME/.ssh/authorized_keys
fi
chmod 700 $BOX_USER_HOME/.ssh/
fi
[ -d /var/cache/apt/archives ] || mkdir -p /var/cache/apt/archives
# If you upload your cache of Ubuntu .debs, it cuts down on the downloading
[ -d $UPTMP/archives ] && \
$COPY $UPTMP/archives/*.deb /var/cache/apt/archives 2>/dev/null
# leave this for cleanup:
# rm -rf $UPTMP/archives
# If you upload your cache of pip files, it cuts down on the downloading
if [ -d $UPTMP/boxuser_pip_cache ] ; then
bootstrap_mkdir $BOX_USER_HOME/.cache/ && \
cp -rip $UPTMP/boxuser_pip_cache $BOX_USER_HOME/.cache/pip && \
chown -R ${BOX_USER_NAME}.{BOX_ALSO_GROUP} $BOX_USER_HOME/.cache/pip && \
chmod -R g+rw $BOX_USER_HOME/.cache/pip && \
chmod -R o-w $BOX_USER_HOME/.cache/pip
fi
if [ -d $UPTMP/root_pip_cache ] ; then
bootstrap_mkdir /root/.cache/ && \
cp -rip $UPTMP/root_pip_cache /root/.cache/pip && \
chown -R root.root /root/.cache/pip && \
chmod -R g+rw /root/.cache/pip && \
chmod -R o-w /root/.cache/pip
fi
if [ -d /etc/apt ] ; then
if ! route | grep -q ^default ; then
DEBUG "Not connected; skipping apt-get update"
elif [ ! -f /var/log/dpkg.log ] ; then
apt-get update # || exit 4
fi
which unzip || ! [ -f /var/cache/apt/archives/unzip_6.0-23+deb10u1_amd64.deb ] || \
dpkg -i /var/cache/apt/archives/unzip_6.0-23+deb10u1_amd64.deb
which curl || [ ! -f /var/cache/apt/archives/curl_7.64.0-4+deb10u1_amd64.deb ] || \
dpkg -i /var/cache/apt/archives/curl_7.64.0-4+deb10u1_amd64.deb \
/var/cache/apt/archives/libcurl4_7.64.0-4+deb10u1_amd64.deb \
/var/cache/apt/archives/libcurl4-openssl-dev_7.64.0-4+deb10u1_amd64.deb
apt-get install -y --force-yes wget unzip openssl || true
[ -f /usr/include/Python.h ] || \
apt-get install -y --force-yes \
libffi-dev libssl-dev python3-dev python3-apt python3-pycparser \
python3-coverage || \
echo WARN you must run apt-get update
# msg: Could not find `coverage` module.
elif [ -d /etc/portage ] ; then
# FixMe: put these in wheels?
[ -x /usr/bin/unzip ] || which unzip 2>/dev/null || emerge -vb app-arch/unzip
[ -x /usr/bin/wget ] || which wget 2>/dev/null || emerge -vb net-misc/wget
which openssl 2>/dev/null || timeout 600 emerge -vb dev-libs/openssl
# openssl installs:
# dev-python/pyopenssl-19.1.0
# dev-python/six-1.13.0
# dev-python/cryptography-2.8
# dev-python/cffi-1.12.3:0/1.12.3
# dev-python/pycparser-2.19-r1
# dev-python/ply-3.11:0/3.11
# virtual/python-ipaddress-1.0-r1
# dev-python/ipaddress-1.0.23
# virtual/python-enum34-2
# dev-python/enum34-1.1.6-r1
python$PYVER -c 'import OpenSSL' 2>/dev/null || timeout 600 emerge -vb dev-python/pyopenssl
python$PYVER -c 'import pycparser' 2>/dev/null || timeout 600 emerge -vb dev-python/pycparser
python$PYVER -c 'import yaml' 2>/dev/null || timeout 600 emerge -vb dev-python/pyyaml
DEBUG "Gentoo Installed openssl and wget"
fi
# On a CORP laptop off the VPN we may need some CAs
[ -d $PREFIX/etc/ssl ] || mkdir -p $PREFIX/etc/ssl
[ ! -f $PLAY_PIP_CERT ] && \
[ -f $UPTMP/cacert.pem ] && \
$COPY $UPTMP/cacert.pem $PLAY_PIP_CERT
# pip gets confused
# or just delete $PREFIX/$LIB/python$PYTHON_MINOR/dist-packages afterwards
for PYVER in 3 ; do
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
site_packages=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages
[ -d $site_packages ] || bootstrap_mkdir $site_packages
[ -f $site_packages/__init__.py ] || touch $site_packages/__init__.py
if [ -d /etc/apt ] ; then
dist_packages=$PREFIX/lib/python$PYTHON_MINOR/dist-packages
WD=$PWD
if [ -d $dist_packages ] ; then
cd $PREFIX/lib/python$PYTHON_MINOR
ln -s $site_packages .
cd $WD
fi
fi
# we will use $PREFIX/bin/python3.bash NOT $PREFIX/bin/python3.sh
# to not conflict with what Ansible will push later/before.
if [ ! -e $PREFIX/bin/python$PYVER.bash ] ; then
echo "INFO: bootstraping $PREFIX/bin/python$PYVER.bash"
cat > $PREFIX/bin/python$PYVER.bash << EOF
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
# from bootstrap_pip_ansible.bash
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
# pip gets confused
dist_packages=$site_packages
dist_packages=\$dist_packages:\${dist_packages}/pip/_vendor
if [ -z "$PYTHONPATH" ] ; then
export PYTHONPATH=\$dist_packages
else
export PYTHONPATH=\$PYTHONPATH:\$dist_packages
fi
exec python$PYTHON_MINOR "\$@"
EOF
chmod 755 $PREFIX/bin/python$PYVER.bash
fi
# pip may be loaded in the base iso
if [ -x $PREFIX/bin/python$PYVER.bash ] && \
$PREFIX/bin/python$PYVER.bash -c 'import pip' 2>/dev/null ; then
INFO pip$VER already installed
elif [ ! -d $UPTMP/wheels/ ] ; then
WARN $UPTMP/wheels not found
else
# we may be without the VPN/proxy but on a corporate laptop
# with a hosed chain of Certificate Authorities for the MITM proxy
# in which case http://bootstrap.pypa.io/get-pip.py will not work,
# so effective but groddy:
# just unzip the wheels into site-packages and force-reinstall later
cd $UPTMP/wheels/
echo "INFO: installing pip - unzipping wheels into $site_packages"
for file in *.whl ; do
#a=$( echo $file | sed -e 's/-.*//' )
#b=$( basename $a|sed -e 's/Py//'|tr '[A-Z]' '[a-z]' )
#python$PYVER -c "import $b" 2>/dev/null >/dev/null && continue
unzip -n $file -d $site_packages >/dev/null
done
# morons
# -rwx------ 1 root root 8866 Jun 11 2018 /usr/local/$LIB/python$PYTHON_MINOR/site-packages/idna-2.7.dist-info/METADATA
find $site_packages -type d -exec chmod a+rx '{}' \;
find $site_packages -type f -exec chmod a+r '{}' \;
chgrp -R "$BOX_ALSO_GROUP" $site_packages
# hack in a PYTHONPATH for our unzipped wheels - removed later
for elt in pip ; do # is wheel needed?
echo "INFO: Installing $elt"
# use $PYVER.bash for bootstrap - $PYVER.bash will come later
cat > $PREFIX/bin/$elt$PYVER.bash << EOF
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
export PLAY_PIP_CERT=$PIP_CERT
export PYTHONPATH=${site_packages}
export PYTHONPATH=\$PYTHONPATH:${site_packages}/pip/_vendor
#? FixMe: narrow to InsecurePlatformWarning
python$PYVER -W ignore -m $elt "\$@"
EOF
chmod 755 $PREFIX/bin/$elt$PYVER.bash
$PREFIX/bin/$elt$PYVER.bash --help >/dev/null
DEBUG "Installed $elt$PYVER.bash"
done
fi
# do I still need this
#if [ -x $PREFIX/bin/pip$PYVER ] && [ -d $site_packages ] ; then
# export PYTHONPATH=$site_packages:$site_packages/pip/_vendor
#fi
if [ ! -x $PREFIX/bin/pip$PYVER.bash ] ; then
echo "ERROR: Failed to Install pip$PYVER at $PREFIX/bin/pip$PYVER.bash"
exit 3
elif ! $PREFIX/bin/python$PYVER.bash -m pip -V ; then
echo "ERROR: Failed to run pip$PYVER at $PREFIX/bin/pip$PYVER"
exit 4
fi
if [ -f $PLAY_PIP_CERT ] ; then
if [ ! -f $site_packages/pip/_vendor/requests/cacert.pem.dst ] && \
[ -f $site_packages/pip/_vendor/requests/cacert.pem ] && \
[ ! -h $site_packages/pip/_vendor/requests/cacert.pem ] ; then
mv $site_packages/pip/_vendor/requests/cacert.pem $site_packages/pip/_vendor/requests/cacert.pem.dst
fi
if [ ! -h $site_packages/pip/_vendor/requests/cacert.pem ] ; then
rm -f $site_packages/pip/_vendor/requests/cacert.pem
fi
[ -e $site_packages/pip/_vendor/requests/cacert.pem ] || \
ln -s $PLAY_PIP_CERT $site_packages/pip/_vendor/requests/cacert.pem
INFO linked $PLAY_PIP_CERT $site_packages/pip/_vendor/requests/cacert.pem
fi
done
# dont use -CAfile $UPTMP/cacert.pem - we want it to fail if we need the cert
if openssl s_client -connect pypi.org:443 </dev/null | \
grep -q 'unable to get local issuer certificate' ; then
echo "WARN: it looks like you have a hosed SSL Certificate Authority chain"
fi
$PREFIX/bin/pip$PYVER.bash --version || exit 5
[ -d /usr/local/src ] || { bootstrap_mkdir /usr/local/src ; }
[ -d /usr/local/bin ] || { bootstrap_mkdir /usr/local/bin ; }
if [ -f $PLAY_PIP_CERT ] ; then
export PLAY_PIP_CERT=$PIP_CERT
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS --cert $PLAY_PIP_CERT"
else
echo "WARN: PLAY_PIP_CERT not found $PIP_CERT"
fi
if [ ! -f /etc/wgetrc ] ; then
sh $WD/bootstrap_proxy.bash
fi
# pip uses curl - and has a config file PIP_CONFIG
DEBUG "http_proxy=$http_proxy https_proxy=$https_proxy"
if [ -n "$https_proxy" ] ; then
echo "INFO: Adding to PIP_INSTALL_ARGS --proxy=$https_proxy"
elif [ -f /etc/wgetrc ] && grep ^http_proxy /etc/wgetrc ; then
proxy=$( grep ^http_proxy /etc/wgetrc|sed -e 's@.*=@--proxy=@' )
echo "INFO: Adding to PIP_INSTALL_ARGS $proxy"
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS $proxy"
fi
# lengthen the timeout in case you are on a slow line
# or /etc/pip.conf
# [global]
# timeout = 60
cd $PREFIX/src || exit 6
boostrap_setup_ansible () {
local WD=$PWD
cd /usr/local/src
[ -d ansible-$ANSIBLE_VER ] || tar xfz $UPTMP/wheels/$ansible_tgz
cd ansible-$ANSIBLE_VER
RARGS=" --user $RARGS"
# Can not combine '--user' and '--prefix'
## RARGS=" --prefix=$PREFIX $RARGS"
# Can not combine '--user' and '--install-option=--prefix' ?? - check for symlink
# RARGS=" --prefix=/usr/local $RARGS"
RARGS=" --install-scripts=/usr/local/bin $RARGS"
RARGS=" --install-lib=/usr/local/$LIB/python$PYTHON_MINOR/site-packages $RARGS"
RARGS=" --install-layout=unix $RARGS"
export PYTHONPATH=/usr/local/$LIB/python3.7/site-packages
DEBUG "/usr/local/bin/python$PYVER.bash setup.py install $RARGS"
su -c "/usr/local/bin/python$PYVER.bash setup.py install $RARGS" \
${BOX_USER_NAME} >> install.log
retval=$?
cd $WD
return $retval
}
# NOW we use our fresh pip to install ansible from source, into /usr/local
if [ -x $PREFIX/bin/ansible ] ; then
INFO already installed $PREFIX/bin/ansible
else
if true ; then
DEBUG "$PREFIX/bin/pip$PYVER.bash install $PIP_INSTALL_ARGS $UPTMP/wheels/$ansible_tgz"
# install from the file to keep the version pinned
$PREFIX/bin/pip$PYVER.bash install $PIP_INSTALL_ARGS $UPTMP/wheels/$ansible_tgz \
>> $LOGDIR/pip_install_pip_ansible.log 2>&1 || \
{ ERROR installing $ansible_tgz ; cat $LOGDIR/pip_install_pip_ansible.log && exit 7 ; }
else
boostrap_setup_ansible
[ $? -eq 0 ] || { ERROR installing ansible ; tail install.log ; exit 8 ; }
fi
if [ -d /etc/portage/ ] ; then
[ -d /etc/portage/profile ] || mkdir /etc/portage/profile
grep -q app-admin/ansible-$ANSIBLE_VER /etc/portage/profile/package.provided || \
echo app-admin/ansible-$ANSIBLE_VER >> /etc/portage/profile/package.provided
fi
cd $PREFIX/bin
[ -e ansible-doc ] || { ERROR installing ansible-doc ; exit 9 ; }
grep "#\!.$PREFIX/bin/python$PYVER.bash" ansible-doc || \
sed -e "s@^#\!.*python.*@#\!${PREFIX}/bin/python$PYVER.bash@" -i $scripts
fi
ansible --version || exit 10
if [ -f $PLAY_PIP_CERT ] ; then
export PLAY_PIP_CERT=$PIP_CERT
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS --cert $PLAY_PIP_CERT"
else
echo "WARN: PLAY_PIP_CERT not found $PIP_CERT"
fi
if [ ! -f /etc/wgetrc ] ; then
sh $WD/bootstrap_proxy.bash
fi
# pip uses curl - and has a config file PIP_CONFIG
DEBUG "http_proxy=$http_proxy https_proxy=$https_proxy"
if [ -n "$https_proxy" ] ; then
echo "INFO: Adding to PIP_INSTALL_ARGS --proxy=$https_proxy"
elif [ -f /etc/wgetrc ] && grep ^http_proxy /etc/wgetrc ; then
proxy=$( grep ^http_proxy /etc/wgetrc|sed -e 's@.*=@--proxy=@' )
echo "INFO: Adding to PIP_INSTALL_ARGS $proxy"
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS $proxy"
fi
cd $PREFIX/src
# install pycurl as a test of pip and a requisite for proxyauth.py
if ! $PREFIX/bin/python$PYVER.bash -c 'import curl' 2>/dev/null ; then
if [ -d /etc/apt ] ; then
apt-get install -y --force-yes libcurl4-openssl-dev \
2>&1|tee $LOGDIR/apt-get_install_libcurl4-openssl-dev.log
elif [ -d /etc/portage ] ; then
[ -x /usr/bin/curl ] || which curl 2>/dev/null || emerge -vb curl
fi
#? --allow-unverified pycurl
if ! route | grep -q ^default ; then
DEBUG "Not connected; not installing pycurl"
elif $PREFIX/bin/pip$PYVER.bash install $PIP_INSTALL_ARGS pycurl >> $LOGDIR/pip_install_pycurl.log 2>&1 ; then
echo "INFO: Installed pycurl from pip with $PREFIX/bin/pip install $PIP_INSTALL_ARGS"
# We dont fail the packer build if it errors - just fix it and rerun
$PREFIX/bin/python$PYVER.bash -c 'import curl; print curl.__file__' || true
else
echo "WARN: Installing pycurl failed with $PREFIX/bin/pip install $PIP_INSTALL_ARGS"
cat $LOGDIR/pip_install_pycurl.log
fi
fi
[ -e /usr/local/bin/python$PYVER.sh ] || \
[ -h /usr/local/bin/python$PYVER.sh ] || \
ln -s /usr/local/bin/python$PYVER.babash /usr/local/bin/python$PYVER.sh
find /usr/local/$LIB/python$PYVER.7/site-packages/ansible/modules/ -name \*.py \
-exec grep -q /usr/bin/python '{}' \; -print \
-exec sed -e "1,$PYVERs@#!/usr/bin/python@#!/usr/local/bin/python$PYVER.bash@" -i '{}' \;
exit 0

View file

@ -0,0 +1,7 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
ROLE=base
prog=$( basename $0 .bash )
exec python3.sh /usr/local/bin/base_certdata2pem.py "$@"

View file

@ -0,0 +1,153 @@
#!/usr/bin/python
# vim:set et sw=4:
#
# certdata2pem.py - splits certdata.txt into multiple files
#
# Copyright (C) 2009 Philipp Kern <pkern@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
# USA.
import base64
import os.path
import re
import sys
import textwrap
import io
objects = []
# Dirty file parser.
in_data, in_multiline, in_obj = False, False, False
field, type, value, obj = None, None, None, dict()
# Python 3 will not let us decode non-ascii characters if we
# have not specified an encoding, but Python 2's open does not
# have an option to set the encoding. Python 3's open is io.open
# and io.open has been backported to Python 2.6 and 2.7, so use io.open.
for line in io.open('certdata.txt', 'rt', encoding='utf8'):
# Ignore the file header.
if not in_data:
if line.startswith('BEGINDATA'):
in_data = True
continue
# Ignore comment lines.
if line.startswith('#'):
continue
# Empty lines are significant if we are inside an object.
if in_obj and len(line.strip()) == 0:
objects.append(obj)
obj = dict()
in_obj = False
continue
if len(line.strip()) == 0:
continue
if in_multiline:
if not line.startswith('END'):
if type == 'MULTILINE_OCTAL':
line = line.strip()
for i in re.finditer(r'\\([0-3][0-7][0-7])', line):
value.append(int(i.group(1), 8))
else:
value += line
continue
obj[field] = value
in_multiline = False
continue
if line.startswith('CKA_CLASS'):
in_obj = True
line_parts = line.strip().split(' ', 2)
if len(line_parts) > 2:
field, type = line_parts[0:2]
value = ' '.join(line_parts[2:])
elif len(line_parts) == 2:
field, type = line_parts
value = None
else:
raise NotImplementedError('line_parts < 2 not supported.')
if type == 'MULTILINE_OCTAL':
in_multiline = True
value = bytearray()
continue
obj[field] = value
if len(obj) > 0:
objects.append(obj)
# Read blacklist.
blacklist = []
if os.path.exists('blacklist.txt'):
for line in open('blacklist.txt', 'r'):
line = line.strip()
if line.startswith('#') or len(line) == 0:
continue
item = line.split('#', 1)[0].strip()
blacklist.append(item)
# Build up trust database.
trust = dict()
for obj in objects:
if obj['CKA_CLASS'] != 'CKO_NSS_TRUST':
continue
if obj['CKA_LABEL'] in blacklist:
print("Certificate %s blacklisted, ignoring." % obj['CKA_LABEL'])
elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_TRUSTED_DELEGATOR':
trust[obj['CKA_LABEL']] = True
elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED':
print('!'*74)
print("UNTRUSTED BUT NOT BLACKLISTED CERTIFICATE FOUND: %s" % obj['CKA_LABEL'])
print('!'*74)
else:
print("Ignoring certificate %s. SAUTH=%s, EPROT=%s" % \
(obj['CKA_LABEL'], obj['CKA_TRUST_SERVER_AUTH'],
obj['CKA_TRUST_EMAIL_PROTECTION']))
for obj in objects:
if obj['CKA_CLASS'] == 'CKO_CERTIFICATE':
if not obj['CKA_LABEL'] in trust or not trust[obj['CKA_LABEL']]:
continue
bname = obj['CKA_LABEL'][1:-1].replace('/', '_')\
.replace(' ', '_')\
.replace('(', '=')\
.replace(')', '=')\
.replace(',', '_')
# this is the only way to decode the way NSS stores multi-byte UTF-8
# and we need an escaped string for checking existence of things
# otherwise we're dependant on the user's current locale.
if bytes != str:
# We're in python 3, convert the utf-8 string to a
# sequence of bytes that represents this utf-8 string
# then encode the byte-sequence as an escaped string that
# can be passed to open() and os.path.exists()
bname = bname.encode('utf-8').decode('unicode_escape').encode('latin-1')
else:
# Python 2
# Convert the unicode string back to its original byte form
# (contents of files returned by io.open are returned as
# unicode strings)
# then to an escaped string that can be passed to open()
# and os.path.exists()
bname = bname.encode('utf-8').decode('string_escape')
fname = bname + b'.crt'
if os.path.exists(fname):
print("Found duplicate certificate name %s, renaming." % bname)
fname = bname + b'_2.crt'
f = open(fname, 'w')
f.write("-----BEGIN CERTIFICATE-----\n")
encoded = base64.b64encode(obj['CKA_VALUE']).decode('utf-8')
f.write("\n".join(textwrap.wrap(encoded, 64)))
f.write("\n-----END CERTIFICATE-----\n")

View file

@ -0,0 +1,90 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
PREFIX=/usr/local
ROLE=base
[ "$#" -eq 0 ] && echo USAGE: $0 2.7 ... 3.9 3.10 3.11 && exit 1
. /usr/local/bin/usr_local_base.bash || exit 2
[ -f $PREFIX/etc/testforge/testforge.bash ] \
&& . /usr/local/etc/testforge/testforge.bash
PYTHON_MINOR="$1"
PYMAJ="${PYTHON_MINOR:0:1}"
if [ -z "$LIB" -a -f /usr/lib/python$PYTHON_MINOR/site.py ] ; then
LIB=lib
elif [ -z "$LIB" -a -f /usr/lib64/python$PYTHON_MINOR/site.py ] ; then
LIB=lib64
fi
[ -d /usr/local/lib/python$PYTHON_MINOR ] && \
[ ! -e /usr/local/lib64/python$PYTHON_MINOR ] && \
ln -s /usr/local/lib/python$PYTHON_MINOR /usr/local/lib64/python$PYTHON_MINOR
if [ "" = "$BASE_PYTHON2_MINOR" ] ; then
not_PYTHON_MINOR=""
elif [ $PYTHON_MINOR = "$BASE_PYTHON2_MINOR" ] ; then
not_PYTHON_MINOR="$BASE_PYTHON3_MINOR"
elif [ $PYTHON_MINOR = "$BASE_PYTHON3_MINOR" ] ; then
not_PYTHON_MINOR="$BASE_PYTHON2_MINOR"
else
ERROR "$PYTHON_MINOR not in $BASE_PYTHON2_MINOR $BASE_PYTHON3_MINOR"
exit 1
fi
INFO $prog PYMAJ=$PYMAJ PYTHON_MINOR=$PYTHON_MINOR not_PYTHON_MINOR=$not_PYTHON_MINOR PYTHONPATH=$PYTHONPATH
export PYTHONPATH=""
if [ "$PYMAJ" = '2' ] ; then
imp='import sys; print sys.path'
elif [ "$PYMAJ" = '3' ] ; then
imp='import sys; print(repr(sys.path))'
fi
[ -x $PREFIX/bin/python$PYMAJ.sh ] || {
echo >&2 ERROR: $prog 2 -x $PREFIX/bin/python$PYMAJ.sh "$PYTHON_MINOR" && exit 2 ;
}
if [ -f /etc/python-exec/python2.conf ] ; then
grep -F "$BASE_PYTHON2_MINOR" /etc/python-exec/python2.conf || {
echo >&2 ERROR: $prog 3 "$BASE_PYTHON2_MINOR" /etc/python-exec/python2.conf
}
fi
if [ -f /etc/python-exec/python3.conf ] ; then
grep -F "$BASE_PYTHON3_MINOR" /etc/python-exec/python3.conf || {
echo >&2 ERROR: $prog 4 "$BASE_PYTHON3_MINOR" /etc/python-exec/python3.conf
}
fi
# echo -n DEBUG: $prog 2 python$PYTHON_MINOR -S -s
python$PYMAJ -S -s -c "$imp" \
|| { echo >&2 ERROR: $prog 22 $PYTHON_MAJ -S -s"$PYTHON_MINOR" && exit 22 ; }
# echo -n DEBUG: $prog 4 python$PYTHON_MINOR -s
python$PYMAJ -s -c "$imp" \
|| { echo >&2 ERROR: $prog 4 python$PYTHON_MINOR -s "$PYTHON_MINOR" && exit 4 ; }
# echo -n DEBUG: $0 6 $PREFIX/bin/python$PYMAJ.sh -S -s
$PREFIX/bin/python$PYMAJ.sh -S -s -c "$imp" \
|| { echo >&2 ERROR: $prog 6 python$PYMAJ.sh -S -s "$PYTHON_MINOR" && exit 6 ; }
echo -n DEBUG: $0 8 $PREFIX/bin/python$PYMAJ.sh -s
$PREFIX/bin/python$PYMAJ.sh -s -c "$imp" \
|| { echo >&2 ERROR: $prog 8 python$PYMAJ.sh -s "$PYTHON_MINOR" && exit 8 ; }
# INFO $prog 10 $PREFIX/bin/python$PYMAJ.sh sitecustomize.py "$PYTHON_MINOR"
a=$( $PREFIX/bin/python$PYMAJ.sh $PREFIX/$LIB/python$PYTHON_MINOR/site-packages/sitecustomize.py ) || \
{ echo >&2 ERROR: $prog "error 10 $PREFIX/bin/python$PYMAJ.sh $PREFIX/$LIB/python$PYTHON_MINOR/site-packages/sitecustomize.py" && exit 10 ; }
#[ -x "$a" ] || \
# { echo >&2 ERROR: $prog 11 "broken $PREFIX/bin/python$PYMAJ.sh /usr/local/bin/python2.sh - $a" && exit 11 ; }
#echo >&2 INFO: $prog 11 "$a"
# INFO $prog 12 python$PYTHON_MINOR sitecustomize.py "$PYTHON_MINOR"
python$PYMAJ $PREFIX/$LIB/python$PYTHON_MINOR/site-packages/sitecustomize.py || \
{ ERROR 12 $prog python$PYMAJ sitecustomize.py "$PYTHON_MINOR" && exit 12 ; }
exit 0
# [ $( python2.sh {{BASE_USR_LOCAL}}/$LIB/python{{BASE_PYTHON2_MINOR}}/site-packages/sitecustomize.py ) = {{BASE_USR_LOCAL}}/bin/python2.sh ] || exit 2
# [ $( python3.sh {{BASE_USR_LOCAL}}/$LIB/python{{BASE_PYTHON3_MINOR}}/site-packages/sitecustomize.py ) = {{BASE_USR_LOCAL}}/bin/python3.sh ] || exit 3
# [ $( python2.bash {{BASE_USR_LOCAL}}/$LIB/python{{BASE_PYTHON2_MINOR}}/site-packages/sitecustomize.py ) = /var/local/bin/python2.bash ] || exit 22
# [ $( python3.bash {{BASE_USR_LOCAL}}/$LIB/python{{BASE_PYTHON3_MINOR}}/site-packages/sitecustomize.py ) = /var/local/bin/python3.bash ] || exit 33

View file

@ -0,0 +1,27 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
ROLE=base
PREFIX=/usr/local
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash
# accepted files or directories -- to recusively look for files in
[ "$#" -eq 0 ] && set -- $PWD/
# Clean the bad ones under Windows: [:] and other uglies ['"{}[]?!]
# The Bad ones break rsync and but the others can cause trouble elsewhere
re='[^ .,~%+=^@!0-9a-zA-z_()#-]'
find "$@" -type f -or -type d | while read file ; do
dir=`dirname "$file"`
base=`basename "$file"`
# wierd = misses "ZeeRex The Explainable ``Explain__ Service.htm"
new=`sed -f $PREFIX/share/sed/base_clean_filenames.sed <<< $base`
[ "$base" = "$new" ] && continue
[ -f "$file" -a -f "$dir/$new" ] && diff -qr "$file" "$dir/$new" && rm -f "$file" && continue
DBUG \"$file\" \"$dir/$new\"
mv -i "$file" "$dir/$new"
done
exit 0

View file

@ -0,0 +1,24 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# we use stdout
ROLE=base
prog=$( basename $0 .bash )
N=""
IFS=':'
[ -z "$UID" ] && UID=$( id -u )
for elt in $PATH ; do
[ $UID -eq 0 -a "$elt" = '.' ] && continue
[ -d "$elt" ] || continue
[ -z "$N" ] && N="$elt" && continue
[[ $N =~ (^|:)${elt}(:|$) ]] && continue
N="$N:$elt" && continue
done
IFS=' '
elt=/var/local/bin
[[ "$N" =~ (^|:)"${elt}"(:|$) ]] || N="$N:$elt"
echo $N
exit 0

View file

@ -0,0 +1,40 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# answer output
prog=$( basename $0 .bash )
ROLE=base
[ $# -lt 2 ] && echo "USAGE: $0 PYTHON_MINOR PPATH" >>/proc/self/fd/2 && exit 1
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
PYTHON_MINOR=$1
PPATH=$2
PYVER=$( echo $1|sed -e 's/.*python//' -e 's@/.*@@' )
[[ "$PYTHON_MINOR" =~ .*2\..* ]] && notPYVER="3." || notPYVER="2."
# echo "DEBUG: $1 $PPATH $notPYVER" >>/proc/self/fd/2
N=""
IFS=':'
warns=0
[ -z "$UID" ] && UID=$( id -u )
for elt in $PPATH ; do
[ -d "$elt" ] || continue
[[ $elt =~ .*python${notPYVER}.* ]] ; a=$?
# DBUG $1 $elt $notPYVER a=$a >>/proc/self/fd/2
[ $a -eq 0 ] && { WARN $prog wanted: $PYTHON_MINOR got: $elt >>/proc/self/fd/2 ; \
warns=$( expr $warns + 1 ) ; continue ; }
[ -z "$N" ] && N="$elt" && continue
[[ $N =~ $elt ]] && continue
[ -n "$N" ] && N="$N:$elt"
# DBUG $prog adding: $elt
done
IFS=' '
echo $N
exit $warns

View file

@ -0,0 +1,95 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
ROLE=base
# The idea here is to run ansible_local.bash --tags daily
# and then use this to do the parsing and throwing errors based on the output.
# This was the ansible run can be free from erroring and this can be
# run repeatedly anytime outside of ansible to deal with the issues raised.
# It is also run at the end of ansible_local.bash --tags daily to raise the issues.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[ -f /usr/local/etc/testforge/testforge.bash ] && . /usr/local/etc/testforge/testforge.bash
. /usr/local/etc/local.d/local.bash
MYID=$( id -u )
[ $MYID -eq 0 ] || { ERROR $prog must be run as root $MYID ; exit 1 ; }
LOG_DIR=/usr/local/tmp
ly=daily
errs=0
warns=0
# sh /usr/local/bin/base_hourly.bash
LOG_DIR=/usr/local/tmp/$ly
[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR"
ELOG=$LOG_DIR/E${prog}_${ly}$$.log
WLOG=$LOG_DIR/W${prog}_${ly}$$.log
OUT=$LOG_DIR/O${prog}_${ly}$$.log
rm -f $LOG_DIR/*${prog}_${ly}*.log
if [ -f /var/log/dmesg.log ] ; then
grep 'IOMMU enabled' /var/log/dmesg.log || WARN NOT 'IOMMU enabled' | tee -a $WLOG
fi
cp /dev/null /var/log/dirmngr.log
/usr/local/bin/base_gnupg_test.bash || ERROR $retval /usr/local/bin/base_gnupg_test.bash >> $WLOG
[ -d /etc/portage ] && \
grep 'ERR 219 Server indicated a failure' /var/log/dirmngr.log >> $ELOG
[ -f /usr/local/etc/testforge/testforge.bash ] && \
. /usr/local/etc/testforge/testforge.bash
[ -z "$UPTMP" ] && UPTMP=$PREFIX/tmp
if [ -d /etc/apt -a -d /o/Cache/Apt/Devuan/4 ] ; then
[ -z "$TESTF_UBUNTU16_VAR_APT_ARCHIVES" ] && \
TESTF_UBUNTU16_VAR_APT_ARCHIVES=/o/Cache/Apt/Devuan/4
[ -z "BOX_USER_NAME" ] && BOX_USER_NAME=devuan
else
[ -z "BOX_USER_NAME" ] && BOX_USER_NAME=vagrant
fi
if [ -d /o/Cache/Pip/ ] ; then
[ -z "$HOSTVMS_BOXUSER_PIP_CACHE" ] && \
HOSTVMS_BOXUSER_PIP_CACHE=/o/Cache/Pip/
fi
# FixMe: bootstrap
elt=pip ; DBUG $elt
scripts="ansible ansible-playbook ansible-pull ansible-doc ansible-galaxy ansible-console ansible-connection ansible-vault"
for PYVER in 2 3 ; do
pfile=`python$PYVER.sh -c 'import pip; print(pip.__file__)'`
[ $? -eq 0 -a -f $pfile ] && continue
# /usr/local/sbin/bootstrap_pip.bash
pfile=`python$PYVER.sh -c 'import pip; print(pip.__file__)'`
[ $? -eq 0 -a -f $pfile ] || WARN pip $PYVER not installed - $pfile
for elt in $scripts ; do
[ -e $PREFIX/bin/$elt ] || { WARN installing $elt $PYVER ; }
done
done
elt=doctest3
if [ $MYID -ne 0 ] ; then
/var/local/bin/testforge_python_doctest3.bash \
/var/local/share/doc/txt/base3.txt \
> "$LOG_DIR"/$elt$$.log 2>&1 || ERROR $elt >> $ELOG
fi
[ -f $WLOG ] && warns=$( wc -l $WLOG | cut -f 1 -d ' ' )
[ $? -eq 0 -a $warns -ne 0 ] && \
WARN "$prog $warns $ly $prog warnings in $WLOG"
[ -f $ELOG ] && errs=$( wc -l $ELOG | cut -f 1 -d ' ' )
[ $? -eq 0 -a $errs -ne 0 ] && \
echo "ERROR: $prog $errs $ly $prog errors in $ELOG" && cat $ELOG
[ $errs -eq 0 ] && \
[ $warns -eq 0 ] && \
INFO "$prog No $ly errors" && \
rm -f $WLOG $ELOG $OUT
exit $errs

View file

@ -0,0 +1,51 @@
#!/usr/bin/expect --
# -*- mode: tcl; tab-width: 8; encoding: utf-8-unix -*-
set timeout 30
set KEY_ID 96D8BF6D
#? stty raw -echo
spawn gpg --home /etc/portage/gnupg --edit-key $KEY_ID trust
# unknown] (1). Gentoo ebuild repository signing key (Automated Signing Key) <infrastructure@gentoo.org>
# unknown] (2) Gentoo Portage Snapshot Signing Key (Automated Signing Key)
## tsign
#expect "Really sign all user IDs? (y/N)?*"
#send_user "Sending y\n"
#send "y\n"
# tsign -> gpg: no default secret key: No secret key
# trust
expect "Your decision?*"
send_user "Sending 4\n"
send "4\n"
# No save is required for trust
expect "gpg>*"
send_user "Sending save\r"
send "save\r"
expect -re .+ {
exp_continue
} timeout {
exit 1
} eof {
exit 0
} "Key not changed so no update needed*" {
exit 0
}
expect "gpg>*"
send_user "Sending quit\r"
send "quit\r"
expect -re .+ {
exp_continue
} timeout {
exit 1
} eof {
exit 0
}
# expect -r .+ {send "\r"}

View file

@ -0,0 +1,344 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Release media signatures Gentoo Linux</title>
<meta name="theme-color" content="#54487a">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta property="og:title" content="Release media signatures Gentoo Linux">
<meta property="og:image" content="https://www.gentoo.org/assets/img/logo/gentoo-g.png">
<meta property="og:description" content="News and information from Gentoo Linux">
<meta name="twitter:image" content="https://www.gentoo.org/assets/img/logo/gentoo-g.png">
<link rel="apple-touch-icon" href="https://www.gentoo.org/assets/img/logo/icon-192.png">
<link rel="icon" sizes="192x192" href="https://www.gentoo.org/assets/img/logo/icon-192.png">
<link href="https://assets.gentoo.org/tyrian/v1/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="https://assets.gentoo.org/tyrian/v1/tyrian.min.css" rel="stylesheet" media="screen">
<link href="/assets/css/screen.css" rel="stylesheet" media="screen">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/www-gentoo-org.xml" title="Gentoo Website">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/forums-gentoo-org.xml" title="Gentoo Forums">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/bugs-gentoo-org.xml" title="Gentoo Bugzilla">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/packages-gentoo-org.xml" title="Gentoo Packages">
<link rel="search" type="application/opensearchdescription+xml" href="https://www.gentoo.org/search/archives-gentoo-org.xml" title="Gentoo List Archives">
</head>
<body class="">
<header>
<div class="site-title">
<div class="container">
<div class="row">
<div class="site-title-buttons">
<div class="btn-group btn-group-sm">
<a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a>
<div class="btn-group btn-group-sm">
<a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#">
<span class="fa fa-fw fa-map-o"></span> <span class="hidden-xs">gentoo.org sites</span> <span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a></li>
<li><a href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a></li>
<li><a href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a></li>
<li><a href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a></li>
<li><a href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a></li>
<li class="divider"></li>
<li><a href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a></li>
<li><a href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a></li>
<li><a href="https://gitweb.gentoo.org/" title="Browse our source code in Gitweb"><span class="fa fa-code fa-fw"></span> Gitweb</a></li>
<li class="divider"></li>
<li><a href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra status</a></li>
</ul>
</div>
</div>
</div>
<div class="logo">
<a href="/" title="Back to the homepage" class="site-logo">
<object data="https://assets.gentoo.org/tyrian/v1/site-logo.svg" type="image/svg+xml">
<img src="https://assets.gentoo.org/tyrian/v1/site-logo.png" alt="Gentoo Linux logo">
</object>
</a>
</div>
</div>
</div>
</div>
<nav class="tyrian-navbar" role="navigation">
<div class="container">
<div class="row">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse navbar-main-collapse">
<ul class="nav navbar-nav">
<li class=""><a href="/">Home</a></li>
<li class=""><a href="/get-started/">Get started</a></li>
<li class="active"><a href="/downloads/">Downloads</a></li>
<li class=""><a href="/inside-gentoo/">Inside Gentoo</a></li>
<li class=""><a href="/support/">Support</a></li>
<li class=""><a href="/get-involved/">Get involved</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class=""><a href="/donate/"><span class="fa fa-heart" style="color:#d9534f;"></span> Donate</a></li>
</ul>
</div>
</div>
</div>
</nav>
<nav class="navbar navbar-grey navbar-stick" role="navigation">
<div class="container">
<div class="row">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-secondary-collapse">
<span class="sr-only">Toggle secondary navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse navbar-secondary-collapse">
<ul class="nav navbar-nav">
<li class=""><a href="/downloads/mirrors/">Mirrors</a></li>
<li class="active"><a href="/downloads/signatures/">Signatures</a></li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<div class="container">
<div class="row">
<div id="content" class="col-md-12">
<h1 class="first-header">Release media signatures</h1>
<p>
Our current releases are signed with either of these keys <strong>or any sub keys:</strong>
</p>
<br>
<table class="table table-striped">
<tr>
<th>Key Fingerprint</th>
<th>Description</th>
<th>Created</th>
<th>Expiry</th>
</tr>
<tr>
<td><kbd>13EBBDBEDE7A12775DFDB1BABB572E0E2D182910</kbd></td>
<td>Gentoo Linux Release Engineering (Automated Weekly Release Key)</td>
<td>2009-08-25</td>
<td>2022-07-01</td>
</tr>
<tr>
<td><kbd>DCD05B71EAB94199527F44ACDB6B8C1F96D8BF6D</kbd></td>
<td>Gentoo ebuild repository signing key (Automated Signing Key)</td>
<td>2011-11-25</td>
<td>2022-07-01</td>
</tr>
<tr>
<td><kbd>EF9538C9E8E64311A52CDEDFA13D0EF1914E7A72</kbd></td>
<td><a rel='external' href='https://github.com/gentoo-mirror/'>Gentoo repository mirrors</a> (automated git signing key)</td>
<td>2018-05-28</td>
<td>2022-07-01</td>
</tr>
<tr>
<td><kbd>D99EAC7379A850BCE47DA5F29E6438C817072058</kbd></td>
<td>Gentoo Linux Release Engineering (Gentoo Linux Release Signing Key)</td>
<td>2004-07-20</td>
<td>2022-01-01</td>
</tr>
<tr>
<td><kbd>ABD00913019D6354BA1D9A132839FE0D796198B1</kbd></td>
<td>Gentoo Authority Key L1</td>
<td>2019-04-01</td>
<td>2022-07-01</td>
</tr>
<tr>
<td><kbd>18F703D702B1B9591373148C55D3238EC050396E</kbd></td>
<td>Gentoo Authority Key L2 for Services</td>
<td>2019-04-01</td>
<td>2022-07-01</td>
</tr>
<tr>
<td><kbd>2C13823B8237310FA213034930D132FF0FF50EEB</kbd></td>
<td>Gentoo Authority Key L2 for Developers</td>
<td>2019-04-01</td>
<td>2022-07-01</td>
</tr>
</table>
<br>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><span class="fa fa-fw fa-check-circle-o"></span> Verifying files</h3>
</div>
<div class="panel-body">
<p>To verify downloaded files are not tampered with, you need the <tt>.DIGESTS</tt> file matching your release and the matching key from the table above.</p>
<p>Fetch the key:</p>
<p><kbd>gpg --keyserver hkps://keys.gentoo.org --recv-keys &lt;key fingerprint&gt;</kbd></p>
<p>Alternatively, you can fetch a bundle containing all listed keys:</p>
<p><kbd>wget -O - https://qa-reports.gentoo.org/output/service-keys.gpg | gpg --import</kbd></p>
<p>Verify the <tt>DIGESTS</tt> file:</p>
<p><kbd>gpg --verify &lt;foo.DIGESTS.asc&gt;</kbd></p>
<p>Verify the download matches the digests. At least one of the following will exist:</p>
<p><kbd>sha512sum -c &lt;foo.DIGESTS.asc&gt;</kbd></p>
<p><kbd>sha256sum -c &lt;foo.DIGESTS.asc&gt;</kbd></p>
<p><kbd>sha1sum -c &lt;foo.DIGESTS.asc&gt;</kbd></p>
<br>
<div class="alert alert-info">
Detailed instructions are available in the <a href="https://wiki.gentoo.org/wiki/Handbook:Main_Page" class="alert-link">Gentoo Handbook</a>.
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-offset-2 col-md-7">
</div>
<div class="col-xs-12 col-md-3">
<h3 class="footerhead">Questions or comments?</h3>
Please feel free to <a href="/inside-gentoo/contact/">contact us</a>.
</div>
</div>
</div>
<div class="container-sitemap">
<div class="container">
<div class="row row-sitemap hidden-sm hidden-xs">
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/">Home</a></h3>
<ul class="sitemap">
<li class=""><a href="/news/">News</a></li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/get-started/">Get Started</a></h3>
<ul class="sitemap">
<li class=""><a href="/get-started/about/">About Gentoo</a></li>
<li class=""><a href="/get-started/philosophy/">Philosophy</a></li>
<li class=""><a href="/get-started/screenshots/">Screenshots</a></li>
<li class=""><a href="https://wiki.gentoo.org/wiki/FAQ">FAQ <span class="fa fa-fw fa-external-link-square external-link" title="This link will leave www.gentoo.org."></span></a></li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/downloads/">Downloads</a></h3>
<ul class="sitemap">
<li class=""><a href="/downloads/mirrors/">Mirrors</a></li>
<li class=""><a href="/downloads/signatures/">Signatures</a></li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/inside-gentoo/">Inside Gentoo</a></h3>
<ul class="sitemap">
<li class=""><a href="/inside-gentoo/developers/">Developers</a></li>
<li class=""><a href="https://wiki.gentoo.org/wiki/Project:Gentoo">Projects <span class="fa fa-fw fa-external-link-square external-link" title="This link will leave www.gentoo.org."></span></a></li>
<li class=""><a href="/glep/">GLEPs</a></li>
<li class=""><a href="/inside-gentoo/artwork/">Artwork</a></li>
<li class=""><a href="/inside-gentoo/foundation/">Gentoo Foundation</a></li>
<li class=""><a href="/inside-gentoo/sponsors/">Sponsors</a></li>
<li class=""><a href="/inside-gentoo/stores/">Stores</a></li>
<li class=""><a href="/inside-gentoo/contact/">Contact</a></li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/support/">Support</a></h3>
<ul class="sitemap">
<li class=""><a href="/support/consulting/">Consulting</a></li>
<li class=""><a href="/support/documentation/">Documentation</a></li>
<li class=""><a href="/support/news-items/">News items</a></li>
<li class=""><a href="https://packages.gentoo.org/">Package database <span class="fa fa-fw fa-external-link-square external-link" title="This link will leave www.gentoo.org."></span></a></li>
<li class=""><a href="/support/security/">Security</a></li>
<li class=""><a href="/support/use-flags/">USE flags</a></li>
<li class=""><a href="/support/rsync-mirrors/">rsync mirrors</a></li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-2">
<h3 class="footerhead"><a href="/get-involved/">Get Involved</a></h3>
<ul class="sitemap">
<li class=""><a href="/get-involved/irc-channels/">IRC channels</a></li>
<li class=""><a href="https://forums.gentoo.org/">Forums <span class="fa fa-fw fa-external-link-square external-link" title="This link will leave www.gentoo.org."></span></a></li>
<li class=""><a href="/get-involved/mailing-lists/">Mailing lists</a></li>
<li class=""><a href="/get-involved/contribute/">Contribute</a></li>
<li class=""><a href="/get-involved/become-developer/">Become a developer</a></li>
<li class=""><a href="/get-involved/get-code/">Get the code</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-xs-3 col-md-2">
<ul class="footerlinks three-icons">
<li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li>
<li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li>
</ul>
<div>
<div class="sitemap text-center">
<a href="https://wiki.gentoo.org/wiki/Foundation:Privacy_Policy">Privacy Policy</a>
</div>
</div>
</div>
<div class="col-xs-8 col-md-8">
<strong>&copy; 2001&ndash;2021 Gentoo Authors</strong><br>
<small>
Gentoo is a trademark of the Gentoo Foundation, Inc.
The contents of this document, unless otherwise expressly stated, are licensed under the
<a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="license">CC-BY-SA-3.0</a> license.
The <a href="/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply.
</small>
</div>
<div class="col-xs-1 col-md-1">
<strong><a class="text-dark" href="https://gitweb.gentoo.org/sites/www.git/">Version</a></strong><br>
<small>
91e01cb
</small>
</div>
</div>
</div>
</footer>
<script src="https://assets.gentoo.org/tyrian/v1/jquery.min.js"></script>
<script src="https://assets.gentoo.org/tyrian/v1/bootstrap.min.js"></script>
</body>
</html>

View file

@ -0,0 +1,10 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
# remove
prog=$( basename $0 .bash )
PREFIX=/usr/local
ROLE=base
exec bash /usr/local/bin/proxy_get_if.bash "$@"

View file

@ -0,0 +1,56 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
PREFIX=/usr/local
ROLE=base
NOW=`date +%Y-%m-%d`
NOWM=`date +%Y-%m`
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash || exit 2
[ -f /usr/local/etc/testforge/testforge.bash ] && . /usr/local/etc/testforge/testforge.bash
[ $( id -u ) -eq 0 ] || { ERROR $prog should be run as root ; exit 1 ; }
ly=hourly
errs=0
warns=0
elt=base
LOG_DIR=/usr/local/tmp
ELOG=$LOG_DIR/E${prog}_${ly}$$.log
WLOG=$LOG_DIR/W${prog}_${ly}$$.log
OUT=$LOG_DIR/O${prog}_${ly}$$.log
find $LOG_DIR/*${prog}_${ly}*.log -ctime +2 -delete
ansible-inventory 2>> $WLOG || ERROR ansible-inventory $? >> $ELOG
if ip route | grep -v ^def ; then
gpg-connect-agent --dirmngr 'keyserver --hosttable' /bye || exit 3$?
dirmngr-client -v --ping </dev/null || exit 4$?
fi
if [ $USER = root ] ; then
DBUG /var/log/auth.log
grep --text $NOW'.*\(Permission denied\|Could not\)' /var/log/auth.log
# | less -Ps"$NOW sauth.log" -Pm"$NOW sauth.log"
dmesg |grep -q martian && WARN `dmesg |grep -c martian ` Martians
fi
find /tmp -type f -empty -delete
[ -f $WLOG ] && warns=`wc -l $WLOG | cut -f 1 -d ' '`
[ $? -eq 0 -a $warns -ne 0 ] && \
WARN "$warns $ly $prog warnings in $WLOG"
[ -f $ELOG ] && errs=`wc -l $ELOG | cut -f 1 -d ' '`
[ $? -eq 0 -a $errs -ne 0 ] && \
ERROR "$errs $ly $prog errors in $ELOG" && cat $ELOG && exit $errs
[ $errs -eq 0 ] && \
ols_clean_testforge_logs $HARDEN_LOG_DIR && \
[ $warns -eq 0 ] && \
INFO "$prog No $ly errors in $HARDEN_LOG_DIR"
exit 0

View file

@ -0,0 +1,38 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
ROLE=base
# pip installs into /usr/local/bin
# export PATH=.:$PATH:/usr/local/bin
LARGS="$@"
[ "$#" -ge 2 -a $1 = "-p" -a $2 = "2" ] && PYVER=2 || PYVER=3
$PREFIX/bin/base_pip_upgrade.bash "$@" | grep -v 'INFO:\|ERROR:\|DEBUG:' | \
tee /tmp/P$$.lis | \
while read elt rest ; do
[ $PYVER = 2 ] && str="import $elt;print $elt.__file__" || \
str="import $elt;print($elt.__file__)"
$PREFIX/bin/python$PYVER.sh -c $str >/tmp/P$$.log 2>&1
if [ $? -ne 0 ] ; then
lelt=$( echo $elt | tr '[:upper:]' '[:lower:]' )
if [ "$lelt" != "$elt" ] ; then
[ $PYVER = 2 ] && str="import $lelt;print $lelt.__file__" || \
str="import $lelt;print($lelt.__file__)"
$PREFIX/bin/python$PYVER.sh -c $str >/tmp/P$$.log 2>&1 || \
{ rm -f /tmp/P$$.log ; continue ; }
fi
fi
grep /usr/lib /tmp/P$$.log && DBUG $PYVER $elt $rest && continue
grep $PREFIX /tmp/P$$.log && INFO $PYVER $elt $rest && continue
cat /tmp/P$$.log && WARN $PYVER $elt $rest && continue
done
rm -f /tmp/P$$.log
exit 0

View file

@ -0,0 +1,122 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# pip installs into /usr/local/bin
# export PATH=.:$PATH:/usr/local/bin
prog=$( basename $0 .bash )
ROLE=base
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
. /usr/local/etc/testforge/testforge.bash || exit 1
[ -d PREFIX=/var/local/var/log ] && \
BASE_LOG_DIR=/var/local/var/log || \
BASE_LOG_DIR=/tmp
pyver=3
inter=0
verbose=3
usage() {
echo "Usage: $0 [OPTIONS] dirs-or-files"
echo
echo " -i | --inter=$inter - interactivly upgrade 0 or 1 [0]"
echo " -p | --pyver=$pyver - python version - 2 or 3"
echo " -v | --verbose=$verbose - verbosity 0 least 5 most"
echo
echo " -V | --version - print version of this script"
echo " -h | --help - print this help"
}
exitWithErrMsg() {
retval=$1
shift
echo "$1" 1>&2
exit $retval
}
SHORTOPTS="hVp:v:i:"
LONGOPTS="help,version,pyver:,verbose:,inter:"
PKGS=
ARGS=$(getopt --options $SHORTOPTS --longoptions $LONGOPTS -- "$@")
[ $? != 0 ] && exitWithErrMsg 1 "Aborting."
route | grep -q ^default || exitWithErrMsg 2 "We are not connected: Aborting."
eval set -- "$ARGS"
while true; do
case "$1" in
-p|--pyver)
shift
pyver="$1"
;;
-i|--inter)
shift
inter=1
;;
-v|--verbose)
shift
verbose="$1"
;;
-h|--help)
usage
exit 0
;;
'--')
shift
PKGS="$*"
break
;;
*)
break
;;
esac
shift
done
#echo $PKGS
if [[ $pyver =~ 2.* ]] ; then
LOG_DIR=$BASE_LOG_DIR/pip/$BASE_PYTHON2_MINOR
pip_exe=/usr/local/bin/pip2.sh
else
LOG_DIR=$BASE_LOG_DIR/testforge/pip/$BASE_PYTHON3_MINOR
pip_exe=/usr/local/bin/pip3.sh
fi
cd /usr/local/bin
# --process-dependency-links
# this is missing many/most
# --format: invalid choice: 'legacy' (choose from 'columns', 'freeze', 'json')
$pip_exe list -o --format=columns --user | tee /tmp/$$.log
# pyface (Current: 4.5.2 Latest: 5.0.0 [sdist])
grep 'wheel$\|sdist$' /tmp/$$.log | while read pkg current latest rest ; do
echo "INFO: $pkg from $current to $latest "
if [ -n "$PKGS" ] ; then
echo "$PKGS" | grep -v "grep" | grep -q "$pkg" || continue
fi
# this is for the Msys distribution build from source
if [ -f ../src/$pkg.bash ] && grep VER= ../src/$pkg.bash ; then
[ -f ../src/$pkg.bash.old ] && WARN "$0 backup present $pkg.old" && continue
grep -q "^VER=\"$latest\"" ../src/$pkg.bash && \
WARN "$0 $pkg already $latest" && continue
mv ../src/$pkg.bash ../src/$pkg.bash.old
sed -e "s/VER=$current/VER=$latest/" ../src/$pkg.bash < ../src/$pkg.bash.old
echo "INFO: package $pkg "
fi
# -u 2
[ $inter -eq 0 ] && continue
read -p "READ: Upgrade $pkg from $current to $latest? " yn
[ "$yn" = "q" ] && exit
[ "$yn" = "y" ] || continue
$pip_exe $pkg $current $latest
done
rm -f /tmp/$$.log
exit 0

View file

@ -0,0 +1,61 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
ROLE=base
[ -z "$BASE_PYTHON2_MINOR" ] && \
BASE_PYTHON2_MINOR=$( python2 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$BASE_PYTHON3_MINOR" ] && \
BASE_PYTHON3_MINOR=$( python3 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
for PYTHON_MINOR in "$BASE_PYTHON2_MINOR" "$BASE_PYTHON3_MINOR" ; do
[ -z "$PYTHON_MINOR" ] && continue
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR/site-packages ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR/site-packages
fi
done
umask 0022
# [ "$#" -eq 0 ] && set -- $PREFIX/bin
# FixMe? /usr/local/bin too? I think not, except for ours?
for prefix in /usr/local /var/local ; do
cd $prefix/bin || exit 1
#? ls -1d * | grep -v '~' | xargs file | grep -i python | sed -e 's/:.*//'|while read file ; do
ls -1 | grep -v '~' | xargs file | grep script | sed -e 's/:.*//' | \
while read file ; do
head -1 $file | grep -q python || continue
head -1 $file | grep -q $prefix/python..bash && continue
base=$( echo $file | sed -e 's/\.bash$//' )
under=$( echo $prefix | sed -e 's/^.//' -e 's@/@_@g' )
if [ -h /etc/python-exec/$base.conf ] ; then
link=$( readlink /etc/python-exec/$base.conf )
if [ "$link" = python2.conf ] ; then
sed -f $prefix/share/sed/${under}_python2.sed -i $file
else
sed -f $prefix/share/sed/${under}_python3.sed -i $file
fi
else
sed -f $prefix/share/sed/${under}_python2.sed -i $file
sed -f $prefix/share/sed/${under}_python3.sed -i $file
fi
# echo $file
done
# failsafe - Eberly - no longer active
for elt in $BASE_PYTHON2_MINOR $BASE_PYTHON3_MINOR ; do
[ -f $prefix/${LIB}/python$elt/site-packages/site.py ]
# WARN missing $prefix/${LIB}/python$elt/site-packages/site.py
done
done
exit 0

View file

@ -0,0 +1,67 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
ROLE=base
PREFIX=/usr/local
. /usr/local/bin/usr_local_base.bash || exit 2
. ~/.bash_logout
# these can hang unmounting partitions
pkill dirmngr
pkill bootlogd
[ -x /var/local/bin/privacy_home_cleaner.bash ] && /var/local/bin/privacy_home_cleaner.bash
[ -f ~/Makefile ] && grep -q ^stop: ~/Makefile && \
{ cd ~ ; make stop || exit 2 ; }
local_base_umount () {
local mount
cd /mnt
mount=`mount`
for file in linux* ; do
echo $mount | grep -q " on /mnt/$file " || continue
echo /mnt/$file
umount -R /mnt/$file || exit 1
done
# not l - a b f d n u x i j k o q w e h z
for file in ? ; do
echo $mount | grep -q " on /mnt/$file " || continue
# echo /mnt/$file
umount /mnt/$file || WARN $prog error umounting /mnt/$file
done
umount -a
}
local_base_umount || exit 3
# should be 0
NUM=`losetup -a |grep -c -v home`
if [ $NUM -gt 0 ] ; then
losetup -a |grep -v home
echo losetup still mounted
exit 5
fi
sleep 10
umount -a -t ntfs-3g
# should be 1
NUM=`ps ax | grep mount.ntfs-3g | grep -v grep | wc -l`
if [ $NUM -ge 1 ] ; then
ps ax | grep mount.ntfs-3g | grep -v grep
ERROR mount.ntfs-3g still running
exit 6
fi
INFO Calling shutdown
if [ $# -lt 1 ] ; then
shutdown -r now
else
shutdown $*
fi

View file

@ -0,0 +1,32 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# very dangerous
[ "$#" -gt 0 ] && ROOT=$1 || ROOT=/
[ -d "$ROOT" ] || exit 1
ROLE=base
cd $ROOT || exit 2
GROUP=adm
[ -f /usr/local/etc/testforge/testforge.bash ] && . /usr/local/etc/testforge/testforge.bash
[ -n "$BOX_ALSO_GROUP" ] && GROUP=$BOX_ALSO_GROUP
if [ -d ${ROOT}/var/local ] ; then
# allow
chgrp -R $GROUP ${ROOT}/var/local/{bin,data,lib64,src,net}
chmod -R g+rw,o-w ${ROOT}/var/local/{bin,data,lib64,src,net}
chmod a+x ${ROOT}/var/local/{bin,src,share/bash}/*sh
# if [ -d ${ROOT}/var/local/src/lynis ] ; then
chgrp -R $GROUP ${ROOT}/var/local/{bin,data,lib64,src,net}
# forbid /var
chgrp -R root ${ROOT}/var/local/{etc,var,share}
chmod -R g-w,o-w ${ROOT}/var/local/{etc,var,share}
fi
if [ -d ${ROOT}/usr/local ] ; then
# forbid /usr but lib/python* will be created and allowed on install
chgrp -R root ${ROOT}/usr/local/
chmod -R g-w,o-rw ${ROOT}/usr/local/
fi
exit 0

View file

@ -0,0 +1,56 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
exit 0
ROLE=base
usage="
Usage:
wall [options] [message]
Write a message to all users.
Options:
-n, --nobanner do not print banner
-h, --help display this help and exit
"
SHORT=nh
LONG=nobanner,help
PARSED=$(getopt --options $SHORT --longoptions $LONG --name "$0" -- "$@")
if [[ $? -ne 0 ]]; then
echo "$usage"
exit 2
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-n|--nobanner)
n=y
shift
;;
-h|--help)
echo "$usage"
exit 0
;;
--)
shift
break
;;
*)
exit 3
;;
esac
done
ps -ef | grep " pts/" | awk '{print $6}' | sort -u > /tmp/terminals_$$.tmp
ps -ef | grep " tty" | awk '{print $6}' | sort -u | grep -v "pts" >> /tmp/terminals_$$.tmp
if [ "$n" ]; then
pre=""
post=""
else
pre="-e \nBroadcast message from $(whoami)@$(hostname) ($(ps ax | grep "^$$" | awk '{ print $2 }')) ($(date +"%a %b %d %H:%M:%S %Y")):\n\n"
post='\n'
fi
cat /tmp/terminals_$$.tmp | while read TTY_TO; do echo $pre"$*"$post | sudo tee /dev/$TTY_TO 1>/dev/null; done
rm /tmp/terminals_$$.tmp

View file

@ -0,0 +1,9 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# filter
ROLE=base
# extra cleanups to bash from yaml_to_bash
sed -e '/\[/s@, @ @g' \
-e '/\[/s@\([^"]\)u"@\1"@g' -e "/\[/s@\([^']\)u'@\1'@g" \
-e 's@="*\[\(.*\)\]@=(\1)@' -e "s@='*\[\(.*\)\]@=(\1)@"

View file

@ -0,0 +1,29 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
# N.B.: creates /usr/local/etc/testforge/testforge.bash
# filter or program
# should be -f VAR_LOCAL/share/sed/fact_to_bash.sed
# but /usr/local/etc/testforge/testforge.bash isnt created yet
ROLE=base
# wierd: doesnt work on Ubuntu - grep -F -e '=' $* | sed -e 's@^ *@@' | eval
grep '=' $* | sed \
-e "s@u*'@@g" \
-e 's@^ *@@' \
-e 's@\[@"@' \
-e 's@\]@"@' \
-e 's@, @ @g' \
> /tmp/$$.bash
. /tmp/$$.bash
IFS='\t' sed -e 's/=/\t/' -e 's/"//g' /tmp/$$.bash |sort -u | while read key val ; do
# why filter these out?
# echo $key | grep -q 'SOCKS_PROXY\|NO_PROXY\|HTTP_PROXY\|HTTPS_PROXY\|GIT_' && continue
echo "export $key=\"$val\""
done
# rm /tmp/$$.bash

View file

@ -0,0 +1,8 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
ROLE=base
# filter or program
grep '=' "$*" \
| sed -e "s@=@: @" -e "s@^ *@@"

View file

@ -0,0 +1,108 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
shopt -s nullglob || { ERROR use bash ; exit 1 ; }
. /usr/local/bin/usr_local_tput.bash || exit 2
. /usr/local/bin/usr_local_base.bash || exit 3
ROLE=base
PREFIX=/usr/local
[ -z "$PYVER" ] && PYVER=3
declare -a TARGET
if [ -f /usr/local/etc/testforge/testforge.bash ] ; then
. /usr/local/etc/testforge/testforge.bash >/dev/null || exit 1
P="BASE_PYTHON${PYVER}_MINOR"
PYTHON_MINOR="$(eval echo \$$P)"
fi
[ -n "$PYTHON_MINOR" ] || \
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$LIB" -a -d $PREFIX/lib/python$PYTHON_MINOR/site-packages ] && LIB=lib
[ -z "$LIB" -a -d $PREFIX/lib64/python$PYTHON_MINOR/site-packages ] && LIB=lib64
if [ "$#" -eq 0 ] || [[ "$*" =~ "--version" ]] || [[ "$*" =~ "--help" ]] ; then
$PREFIX/bin/python$PYVER.sh -m pip "$@"
exit $?
elif [ "$1" = 'html' ] ; then
wget -c -O - https://pypi.org/project/$2 2>/dev/null
exit $?
elif [ "$1" = 'lynx' ] ; then
lynx https://pypi.org/project/$2
exit $?
elif [ "$1" = 'elinks' ] ; then
elinks https://pypi.org/project/$2
exit $?
fi
if [ -x $PREFIX/bin/base_check_site_py.bash ] ; then
$PREFIX/bin/base_check_site_py.bash $PYTHON_MINOR >/dev/null || exit $?
fi
if [ -n "$PYTHONPATH" ] && [ -x $PREFIX/bin/base_clean_pythonpath.bash ] ; then
PYTHONPATH="$( $PREFIX/bin/base_clean_pythonpath.bash $PYTHON_MINOR $PYTHONPATH )"
fi
# could from pip import download;print(download.__file__)
file=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages/pip/download.py
if [ -f $file ] && grep -q 'if not check_path_owner' $file ; then
mv $file $file.dst
sed -e 's/if not check_path_owner/if False and not check_path_owner/' \
> $file $file.dst
fi
#DBUG $prog PYTHON_MINOR=$PYTHON_MINOR PYTHONPATH=$PYTHONPATH
LARGS="$BASE_PIP_GLOBAL_ARGS" # --no-python-version-warning
if [ -f /usr/local/etc/ssl/cacert-testforge.pem ] ; then
[[ "$*" =~ "--cert" ]] || [[ $LARGS =~ "--cert" ]] || LARGS="--cert $PREFIX/etc/ssl/cacert-testforge.pem $LARGS"
fi
if [ -e $PREFIX/net/Cache/Pip ] ; then
[[ "$*" =~ "--cache-dir" ]] || [[ $LARGS =~ "--cache-dir" ]] || LARGS="--cache-dir $PREFIX/net/Cache/Pip $LARGS"
fi
[[ "$*" =~ "--timeout" ]] || [[ $LARGS =~ "--timeout" ]] || LARGS="--timeout=30 $LARGS"
[[ "$*" =~ '--disable-pip-version-check' ]] || LARGS="--disable-pip-version-check $LARGS"
[[ "$*" =~ '--proxy' ]] || LARGS="$LARGS --proxy http://localhost:3128"
MYID=$( id -u )
if [ "$1" = 'uninstall' ] ; then
[ $MYID -eq 0 ] && ERROR $prog should not be run as root $MYID && exit 2
elif [ "$1" = 'install' ] ; then
[ $MYID -eq 0 ] && ERROR $prog should not be run as root $MYID && exit 2
shift
RARGS="$RARGS --progress-bar=off"
# LARGS="$LARGS --python=/usr/local/bin/python$PYTHON_MINOR.sh"
/usr/local/bin/proxy_ping_test.bash wifi # || exit 3$?
# Can not combine '--user' and '--prefix'
if true ; then # >9.0.1
if [[ $RARGS =~ "--prefix=$PREFIX" ]] ; then
:
else
[ $MYID -eq 0 ] && ERROR $prog should not be run as root $MYID && exit 2
RARGS=" --prefix=$PREFIX $RARGS"
fi
else
# this is required, with the ~/.local symlinks, or it tries to uninstall from the system
[[ $RARGS =~ " --user" ]] || RARGS=" --user $RARGS"
# no quotes around the --install-option arg
[[ $RARGS =~ "--install-scripts" ]] || RARGS=" --install-option=--install-scripts=/usr/local/bin $RARGS"
[[ $RARGS =~ "--install-lib" ]] || RARGS=" --install-option=--install-lib=/usr/local/$LIB/python$PYTHON_MINOR/site-packages $RARGS"
fi
# if [ -d /etc/apt ] ; then # ! uname -a | grep Debian ||
# [[ $RARGS =~ "--install-layout" ]] || RARGS=" --install-option=--install-layout=unix $RARGS"
# fi
#? [[ $RARGS =~ "--no-binary" ]] || RARGS="--no-binary :all: $RARGS"
# this prohibits installing .egg dirs but maybe that means no multi-version
[[ $RARGS =~ "--only-binary" ]] || RARGS="--only-binary :none: $RARGS"
! $PREFIX/bin/python$PYVER.sh -m pip --help | grep -q upgrade-strategy || \
[[ $RARGS =~ "--upgrade-strategy" ]] || RARGS="--upgrade-strategy only-if-needed $RARGS"
# require explicit package-by package installing - ? maybe only from ansible?
RARGS="install $RARGS"
export PYTHONPATH=/usr/local/$LIB/python$PYTHON_MINOR/site-packages
fi
TARGET=("$@")
echo DBUG $prog $LARGS $RARGS "$@"
exec $PREFIX/bin/python$PYVER.sh -W ignore::UserWarning -m pip $LARGS $RARGS "$@" 2>&1

View file

@ -0,0 +1,8 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
shopt -s nullglob || { ERROR use bash ; exit 1 ; }
ROLE=base
export PYVER=2
exec /usr/local/bin/pip.sh "$@"

View file

@ -0,0 +1,108 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
. /usr/local/bin/usr_local_tput.bash || exit 2
. /usr/local/bin/usr_local_base.bash || exit 3
shopt -s nullglob || { ERROR use bash ; exit 1 ; }
ROLE=base
PREFIX=/usr/local
PYVER=3
declare -a TARGET
if [ -f /usr/local/etc/testforge/testforge.bash ] ; then
. /usr/local/etc/testforge/testforge.bash >/dev/null || exit 1
P="BASE_PYTHON${PYVER}_MINOR"
PYTHON_MINOR="$(eval echo \$$P)"
fi
[ -n "$PYTHON_MINOR" ] || \
PYTHON_MINOR=$( python3.10 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
PYTHON_MINOR=3.11
[ -z "$LIB" -a -d $PREFIX/lib/python$PYTHON_MINOR/site-packages ] && LIB=lib
[ -z "$LIB" -a -d $PREFIX/lib64/python$PYTHON_MINOR/site-packages ] && LIB=lib64
if [ "$#" -eq 0 ] || [[ "$*" =~ "--version" ]] || [[ "$*" =~ "--help" ]] ; then
$PREFIX/bin/python$PYVER.sh -m pip "$@"
exit $?
elif [ "$1" = 'html' ] ; then
wget -c -O - https://pypi.org/project/$2 2>/dev/null
exit $?
elif [ "$1" = 'lynx' ] ; then
lynx https://pypi.org/project/$2
exit $?
elif [ "$1" = 'elinks' ] ; then
elinks https://pypi.org/project/$2
exit $?
fi
if [ -x $PREFIX/bin/base_check_site_py.bash ] ; then
$PREFIX/bin/base_check_site_py.bash $PYTHON_MINOR >/dev/null || exit $?
fi
if [ -n "$PYTHONPATH" ] && [ -x $PREFIX/bin/base_clean_pythonpath.bash ] ; then
PYTHONPATH="$( $PREFIX/bin/base_clean_pythonpath.bash $PYTHON_MINOR $PYTHONPATH )"
fi
# could from pip import download;print(download.__file__)
file=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages/pip/download.py
if [ -f $file ] && grep -q 'if not check_path_owner' $file ; then
mv $file $file.dst
sed -e 's/if not check_path_owner/if False and not check_path_owner/' \
> $file $file.dst
fi
#DBUG $prog PYTHON_MINOR=$PYTHON_MINOR PYTHONPATH=$PYTHONPATH
LARGS="$BASE_PIP_GLOBAL_ARGS" # --no-python-version-warning
if [ -f /usr/local/etc/ssl/cacert-testforge.pem ] ; then
[[ "$*" =~ "--cert" ]] || [[ $LARGS =~ "--cert" ]] || LARGS="--cert $PREFIX/etc/ssl/cacert-testforge.pem $LARGS"
fi
if [ -e $PREFIX/net/Cache/Pip ] ; then
[[ "$*" =~ "--cache-dir" ]] || [[ $LARGS =~ "--cache-dir" ]] || LARGS="--cache-dir $PREFIX/net/Cache/Pip $LARGS"
fi
[[ "$*" =~ "--timeout" ]] || [[ $LARGS =~ "--timeout" ]] || LARGS="--timeout=30 $LARGS"
[[ "$*" =~ '--disable-pip-version-check' ]] || LARGS="--disable-pip-version-check $LARGS"
[[ "$*" =~ '--proxy' ]] || LARGS="$LARGS --proxy localhost:3128"
MYID=$( id -u )
if [ "$1" = 'uninstall' ] ; then
[ $MYID -eq 0 ] && ERROR $prog should not be run as root $MYID && exit 2
elif [ "$1" = 'install' ] ; then
shift
/usr/local/bin/proxy_ping_test.bash wifi # || exit 3$?
RARGS="$BASE_PIP_INSTALL_ARGS"
# Can not combine '--user' and '--prefix'
if true ; then # >9.0.1
if [[ $RARGS =~ "--prefix=$PREFIX" ]] ; then
:
else
[ $MYID -eq 0 ] && ERROR $prog should not be run as root $MYID && exit 2
RARGS=" --prefix=$PREFIX $RARGS"
fi
else
# this is required, with the ~/.local symlinks, or it tries to uninstall from the system
[[ $RARGS =~ " --user" ]] || RARGS=" --user $RARGS"
# no quotes around the --install-option arg
[[ $RARGS =~ "--install-scripts" ]] || RARGS=" --install-option=--install-scripts=/usr/local/bin $RARGS"
[[ $RARGS =~ "--install-lib" ]] || RARGS=" --install-option=--install-lib=/usr/local/$LIB/python$PYTHON_MINOR/site-packages $RARGS"
fi
# if [ -d /etc/apt ] ; then # ! uname -a | grep Debian ||
# [[ $RARGS =~ "--install-layout" ]] || RARGS=" --install-option=--install-layout=unix $RARGS"
# fi
#? [[ $RARGS =~ "--no-binary" ]] || RARGS="--no-binary :all: $RARGS"
# this prohibits installing .egg dirs but maybe that means no multi-version
[[ $RARGS =~ "--only-binary" ]] || RARGS="--only-binary :none: $RARGS"
! $PREFIX/bin/python$PYVER.sh -m pip --help | grep -q upgrade-strategy || \
[[ $RARGS =~ "--upgrade-strategy" ]] || RARGS="--upgrade-strategy only-if-needed $RARGS"
# require explicit package-by package installing - ? maybe only from ansible?
RARGS="install $RARGS"
export PYTHONPATH=/usr/local/$LIB/python$PYTHON_MINOR/site-packages
fi
TARGET=("$@")
echo DBUG $prog $LARGS $RARGS "$@"
exec $PREFIX/bin/python$PYVER.sh -W ignore::UserWarning -m pip $LARGS $RARGS "$@" 2>&1

View file

@ -0,0 +1,8 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
shopt -s nullglob || { ERROR use bash ; exit 1 ; }
ROLE=base
export PYVER=3
exec /usr/local/bin/pip.sh "$@"

View file

@ -0,0 +1,974 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
ROLE=proxy
PYVER=3
# DEBUG=1
. /usr/local/bin/proxy_ping_lib.bash || \
{ ERROR loading /usr/local/bin/proxy_ping_lib.bash ; exit 6; }
PL=/usr/local/bin/proxy_libvirt_lib.bash
declare -a tests
which traceroute 2>/dev/null >/dev/null && HAVE_TRACEROUTE=1 || HAVE_TRACEROUTE=0
which dig 2>/dev/null >/dev/null && HAVE_DIG=1 || HAVE_DIG=0
which nslookup 2>/dev/null >/dev/null && HAVE_NSLOOKUP=1 || HAVE_NSLOOKUP=0
which tor-resolve 2>/dev/null >/dev/null && HAVE_TOR_RESOLVE=1 || HAVE_TOR_RESOLVE=0
[ -z "$prog" ] || prog=proxy_ping_test
proxy_ping_get_socks
[ -z "$SOCKS_HOST" ] && SOCKS_HOST=127.0.0.1
[ -z "$SOCKS_PORT" ] && SOCKS_PORT=9050
[ -z "$SOCKS_DNS" ] && SOCKS_DNS=9053
HTTPS_PORT=9128
HTTPS_HOST=127.0.0.1
proxy_ping_get_https
[ -z "$HTTPS_HOST" ] && HTTPS_HOST=127.0.0.1
HTTP_PORT=3128
HTTP_PROXY_HOST=127.0.0.1
proxy_ping_get_http
[ -z "$HTTP_HOST" ] && HTTP_HOST=127.0.0.1
[ -f $PREFIX/etc/testforge/testforge.bash ] && \
. /usr/local/etc/testforge/testforge.bash >/dev/null || exit 1
P="BASE_PYTHON${PYVER}_MINOR"
PYTHON_MINOR="$(eval echo \$$P)"
[ -n "$PYTHON_MINOR" ] || \
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -n "$PYTHON_MINOR" ] || exit 4
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR ] ; then
#? ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR
exit 5
fi
THOPS=40
NEEDED_BINS="ping traceroute nmap dig nslookup tor-resolve"
NEEDED_SCRIPTS="
/usr/local/bin/proxy_ping_lib.bash
/usr/local/bin/proxy_ping_test.bash
"
grep -q Debian /etc/os-release
DEBIAN=$?
TIMEOUT=30
[ -n "$GATEW_DOM" ] || GATEW_DOM="$( proxy_testforge_get_gateway_dom )"
[ -n "$GATEW_DOM" ] || GATEW_DOM="Whonix-Gateway"
DNS_HOST1="208.67.220.220"
DNS_HOST2="8.8.8.8"ggggg
[ -n "$DNS_TARGET" ] || DNS_TARGET=www.whatismypublicip.com # 108.160.151.39
[ -n "$HTTP_TARGET" ] || HTTP_TARGET=www.whatismypublicip.com # 108.160.151.39
HTTP_TARGET=www.whatismypublicip.com
# time.nist.gov 132.163.97.3
NTP_HOST1=132.163.97.3
# pool.ntp.org 78.46.53.2
NTP_HOST2=78.46.53.2
# --no-check-certificate
WGET="wget --tries=1 --max-redirect=0 --timeout=$TIMEOUT -O /dev/null"
CURL="curl -o /dev/null $CURL_ARGS"
SCURL="/usr/local/bin/scurl.bash --output /dev/null"
NSL='nslookup -querytype=A -debug'
NETS='netstat -nl4e'
ALL=""
[ -z "$USER" ] && USER=$(id -un )
[ $USER = root ] && DMESG_LINES=1 || DMESG_LINES=0
[ -n "$PROXY_WLAN" ] || PROXY_WLAN=`proxy_ping_get_wlan`
# fixme - required
PROXY_WLAN=$( echo $PROXY_WLAN | grep ^wlan |sed -e 's/:.*//' )
[ -n "$PROXY_WLAN_GW" ] || PROXY_WLAN_GW=`proxy_ping_get_wlan_gw`
# fixme - required
PROXY_WLAN_GW=$( echo $PROXY_WLAN_GW | grep ^wlan |sed -e 's/:.*//' )
MODE=$( proxy_ping_mode )
USAGE="$prog without arguments tests the current MODE=$MODE,
or 0 to list the tests by number,
or one or more of the groups:
"
DNS_HOST=$SOCKS_HOST
[ -z "$PRIV_BIN_OWNER" ] && PRIV_BIN_OWNER=bin
[ -z "$PRIV_BIN_GID" ] && PRIV_BIN_GID=$( grep ^$PRIV_BIN_OWNER /etc/passwd|cut -d: -f 4 )
## proxy_test_netstat_dns
proxy_test_netstat_dns () { DBUG proxy_test_netstat_dns $* ;
$NETS | grep -q ":53"
retval=$?
[ $retval -eq 0 ] && return 0
ERROR $prog test=$ARG "${tests[$ARG]}" dns not running
[ -z "$ALL" ] && exit $ARG$retval || return 1
}
## proxy_test_traceroute_icmp_gw
proxy_test_traceroute_icmp_gw () { DBUG proxy_test_traceroute_icmp_gw $* ;
[ -n "$PROXY_WLAN_GW" ] || PROXY_WLAN_GW=`proxy_ping_get_wlan_gw` || return 1
traceroute --icmp $PROXY_WLAN_GW
retval=$?
[ $retval -eq 0 ] && return 0
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval traceroute --icmp $PROXY_WLAN_GW
[ -z "$ALL" ] && exit $ARG$retval || return 1
# works
GREP="-i icmp"
return 0
}
## proxy_test_dig_direct
proxy_test_dig_direct () { DBUG proxy_test_dig_direct $* ;
dig @$DNS_HOST1 pool.ntp.org +timeout=$TIMEOUT >/dev/null
retval=$?
[ $retval -eq 0 ] && return 0
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval dig @$DNS_HOST1
[ -z "$ALL" ] && exit $ARG$retval || return 1
INFO $prog test=$ARG "${tests[$ARG]}" dig @$DNS_HOST1
# works
GREP="53"
return 0
}
## proxy_test_curl_firewall_bin
proxy_test_curl_firewall_bin () { DBUG proxy_test_curl_firewall_bin $* ;
su -c "$CURL -k --noproxy '*' https://$HTTP_TARGET" -s /bin/sh $PRIV_BIN_OWNER >/dev/null
retval=$?
[ $retval -eq 0 ] && return 0
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval \
su -c "$CURL -k --noproxy '*' https://$HTTP_TARGET" -s /bin/sh $PRIV_BIN_OWNER
proxy_iptables_save|tail|grep PTABLES_filter_DROP-o
[ -z "$ALL" ] && exit $ARG$retval || return $retval
}
## proxy_ping_curl
proxy_ping_curl () { DBUG proxy_ping_curl $* ;
local retval
timeout -k $TIMEOUT $TIMEOUT $CURL "$@"
retval=$?
# "DEBUG: wierd failure curl: (35) Encountered end of file"
[ $retval -eq 0 -o $retval -eq 35 ] && return 0
return $retval
}
## proxy_ping_make_help
proxy_ping_make_help () {
grep 'tests\[[0-9][0-9]*\]=' /usr/local/bin/proxy_ping_test.bash \
> /tmp/proxy_ping_test.hlp
return 0
}
## proxy_ping_test_virbr
proxy_ping_test_virbr () {
local n=$1
[ -z "$n" ] && n=1
[ -z "$CONN" ] || proxy_whonix_get_conn
[ "$CONN" = guest ] && return 0
[ -e /proc/sys/net/ipv4/conf/virbr$n ] || return 0
proxy_ifconfig virbr$n >/dev/null && return 0
return 0
}
## proxy_ping_broken
proxy_ping_broken () { DBUG proxy_ping_broken PROXY_WLAN=$PROXY_WLAN $* ;
# 0 is true
local a=$MODE
if [ "$a" = vda -o "$a" = ws ]; then
# grep 10.152.152.10 /etc/resolv.conf &&
PING_BROKEN=0
return 0
elif [ "$a" = gateway ]; then
PING_BROKEN=0
return 0
elif [ -z "$PROXY_WLAN_GW" ] ; then
PING_BROKEN=0
return 0
fi
[ -n "$PING_BROKEN" ] && return $PING_BROKEN
DBUG $prog proxy_ping_mode=$a PROXY_WLAN=$PROXY_WLAN PROXY_WLAN_GW=$PROXY_WLAN_GW
ping -4 -I $PROXY_WLAN -c 1 -W $TIMEOUT $PROXY_WLAN_GW # 10.16.238.1
if [ $? -ne 0 ] ; then
PING_BROKEN=0
else
PING_BROKEN=1
fi
return $PING_BROKEN
}
## proxy_do_ping
proxy_do_ping () { DBUG proxy_do_ping $* ;
proxy_route_check || { ERROR $prog route not connected ; return 1$? ; }
proxy_ping_broken && return 0
[ -n "$PROXY_WLAN" ] || PROXY_WLAN=`proxy_get_if` || {
ERROR $prog unable to get wlan $? ; return 2 ;
}
ping -4 -I $PROXY_WLAN -c 1 -W $TIMEOUT $DNS_HOST2 >/tmp/P$$.log 2>&1
retval=$?
if [ $retval -eq 1 ] ; then
# false negatives
sleep 4
ping -4 -I $PROXY_WLAN -c 1 -W $TIMEOUT $DNS_HOST2 >/tmp/P$$.log 2>&1
retval=$?
fi
[ $retval -lt 1 ] || {
ERROR $prog do_ping $PROXY_WLAN retval=$retval
rm /tmp/P$$.log
PING_BROKEN=0
return 3$retval
}
grep -q ' 0% ' /tmp/P$$.log || \
{ ERROR $prog retval=$? test=$1 ping retval=$retval ; rm /tmp/P$$.log ; return 4 ; }
PING=1
grep 'packet\|bytes from' /tmp/P$$.log
rm /tmp/P$$.log
return 0
}
proxy_run_as_root () { DBUG proxy_run_as_root $* ;
[ $( id -u ) -eq 0 ] && return 0
ERROR must be root
[ -z "$ALL" ] && exit 9
return 1
}
## proxy_test_pretests
proxy_test_pretests () {
if [ "$1" = panic ] ; then
: dont ping on panic
proxy_ping_broken || proxy_do_ping || \
{ WARN ping failed for panic so skipping ; exit 0 ; }
elif [ "$1" = direct -o "$1" = gateway -o "$1" = vda -o "$1" = kick ] ; then
proxy_route_test || { ERROR $prog route not connected ; exit 1$? ; }
proxy_ping_broken || proxy_do_ping || exit 3$?
proxy_ping_test_resolv $MODE ||\
{ WARN $prog proxy_ping_test_resolv=$? 'echo nameserver 127.0.0.1 > /etc/resolv.conf' ; exit 4 ; }
proxy_ping_firewall_start || { ERROR "proxy_ping_firewall_start ret=$?" ; exit 5 ; }
elif [ "$1" = nat ] ; then
proxy_route_test || { ERROR $prog route not connected ; exit 1$? ; }
else
proxy_do_ping || exit 4$?
proxy_ping_test_resolv $MODE || \
{ WARN "$prog proxy_ping_test_resolv=$? /etc/resolv.conf.$dire" MODE=$MODE
exit 4 ; }
fi
return 0
}
## proxy_test_help_args
proxy_test_help_args () {
declare -a ret=()
ret=( $(grep " -.* $1 " /tmp/proxy_ping_test.hlp | \
sed -e 's/.=.*//' -e 's/.*tests.//') )
echo "${ret[@]}"
return 0
}
ALL=0
## proxy_ping_test_set_args
proxy_ping_test_set_args () {
local args="$@"
local val="$@"
declare -a aret=()
rm -f /tmp/proxy_ping_test.hlp
[ -f /tmp/proxy_ping_test.hlp ] || proxy_ping_make_help
## to_tor - tor with the firewall host side client setup tor server - call tor,dns,ntp in addition
[ "$1" = to_tor -o "$1" = test_tor -o "$1" = test_to ] &&
aret=( 6 13 16 ) && \
! proxy_ping_test_env && WARN to_tor and no proxy in env - use noenv
## vda - through the Gateway with the firewall - also polipo,panic - uses env
[ "$1" = vda ] &&
aret=( 35 3 20 ) #
## tor - tor with the firewall to test the host side tor server - call to_tor,dns,ntp in addition
[ "$1" = tor ] &&
aret=( 21 30 20 4 5 36 3 )
## kick - open firewall with tor running - call dns,polipo +tor in addition
[ "$1" = kick -o "$1" = host ] &&
aret=( 24 31 13 16 6 )# 30 24 31 6 13 16
## gateway - on the Gateway, trans firewall with tor running - call dns in addition
[ "$1" = gateway ] &&
aret=( 23 25 4 5 30 24 17 3 21 ) # 31 6 16
# aliases
[ "$1" = "$SOCKS_PORT" ] && set -- socks
[ "$1" = "$HTTP_PORT" ] && set -- http
[ "$1" = "$HTTPS_PORT" ] && set -- https
[ "$1" = "53" ] && set -- dns
[ "$1" = "9053" ] && set -- tordns
[ "$1" = scan ] && set -- iwlist
[ "$1" = panic ] && set -- firewall
[ "$1" = tor ] && set -- torhost
[ "$1" = to_gateway ] && set -- whonix
[ "$1" = from_tor ] && set -- whonix
[ "$1" = from_gateway ] && set -- gateway
[ "$1" = traceroute ] && set -- = trace
[ "$1" = connected ] && set -- wifi
[ "$1" = clear ] && set -- direct
# scenarios - modes: nat selektor
## nat - through the Gateway via the nat
[ "$1" = nat ] && \
set -- ping dns socks http https tordns firefail libvirtguest
# wifi?
[ "$1" = whonix ] && \
set -- ping tordns dns socks http https torhost tordns firefail gw
[ "$1" = tor ] && \
set -- ping tordns dns trace socks http https torhost tordns firefail nmap gw
[ "$1" = selektor ] && \
set -- ping tordns dns trace socks http https torhost tordns firefail nmap gw
[ "$1" = direct -o "$1" = '' ] && \
set -- ping dns trace nmap gw
## all - all tests not stopping on the first error
[ "$1" = all ] && ALL=1
# aret="${#tests[@]}"
## gw - test if we are connected to the gateway
## torhost - running tor with the firewall
## env - from the cmdline with a properly setup env
## firefail - test the proxy without env vars to expect failure
## http - assumes torhost or whonix and env setup
## https - assumes torhost or whonix and env setup
## socks - assumes torhost or whonix and env setup
## ping - connected routed test the ping to DNS hosts
## ntp - ntpdate through the firewall
## nmap - nmap sgid through the firewall - does not assume env
## iwlist - wlan scan
## firewall - test that the firewall blocks
## virbr1 - assumes tor or whonix
## gateway - ssh to the whonix gateway
## trace - traceroute to DNSHOST - icmp is allowed by the firewall, except on vda
## wifi - test if we are connected - call scan in addition
## libvirthost - hosting a libvirt container
## libvirtguest - in a libvirt container
## tordns - test 9053 for dns using tor-resolve
## dns - dns using tor or the gateway, with the firewall - does not assume env
## whonix - whonix to the Gateway with the firewall - also panic - not assume env
## whonix - whonix gateway host side client setup with the firewall was from_to## direct - assume no firewall and no proxy - but may work depend on env
r
for elt in "$@" ; do
if [ "$elt" = gw -o "$elt" = '' -o "$elt" = env -o \
"$elt" = https -o "$elt" = http -o "$elt" = socks -o "$elt" = dns -o \
"$elt" = torhost -o "$elt" = tordns -o "$elt" = whonix -o \
"$elt" = libvirthost -o "$elt" = libvirtguest -o "$elt" = virbr1 -o \
"$elt" = ping -o "$elt" = trace -o "$elt" = ntp -o "$elt" = nmap -o \
"$elt" = iwlist -o "$elt" = firefail -o "$elt" = direct -o \
"$elt" = trace -o "$elt" = wifi -o "$elt" = '' -o "$elt" = '' \
] ; then
aret+=( `proxy_test_help_args $elt` )
else
WARN unrecognized: $elt >&2
fi
done
DBUG "${aret[@]}" >&2
echo "${aret[@]}"
return 0
}
# -I $PROXY_WLAN -c 1 $DNS_HOST2
if [ "$#" = 0 ] ; then
# default to mode
set -- $MODE
fi
if [ $1 = '-h' -o $1 = '--help' ] ; then
echo USAGE: $USAGE | sed -e 's/[0-9][0-9]*)/\n&/g'
grep '^## [a-oq-z]' $0 | sed -e 's/^## / /'
exit 0
elif [ "$1" = 0 ] ; then
INFO $prog PROXY_WLAN=$PROXY_WLAN MODE=$MODE
echo 0 help /tmp/proxy_ping_test.hlp
[ -f /tmp/proxy_ping_test.hlp ] || proxy_ping_make_help
. /tmp/proxy_ping_test.hlp
for elt in "${!tests[@]}" ; do
echo $elt "${tests[$elt]}"
done
exit 0
elif [[ $1 =~ ^[0-9] ]] ; then
: passthrough
else
set -- `proxy_ping_test_set_args "$@"`
DBUG running tests numbered "$@"
fi
proxy_route_test || { ERROR $prog route not connected ; exit 1$? ; }
proxy_test_pretests "$1"
# https://stackoverflow.com/questions/8290046/icmp-sockets-linux/20105379#20105379
if [ $( id -u ) -eq 0 ] ; then
proxy_ping_chattr
fi
DBUG $prog PROXY_WLAN=$PROXY_WLAN MODE=$MODE $*
# $( sysctl net.ipv4.ping_group_range )
# proxy_iptables_save|grep 216
while [ "$#" -gt 0 ] ; do
# DBUG $prog $1
ARG=$1 ; shift
GREP=""
if [ -z "$ARG" ] ; then
continue
elif ! [ "$ARG" -ge 0 ] ; then
ERROR $prog called with an unrecognized argument $ARG from $0
exit 9
elif [ $ARG -le 0 ] ; then
# do the ping and resov.conf
true
elif [ $ARG -eq 1 ] ; then
tests[1]="wget_https_as_user wget ${HTTPS_PORT} - https "
[ -n "$https_proxy" ] && LARGS="" || \
LARGS="env https_proxy=https://${HTTPS_HOST}:${HTTPS_PORT}"
$LARGS $WGET https://$HTTP_TARGET
retval=$?
if [ $retval -eq 8 -o $retval -eq 0 ] ; then
INFO $prog test=$ARG "${tests[$ARG]}"
else
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval test=$ARG
[ -z "$ALL" ] && continue
fi
# works with fix
GREP="${HTTPS_PORT}"
elif [ $ARG -eq 2 ] ; then
[ -n "$https_proxy" ] && LARGS="--proxy $https_proxy" || \
LARGS="--proxy https://${HTTPS_HOST}:${HTTPS_PORT}"
tests[2]="curl_https_as_user curl $LARGS https://$HTTP_TARGET - https "
proxy_ping_curl $LARGS https://$HTTP_TARGET >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl $LARGS https://$HTTP_TARGET
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works with fix
GREP="${HTTPS_PORT}"
elif [ $ARG -eq 3 ] ; then
tests[3]="curl_socks_virbr1_as_user $SOCKS_HOST $SOCKS_PORT - torhost "
# proxy_dest_port_wlan_config || { ERROR DEST=$DEST ; continue ; }
# curl: (4) A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision
[ $DEBIAN -eq 0 ] && continue
[ -z "$socks_proxy" ] && socks_proxy=socks5h://${SOCKS_HOST}:$SOCKS_PORT
if [ $MODE = whonix ] ; then
ssh -o ForwardX11=no user@10.0.2.15 netstat -nl4e| grep 15:$SOCKS_PORT || {
retval=$?
ERROR ssh -o ForwardX11=no user@10.0.2.15 netstat
[ -z "$ALL" ] && exit $ARG$retval || continue ;
}
socks_proxy=socks5h://${SOCKS_HOST}:$SOCKS_PORT
proxy_ping_curl -x $socks_proxy \
--interface virbr1 n--dns-interface virbr1 https://$HTTP_TARGET >/dev/null || {
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl -x $socks_proxy --interface virbr1 --dns-interface virbr1 https://$HTTP_TARGET
[ -z "$ALL" ] && exit $ARG$retval || continue
}
else
socks_proxy=socks5h://${SOCKS_HOST}:$SOCKS_PORT
proxy_ping_curl -x $socks_proxy https://$HTTP_TARGET >/dev/null \
|| { retval=$? ; ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl ${SOCKS_HOST} $SOCKS_PORT
[ -z "$ALL" ] && exit $ARG$retval || continue ; }
fi
INFO $prog test=$ARG "${tests[$ARG]}"
# works with user/pass
GREP="$SOCKS_PORT"
elif [ $ARG -eq 4 ] ; then
tests[4]="dig_socks_through_as_user @${SOCKS_HOST} -p $SOCKS_DNS www.whatismypublicip.com - tordns "
[ $HAVE_DIG = 1 ] || continue
if [ $MODE = whonix ] ; then
ssh -o ForwardX11=no user@10.0.2.15 netstat -nl4e | grep 15:$SOCKS_DNS
fi
dig @${SOCKS_HOST} -p $SOCKS_DNS www.whatismypublicip.com +timeout=$TIMEOUT >/dev/null || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval dig @${SOCKS_HOST} -p $SOCKS_DNS www.whatismypublicip.com
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works with fix
GREP="$SOCKS_DNS"
elif [ $ARG -eq 5 ] ; then
tests[5]="nslookup_socks_as_user - tordns "
[ $HAVE_NSLOOKUP = 1 ] || continue
desc="$NSL -port=$SOCKS_DNS www.whatismypublicip.com ${DNS_HOST}"
$desc >/dev/null || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval $desc
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}" $desc
# works with fix
GREP="$SOCKS_DNS"
elif [ $ARG -eq 6 ] ; then
proxy=`proxy_ping_get_https`
desc="curl --proxy http://${proxy}"
tests[6]="curl_https_as_user - https "
proxy_ping_curl --proxy http://${proxy} \
--proxy-insecure https://$HTTP_TARGET || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval $desc
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}" $desc
# works
GREP="$HTTP_PORT"
elif [ $ARG -eq 7 ] ; then
tests[8]="traceroute_icmp_dns_as_root --icmp - trace "
[ $USER = root ] || continue
[ -n "$PROXY_WLAN" ] || proxy_get_if || continue
[ $HAVE_TRACEROUTE = 1 ] || continue
traceroute -i $PROXY_WLAN --icmp $DNS_TARGET -m $THOPS || { \
retval=$?
ERROR $retval traceroute --icmp -m $THOPS
[ -z "$ALL" ] && exit 7$retval
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="-i icmp"
elif [ $ARG -eq 8 ] ; then
tests[8]="traceroute_tcp_dns_as_root -i $PROXY_WLAN -p 53 -T4 - trace "
[ $USER = root ] || continue
[ -n "$PROXY_WLAN" ] || proxy_get_if || continue
[ $HAVE_TRACEROUTE = 1 ] || continue
traceroute -i $PROXY_WLAN -p 53 -T4 $DNS_TARGET -m $THOPS || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval traceroute -T4 -p 53 -m $THOPS
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="53"
elif [ $ARG -eq 9 ] ; then
tests[9]="traceroute_icmp_dns_as_user -p 53 - trace "
[ $USER = root ] || continue
[ -n "$PROXY_WLAN" ] || proxy_get_if || continue
[ $HAVE_TRACEROUTE = 1 ] || continue
traceroute -i $PROXY_WLAN --icmp $DNS_TARGET -p 53 -m $THOPS || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval traceroute -i $PROXY_WLAN --icmp -m $THOPS
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="53"
elif [ $ARG -eq 10 ] ; then
tests[10]="wget_http_as_user $HTTP_PORT - http "
proxy=`proxy_ping_get_http`
env http_proxy=http://${proxy} \
$WGET -S http://$HTTP_TARGET 2>/dev/null
retval=$?
# 8 is an oddball
if [ $retval -eq 8 -o $retval -eq 0 ] ; then
INFO $prog test=$ARG "${tests[$ARG]}" wget $HTTP_PORT
else
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval wget $HTTP_PORT
[ -z "$ALL" ] && exit $ARG$retval || continue
fi
GREP="$HTTP_PORT"
elif [ $ARG -eq 11 ] ; then
tests[11]="curl_https_as_user - https "
proxy=`proxy_ping_get_https`
proxy_ping_curl --proxy http://${proxy} \
--proxy-insecure https://$HTTP_TARGET || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl $HTTP_PORT
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="$HTTP_PORT"
elif [ $ARG -eq 12 ] ; then
tests[12]="nmap_dns_as_root --privileged --send-eth -Pn -sU -p U:53 $DNS_HOST1 - nmap direct "
[ $USER = root ] || continue
which nmap 2>/dev/null >/dev/null || continue
[ -z "$DNS_HOST1" ] && DNS_HOST1="208.67.220.220"
nmap --privileged --send-eth -Pn -sU -p U:53 "$DNS_HOST1" || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval nmap 53
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
GREP="53"
elif [ $ARG -eq 13 ] ; then
tests[13]="curl_firewall_bin - wifi "
[ $USER = root ] || continue
proxy_test_curl_firewall_bin || continue
INFO $prog test=$ARG "${tests[$ARG]}" curl bin
# works
GREP="443"
elif [ $ARG -eq 14 ] ; then
tests[14]="traceroute_icmp_gw_as_root --icmp $PROXY_WLAN_GW - gw wifi "
[ $USER = root ] || continue
[ $HAVE_TRACEROUTE = 1 ] || continue
proxy_test_traceroute_icmp_gw || continue
# works
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="-i icmp"
elif [ $ARG -eq 15 ] ; then
tests[15]="test_dig_direct - direct "
[ $HAVE_DIG = 1 ] || continue
proxy_test_dig_direct || continue
INFO $prog test=$ARG "${tests[$ARG]}" proxy_test_dig_direct
elif [ $ARG -eq 16 ] ; then
tests[16]="nslookup_as_root nslookup $PRIV_BIN_OWNER - torhost "
[ $USER = root ] || continue
[ $HAVE_NSLOOKUP = 1 ] || continue
su -c "$NSL $DNS_TARGET $DNS_HOST1" -s /bin/sh $PRIV_BIN_OWNER >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval "$NSL $DNS_TARGET $DNS_HOST1" -s /bin/sh $PRIV_BIN_OWNER
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works /fails but maybe a noop
GREP="53"
elif [ $ARG -eq 17 ] ; then
tests[17]="ntpdate_as_root ntpdate without service - ntp "
proxy_run_as_root || exit 9
[ -x /usr/sbin/ntpdate ] || continue
# Curious: even though sgid 2755 ntp it fails as su ntp
# 12 Nov 23:28:35 ntpdate[17341]: bind() fails: Permission denied
/usr/sbin/ntpdate "$NTP_HOST1" || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval ntpdate
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="123"
elif [ $ARG -eq 18 ] ; then
tests[18]="ntpdate_as_root ntpdate with servie - ntp "
proxy_run_as_root || exit 9
proxy_rc_service ntpd status >/dev/null && \
proxy_rc_service ntpd stop >/dev/null && sleep 2
/usr/sbin/ntpdate $NTP_HOST1 || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval ntpdate
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
proxy_rc_service ntpd status >/dev/null || proxy_rc_service ntpd start
GREP="123"
elif [ $ARG -eq 19 ] ; then
tests[19]="curl_noproxy_http_as_user curl raw noproxy - firefail "
proxy_ping_curl --noproxy "'*.*'" --connect-timeout $TIMEOUT \
http://$HTTP_TARGET >/dev/null && {
retval=$?
ERROR PANIC: $prog test=$ARG "${tests[$ARG]}" curl raw --noproxy
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP=80
elif [ $ARG -eq 20 ] ; then
tests[20]="curl_socksproxy_as_user curl $SOCKS_PORT - socks "
# needs dns
[ $DEBIAN -eq 0 ] && continue
socks_proxy=socks5h://${SOCKS_HOST}:$SOCKS_PORT
proxy_ping_curl -x $socks_proxy https://$HTTP_TARGET >/dev/null \
|| { retval=$? ; ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl $SOCKS_PORT
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works with user/pass
GREP="$SOCKS_PORT"
elif [ $ARG -eq 21 ] ; then
tests[21]="curl_httpsproxy_as_user - https "
[ -z "$https_proxy" ] && https_proxy=http://${HTTPS_PROXY_HOST}:${HTTPS_PORT}
proxy_ping_curl -x $https_proxy https://$HTTP_TARGET >/dev/null || { \
if [ "$MODE" = gateway ] ; then
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval curl ${HTTPS_HOST} ${HTTPS_PORT}
continue
else
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl ${HTTPS_HOST} HTTPS_PORT=${HTTPS_PORT}
[ -z "$ALL" ] && exit $ARG$retval || continue
fi
}
INFO $prog test=$ARG "${tests[$ARG]}" curl ${HTTPS_HOST} ${HTTPS_PORT}
GREP="${HTTPS_PORT}"
elif [ $ARG -eq 22 ] ; then
tests[22]="iwlist_scan_as_user iwlist $PROXY_WLAN scan - iwlist "
[ $USER = root ] || continue
which iwlist 2>/dev/null || continue
[ -n "$PROXY_WLAN" ] || proxy_get_if || continue
iwlist $PROXY_WLAN scan >/dev/null || {
ERROR $prog retval=$? test=$ARG $PROXY_WLAN scan
[ -z "$ALL" ] && exit $ARG$1 || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
elif [ $ARG -eq 23 ] ; then
tests[23]="curl_proxy_as_user - direct "
proxy_ping_curl --insecure https://$HTTP_TARGET >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl direct
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
elif [ $ARG -eq 24 ] ; then
tests[24]="dig_direct_or_dnsmasq dig -b $IP www.whatismypublicip.com - direct "
[ $HAVE_DIG = 1 ] || continue
[ -n "$PROXY_WLAN" -a -n "$IP" ] || proxy_ping_get_wlan_gw || continue
[ -n "$IP" ] || continue
dig -b $IP www.whatismypublicip.com +timeout=$TIMEOUT >/dev/null || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval dig -b $IP
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}" dig -b $IP
elif [ $ARG -eq 25 ] ; then
tests[25]="nslookup_as_user - direct "
[ $HAVE_NSLOOKUP = 1 ] || continue
# noenv with or without proxy
# @$DNS_HOST1 should fail for firewall unless dnsmasq is working
$NSL >/dev/null www.whatismypublicip.com || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval nslookup www.whatismypublicip.com
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}" nslookup
elif [ $ARG -eq 26 ] ; then
tests[26]="route_connected_ping_scan - direct "
[ $HAVE_DIG = 1 ] || continue
#? proxy_test_pretests
proxy_do_ping && \
INFO $prog test=$ARG "${tests[$ARG]}" retval=$retval dig -b $IP || \
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval dig -b $IP
elif [ $ARG -eq 27 ] ; then
tests[27]="dns_as_user dig -b 127.0.0.1 - direct "
[ $HAVE_DIG = 1 ] || continue
[ -n "$PROXY_WLAN" -a -n "$IP" ] || proxy_ping_get_wlan_gw || continue
dig -b 127.0.0.1 www.whatismypublicip.com +timeout=$TIMEOUT >/dev/null || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval dig -b $IP
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
elif [ $ARG -eq 28 ] ; then
tests[28]="wget_as_user - direct "
proxy_ping_test_env || { WARN $prog test=$ARG "${tests[$ARG]}" no proxy in env ; }
$WGET -S https://$HTTP_TARGET 2>/dev/null
retval=$?
if [ $retval -eq 8 -o $retval -eq 0 ] ; then
INFO $prog test=$ARG "${tests[$ARG]}" wget
else
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval wget
[ -z "$ALL" ] && exit $ARG$retval || continue
fi
elif [ $ARG -eq 29 ] ; then
tests[29]="curl_as_user - direct "
proxy_ping_test_env || { WARN $prog test=$ARG "${tests[$ARG]}" no proxy in env ; }
proxy_ping_curl https://$HTTP_TARGET >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval curl
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
elif [ $ARG -eq 30 ] ; then
tests[30]="tor_bootstrap_check_as_root tor_bootstrap_check.py - torhost "
[ $MODE = tor -o $MODE = selektor ] || {
ERROR $prog MODE != tor test=$ARG
[ -z "$ALL" ] && exit $ARG$retval || continue
}
port=$SOCKS_PORT
$NETS | grep -q :$port || {
ERROR $prog retval=$? test=$ARG tor not running on $port
[ -z "$ALL" ] && exit $ARG || continue
}
[ $USER = root ] || continue
# was /usr/local/bin/tor_bootstrap_check.bash
[ -f /usr/local/src/helper-scripts/tor_bootstrap_check.py ] || return 1
python3.sh /usr/local/src/helper-scripts/tor_bootstrap_check.py
# morons 100%
retval=$?
[ $retval -eq 0 -o $retval -eq 100 ] || { \
retval=$?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval tor_bootstrap_check
}
INFO $prog test=$ARG "${tests[$ARG]}"
elif [ $ARG -eq 31 ] ; then
tests[31]="curl_noproxy_as_root polipo http pages $HTTP_PORT - direct http "
proxy_ping_curl --noproxy http://${HTTP_HOST}:$HTTP_PORT && { \
retval=$?
ERROR PANIC: $prog test=$ARG "${tests[$ARG]}" retval=$retval polipo http pages $HTTP_PORT
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
GREP="$HTTP_PORT"
elif [ $ARG -eq 32 ] ; then
tests[32]="ping_nmap_direct_as_root nmap 53 - direct "
[ $USER = root ] || continue
which nmap 2>/dev/null >/dev/null || continue
[ -n "$PROXY_WLAN" -a -n "$PROXY_WLAN_GW" ] || proxy_ping_get_wlan_gw || continue
proxy_ping_nmap_direct $DNS_HOST1 "$PROXY_WLAN_GW" U:67 || {
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval nmapd 53
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
GREP="53"
elif [ $ARG -eq 33 ] ; then
tests[33]="host_virbr_as_user proxy_ping_test_virbr 1 - libvirthost "
proxy_ping_test_virbr 1 || {
retval=$?
ERROR $CONN virbr1 not running
[ -z "$ALL" ] && exit 1 || continue
}
# * Immediate connect fail for 10.0.2.15: Connection refused
INFO $prog test=$ARG "${tests[$ARG]}"
elif [ $ARG -eq 34 ] ; then
tests[34]="python_ping_as_root traceroute --icmp $PROXY_WLAN_GW - wifi "
[ $USER = root ] || continue
[ -n "$PROXY_WLAN_GW" -a -n "$IP" ] || PROXY_WLAN_GW=`proxy_ping_get_wlan_gw` || continue
[ -f /usr/local/bin/ping2.py ] || continue
/usr/local/bin/ping2.py $IP $DNS_HOST1 $PROXY_WLAN_GW || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval ping2.py $DNS_HOST1
[ -z "$ALL" ] && exit $ARG$retval || continue
}
# works
INFO $prog test=$ARG "${tests[$ARG]}"
GREP="-i icmp"
elif [ $ARG -eq 35 ] ; then
tests[35]="dig_as_root - firewall dig @$DNS_HOST1 - torhost dns "
[ $USER = root ] || continue
[ $HAVE_DIG = 1 ] || continue
# @$DNS_HOST1
su -c "dig pool.ntp.org +timeout=$TIMEOUT" -s /bin/sh $PRIV_BIN_OWNER >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval dig pool.ntp.org $PRIV_BIN_OWNER
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
GREP="53"
elif [ $ARG -eq 36 ] ; then
tests[36]="tor_resolve_as_user tor-resolve pool.ntp.org - tordns "
[ $HAVE_TOR_RESOLVE = 1 ] || continue
tor-resolve pool.ntp.org >/dev/null || { \
retval=$?
# dunno Failed parsing SOCKS5 response conf?
WARN $prog test=$ARG "${tests[$ARG]}" retval=$retval tor-resolve pool.ntp.org
continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
# works
GREP="9053"
elif [ $ARG -eq 37 ] ; then
tests[37]="qemu-guest-agent and ports - libvirtguest "
ser=qemu-guest-agent
proxy_rc_service $ser status >/dev/null || proxy_rc_service $ser start
proxy_rc_service $ser status >/dev/null || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval $ser status
[ -z "$ALL" ] && exit $ARG$retval || continue
}
[ -d /dev/virtio-ports ] || { \
retval=$?
ERROR $prog test=$ARG "${tests[$ARG]}" retval=$retval /dev/virtio-ports
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
GREP=""
elif [ $ARG -eq 38 ] ; then
tests[38]="qemu-guest-agent and ports - libvirthost whonix "
[ $USER = root ] || continue
$PL proxy_libvirt_list
aret=$?
if [ $aret -eq 10 ] ;then
WARN proxy_libvirt_status hung
elif [ $aret -ne 10 -a $aret -ne 0 ] ; then
DBUG proxy_libvirt_status aret=$aret
else
$PL proxy_libvirt_list | grep -q "$GATEW_DOM" || {
ERROR MODE=$MODE and $GATEW_DOM not running ;
[ -z "$ALL" ] && exit $ARG$retval || continue
}
INFO $prog test=$ARG "${tests[$ARG]}"
fi
elif false ; then
if ! grep -q '10.152.152.10\|127.0.0.1' /etc/resolv.conf ; then
$NETS | grep -q :53 || {
ERROR $prog retval=$? test=$ARG local resolv.conf but :53 not running
[ -z "$ALL" ] && exit 1 || continue
}
fi
fi
[ -n "$GREP" ] && [ $DMESG_LINES -gt 0 ] && \
DBUG `dmesg|tail|grep $GREP|tail -$DMESG_LINES`
done
exit 0
1)
env https_proxy=http://${SOCKS_HOST}:${HTTPS_PORT} wget $D -O - --no-check-certificate
2)
curl $D -k --proxy
3)
curl $D -k --proxy socks5://${SOCKS_HOST}:$SOCKS_PORT --proxy-insecure
5)
nslookup -port=$SOCKS_DNS www.whatismypublicip.com ${SOCKS_HOST} \
6)
curl -k --proxy $HTTP_PORT
16)
nslookup $PRIV_BIN_OWNER
18)
ntpdate as sroot
19)
curl raw noproxy
0)
usage

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
[ -z "$PYVER" ] && PYVER=3
export PYVER
#[ -f /usr/local/bin/usr_local_tput.bash ] && \
# . /usr/local/bin/usr_local_tput.bash
ROLE=base
declare -a RARGS
RARGS=("$@")
[ -f /usr/local/bin/pyver.sh ] && . /usr/local/bin/pyver.sh || {
[ -f /usr/local/etc/testforge/testforge.bash ] && \
. /usr/local/etc/testforge/testforge.bash >/dev/null
P="BASE_PYTHON${PYVER}_MINOR"
PYTHON_MINOR="$(eval echo \$$P)"
[ -n "$PYTHON_MINOR" ] || \
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR >&2 ; exit 1
fi
}
if [ -z "$PYTHONPATH" ] ; then
# sic - failsafe
export PYTHONPATH=/usr/lib/python$PYTHON_MINOR/site-packages
fi
if [ -d /usr/$LIB/python$PYTHON_MINOR/site-packages/llvmlite/binding ] ; then
if [ -z "$LD_LIBRARY_PATH" ] ; then
export LD_LIBRARY_PATH=/usr/$LIB/python$PYTHON_MINOR/site-packages/llvmlite/binding
else
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/$LIB/python$PYTHON_MINOR/site-packages/llvmlite/binding
fi
fi
# do I want $HOME/.local on the path? - no
# do I want local/lib/.../dist-packages on the path? - no is already is
# on Debian ~/.local/lib/python*/site-packages is already on the path
for elt in usr/local ; do
[ -d /$elt ] || continue
[ -d /$elt/bin ] && [[ ! $PATH =~ /$elt/bin ]] && \
export PATH=$PATH:/$elt/bin
[ -e /$elt/$LIB ] || continue
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/$elt/$LIB
[ -d /$elt/$LIB/python$PYTHON_MINOR/site-packages ] || \
mkdir /$elt/$LIB/python$PYTHON_MINOR/site-packages
[ ! -f /$elt/$LIB/python$PYTHON_MINOR/site-packages/__init__.py ] && \
touch /$elt/$LIB/python$PYTHON_MINOR/site-packages/__init__.py
[[ ! $PYTHONPATH =~ /$elt/$LIB/python$PYTHON_MINOR/site-packages ]] && \
export PYTHONPATH=$PYTHONPATH:/$elt/$LIB/python$PYTHON_MINOR/site-packages
done
# echo INFO exec /usr/bin/python$PYTHON_MINOR -W ignore::DeprecationWarning "${RARGS[@]}"
/usr/bin/python$PYTHON_MINOR -W ignore::DeprecationWarning "${RARGS[@]}"

View file

@ -0,0 +1,5 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
ROLE=bash
export PYVER=2
exec /usr/local/bin/python.sh "$@"

View file

@ -0,0 +1,5 @@
#!/bin/bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
ROLE=bash
export PYVER=3
/usr/local/bin/python.sh "$@"

View file

@ -0,0 +1,117 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
DBUG() { echo DEBUG $* >&2 ; }
INFO() { echo INFO $* >&2 ; }
WARN() { echo WARN $* >&2 ; }
ERROR() { echo ERROR $* >&2 ; }
prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=base
[ -z "$PYVER" ] && PYVER=3 # echo ERROR define PYVER >&2 && exit 1
[ -z "$USER" ] && USER=$( id -un )
ini_file=/usr/local/etc/testforge/testforge.bash
if [ ! -f $ini_file ] ; then
# bootstrap
[ -d /usr/local/etc/testforge ] || mkdir -p /usr/local/etc/testforge
[ -x /usr/bin/python$PYVER ] && \
echo export BASE_PYTHON${PYVER}_MINOR=`/usr/bin/python$PYVER --version|sed -e 's/.* //' -e 's/\.[0-9]*$//'` >> $ini_file
else
. $ini_file >/dev/null
fi
set -- -x
P="BASE_PYTHON${PYVER}_MINOR"
PYTHON_MINOR="$(eval echo \$$P)"
[ -n "$PYTHON_MINOR" ] || \
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR
exit 1
fi
if [ "$USER" = root ] ; then
[ -f /usr/$LIB/python$PYTHON_MINOR/sitecustomize.py ] && \
mv /usr/$LIB/python$PYTHON_MINOR/sitecustomize.py /usr/$LIB/python$PYTHON_MINOR/sitecustomize.py.bak && \
rm -f /usr/$LIB/python$PYTHON_MINOR/sitecustomize.pyc
fi
if [ ! -d /usr/local/$LIB/python$PYTHON_MINOR/site-packages/ ] ; then
if [ "$USER" = root ] ; then
mkdir -p /usr/local/$LIB/python$PYTHON_MINOR/site-packages/
chgrp adm /usr/local/$LIB/python$PYTHON_MINOR/site-packages/
chmod 775 /usr/local/$LIB/python$PYTHON_MINOR/site-packages/
else
ERROR Install error missing /usr/local/$LIB/python$PYTHON_MINOR/site-packages/
exit 2
fi
fi
[ -d /usr/local/$LIB/python$PYTHON_MINOR/site-packages/ ] || \
mkdir -p /usr/local/$LIB/python$PYTHON_MINOR/site-packages/
[ -f /usr/local/$LIB/python$PYTHON_MINOR/site-packages/sitecustomize.py ] || \
cat > /usr/local/$LIB/python$PYTHON_MINOR/site-packages/sitecustomize.py << EOF
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
from __future__ import print_function
import codecs
codecs._codecs_lookup = codecs.lookup
def lookup(s):
if s.endswith('-unix'):
s = s[:-5]
elif s.endswith('-dos'):
s = s[:-4]
return codecs._codecs_lookup(s)
codecs.lookup = lookup
import os,sys
pyver = sys.version[:3]
notver = "3" if sys.version[:1] == '2' else '2'
for elt in sys.path:
if elt.find('python' + notver) < 0: continue
p = os.environ.get('PYTHONPATH', '')
sys.stderr.write('WARN: sitecustomize.py PYTHONPATH=' +p +' sys.path=' +repr(sys.path) +'\n')
sys.stderr.write('"python' + notver +' in sys.path for ' +sys.executable +"\n")
raise RuntimeError('"python' + notver +' in sys.path for ' +sys.executable)
dir=None
for elt in ['var', 'usr']:
if 'LD_LIBRARY_PATH' not in os.environ or 'PYTHONPATH' not in os.environ:
continue
dir = '/' + elt + '/local/bin'
if dir not in os.environ['PATH'].split(os.pathsep):
continue
dir = '/' + elt + "/local/$LIB"
if dir not in os.environ['LD_LIBRARY_PATH'].split(os.pathsep):
continue
dir = '/' + elt + "/local/$LIB/python" + pyver + '/site-packages'
# the bash wrapper will have put this on
if dir in os.environ['PYTHONPATH'].split(os.pathsep):
# print(repr(sys.path))
if dir not in sys.path:
sys.path.insert(0, dir)
bin = '/' + elt + '/local/bin/python' + pyver[0]
if elt == 'var':
bin += '.bash'
else:
bin += '.sh'
if os.path.isfile(bin):
# print(sys.executable + '=' + bin)
sys.executable = bin
# var takes precedence
break
if __name__ == '__main__':
print(sys.executable)
del os, sys, dir, elt, pyver
EOF

View file

@ -0,0 +1,36 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
# on stdout - messages on stderr
prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=base
base=AnsI
# quiet
[ "$#" -eq 0 ] && exit 1
VARIABLE=$1
[ -f $PREFIX/etc/testforge/testforge.bash ] && . $PREFIX/etc/testforge/testforge.bash
[ -n "$TESTFORGE_ANSIBLE_SRC" ] || TESTFORGE_ANSIBLE_SRC=/g/TestForge/src/ansible
name=`hostname`
if [ -d "$TESTFORGE_ANSIBLE_SRC" ] && [ -f $TESTFORGE_ANSIBLE_SRC/hosts.yml ] ; then
base=$name
ansible-inventory -i $TESTFORGE_ANSIBLE_SRC/hosts.yml \
--playbook-dir=$TESTFORGE_ANSIBLE_SRC \
--host=$base >> /tmp/${AnsI}$$.json 2> /tmp/${AnsI}$$.err
if [ $? -eq 0 -a -f /tmp/${AnsI}$$.json ] ; then
#!? export
VALUE=`jq .$VARIABLE </tmp/${AnsI}$$.json | sed -e 's/,//'|xargs echo`
# [ -n "$DEBUG" ] && echo >&2 "DEBUG: $prog base=$base VALUE=$VALUE"
[ "$VALUE" = "null" ] && VALUE=""
echo -n "$VALUE"
fi
rm -f /tmp/${AnsI}$$.json
fi
exit 0

View file

@ -0,0 +1,39 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
PREFIX=/usr/local
ROLE=base
. /usr/local/bin/usr_local_base.bash || exit 2
umask 0022
[ "$#" -gt 0 ] && inidir=$1 || inidir=/usr/local/etc/testforge
[ -f $inidir ] || mkdir -p $inidir
if [ -f $inidir ] ; then
inifile=$inidir
else
inifile=$inidir/testforge.ini
fi
# echo -n "DEBUG: $prog "; ls -l $inifile
[ -e $inifile ] || { ERROR no file $inifile ; exit 1 ; }
[ -s $inifile ] || { ERROR empty file $inifile ; exit 2 ; }
bashfile=$( echo $inifile | sed -e 's/.ini$/.bash/' )
if [ ! -s $bashfile ] || [ $inifile -nt $bashfile ] ; then
INFO "$inifile > $bashfile"
/usr/local/bin/fact_to_bash.bash < $inifile > $bashfile || exit 3
echo 'export PATH=$PATH:/sbin:/usr/local/bin:/var/local/bin' >> $bashfile
echo -n "DEBUG: $prog bashfile"; ls -l $bashfile
fi
ymlfile=$( echo $inifile | sed -e 's/.ini$/.yml/' )
if [ ! -s $ymlfile ] || [ $inifile -nt $ymlfile ] ; then
INFO "$inifile > $ymlfile"
/usr/local/bin/fact_to_yaml.bash < $inifile > $ymlfile || exit 4
echo -n "DEBUG: $prog ymlfile "; ls -l $ymlfile
fi
. $bashfile || exit $?
exec bash /usr/local/bin/base_sheebang_after_pip.bash

View file

@ -0,0 +1,60 @@
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
. /usr/local/bin/usr_local_base.bash || exit 2
PREFIX=/usr/local
ROLE=base
[ -z "$BASE_PYTHON2_MINOR" ] && \
BASE_PYTHON2_MINOR=$( python2 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$BASE_PYTHON3_MINOR" ] && \
BASE_PYTHON3_MINOR=$( python3 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
for PYTHON_MINOR in "$BASE_PYTHON2_MINOR" "$BASE_PYTHON3_MINOR" ; do
[ -z "$PYTHON_MINOR" ] && continue
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib64
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR/site-packages ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR/site-packages
fi
done
umask 0022
# [ "$#" -eq 0 ] && set -- $PREFIX/bin
# FixMe? /usr/local/bin too? I think not, except for ours?
for prefix in /usr/local /var/local ; do
cd $prefix/bin || exit 1
#? ls -1d * | grep -v '~' | xargs file | grep -i python | sed -e 's/:.*//'|while read file ; do
ls -1 | grep -v '~' | xargs file | grep script | sed -e 's/:.*//' | \
while read file ; do
head -1 $file | grep -q python || continue
head -1 $file | grep -q $prefix/python..bash && continue
base=$( echo $file | sed -e 's/\.bash$//' )
under=$( echo $prefix | sed -e 's/^.//' -e 's@/@_@g' )
if [ -h /etc/python-exec/$base.conf ] ; then
link=$( readlink /etc/python-exec/$base.conf )
if [ "$link" = python2.conf ] ; then
sed -f $prefix/share/sed/${under}_python2.sed -i $file
else
sed -f $prefix/share/sed/${under}_python3.sed -i $file
fi
else
sed -f $prefix/share/sed/${under}_python2.sed -i $file
sed -f $prefix/share/sed/${under}_python3.sed -i $file
fi
# echo $file
done
# failsafe - Eberly - no longer active
for elt in $BASE_PYTHON2_MINOR $BASE_PYTHON3_MINOR ; do
[ -f $prefix/${LIB}/python$elt/site-packages/site.py ]
# WARN missing $prefix/${LIB}/python$elt/site-packages/site.py
done
done
exit 0

View file

@ -0,0 +1,425 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
# from https://github.com/earlruby/create-vm/
[ -f /usr/local/bin/usr_local_tput.bash ] && \
. /usr/local/bin/usr_local_tput.bash || {
DBUG() { echo DEBUG $* ; }
INFO() { echo INFO $* ; }
WARN() { echo WARN $* ; }
ERROR() { echo ERROR $* ; }
}
prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=toxcore
export PATH=$PATH:$PREFIX/bin
have_genisoimage=true
# create-vm - Quickly create guest VMs using cloud image files and cloud-init.
# Copyright 2018-2023 Earl C. Ruby III
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# Set BOX_NBD_OVERLAY_DIR environment variable to override default storage location for VMs
HOSTNAME=
IMG_FQN=
AUTH_KEYS_FQN=
RAM=2048
VCPUS=1
STORAGE=20
BRIDGE=virbr1
MAC='52:54:00:1d:9c:6f'
VERBOSE=
PASS=
OSINFO=gentoo
password=ansible
OUTDIR=${BOX_NBD_OVERLAY_DIRs:-"${HOME}/vms/virsh"}
usage()
{
cat << EOF
usage: $0 options
Quickly create guest VMs using cloud image files and cloud-init.
OPTIONS:
-h Show this message
-n Host name (required)
-i Full path and name of the base .img file to use (required)
-k Full path and name of the ansible user's public key file (required)
-d Output directory for the overlay qcow2 and related files
-r RAM in MB (defaults to ${RAM})
-c Number of VCPUs (defaults to ${VCPUS})
-s Amount of storage to allocate in GB (defaults to ${STORAGE})
-b Bridge interface to use (defaults to ${BRIDGE})
-m MAC address to use (default is to use a randomly-generated MAC)
-o OSINFO name like win11, win10, fedora32, gentoo, ububtu20
-p ansible users plaintext password
-v Verbose
EOF
}
while getopts "h:n:i:k:r:c:s:b:m:o:p:d:v" option; do
case "${option}"
in
h)
usage
exit 0
;;
n) HOSTNAME=${OPTARG};;
i) IMG_FQN=${OPTARG};;
k) AUTH_KEYS_FQN=${OPTARG};;
r) RAM=${OPTARG};;
c) VCPUS=${OPTARG};;
s) STORAGE=${OPTARG};;
b) BRIDGE=${OPTARG};;
m) MAC=${OPTARG};;
p) PASS=${OPTARG};;
o) password=${OPTARG};;
d) OUTDIR=${OPTARG};
BOX_NBD_OVERLAY_DIR=${OUTDIR};;
v) VERBOSE=1;;
*)
ERROR unhandled option "${option}" ${OPTARG}
usage
exit 1
;;
esac
done
if [[ -z $HOSTNAME ]]; then
ERROR "Host name is required"
usage
exit 1
fi
if [[ -z $IMG_FQN ]]; then
ERROR "Base cloud image file name is required"
usage
exit 1
fi
if [[ -z $BOX_NBD_OVERLAY_DIR ]]; then
ERROR "Output image directory is required BOX_NBD_OVERLAY_DIR"
usage
exit 1
fi
if [[ -z $AUTH_KEYS_FQN ]]; then
ERROR "ansible public key file $AUTH_KEYS_FQN not found"
usage
exit 1
fi
if ! [[ -f $IMG_FQN ]]; then
ERROR "$IMG_FQN file not found"
usage
exit 1
fi
if [[ -n $VERBOSE ]]; then
INFO "Building ${HOSTNAME} in $BOX_NBD_OVERLAY_DIR"
set -xv
fi
mkdir -p "$BOX_NBD_OVERLAY_DIR"/{images,xml,init,base} || exit 2
echo "Creating a qcow2 image file ${BOX_NBD_OVERLAY_DIR}/images/${HOSTNAME}.img that uses the cloud image file ${IMG_FQN} as its base"
INFO qemu-img create -b "${IMG_FQN}" -f qcow2 -F qcow2 \
"${BOX_NBD_OVERLAY_DIR}/images/${HOSTNAME}.img" "${STORAGE}G"
qemu-img create -b "${IMG_FQN}" -f qcow2 -F qcow2 \
"${BOX_NBD_OVERLAY_DIR}/images/${HOSTNAME}.img" "${STORAGE}G" || \
exit 3
echo "Creating meta-data file $BOX_NBD_OVERLAY_DIR/init/meta-data"
cat > "$BOX_NBD_OVERLAY_DIR/init/meta-data" << EOF
instance-id: ${HOSTNAME}
local-hostname: ${HOSTNAME}
EOF
# echo "Creating meta-data file $BOX_NBD_OVERLAY_DIR/init/meta-data.json"
# cat > "$BOX_NBD_OVERLAY_DIR/init/meta-data.json" << EOF
cat > /dev/null << EOF
{
"admin_pass": "root",
"availability_zone": "nova",
"hostname": "test.novalocal",
"launch_index": 0,
"name": "gentoo6",
"meta": {
"role": "webservers",
"essential": "false"
},
"public_keys": {
"mykey": " ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRCJCQ1UD9QslWDSw5Pwsvba0Wsf1pO4how5BtNaZn0xLZpTq2nqFEJshUkd/zCWF7DWyhmNphQ8c+U+wcmdNVcg2pI1kPxq0VZzBfZ7cDwhjgeLsIvTXvU+HVRtsXh4c5FlUXpRjf/x+a3vqFRvNsRd1DE+5ZqQHbOVbnsStk3PZppaByMg+AZZMx56OUk2pZCgvpCwj6LIixqwuxNKPxmJf45RyOsPUXwCwkq9UD4me5jksTPPkt3oeUWw1ZSSF8F/141moWsGxSnd5NxCbPUWGoRfYcHc865E70nN4WrZkM7RFI/s5mvQtuj8dRL67JUEwvdvEDO0EBz21FV/iOracXd2omlTUSK+wYrWGtiwQwEgr4r5bimxDKy9L8UlaJZ+ONhLTP8ecTHYkaU1C75sLX9ZYd5YtqjiNGsNF+wdW6WrXrQiWeyrGK7ZwbA7lagSxIa7yeqnKDjdkcJvQXCYGLM9AMBKWeJaOpwqZ+dOunMDLd5VZrDCU2lpCSJ1M="
},
"uuid": "83679162-1378-4288-a2d4-70e13ec132aa"
}
EOF
# password=`openssl passwd -1 -stdin <<< $password`
echo "Creating user-data file $BOX_NBD_OVERLAY_DIR/init/user-data"
# https://techglimpse.com/nova-boot-instance-with-password/
cat > "$BOX_NBD_OVERLAY_DIR/init/user-data" << EOF
#cloud-config
# password: ansible
# chpasswd: { expire: False }
ssh_pwauth: true
runcmd:
- "rc-update add qemu-guest-agent"
- "chmod 755 /etc/init.d/qemu-guest-agent"
- "/etc/init.d/qemu-guest-agent start"
- "echo /etc/init.d/qemu-guest-agent start >> /etc/rc.local"
users:
- default
- name: ansible
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
groups:
- wheel
- adm
shell: /bin/bash
plain_text_password: "$password"
chpasswd: { expire: False }
homedir: /home/ansible
ssh_pwauth: true
ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRCJCQ1UD9QslWDSw5Pwsvba0Wsf1pO4how5BtNaZn0xLZpTq2nqFEJshUkd/zCWF7DWyhmNphQ8c+U+wcmdNVcg2pI1kPxq0VZzBfZ7cDwhjgeLsIvTXvU+HVRtsXh4c5FlUXpRjf/x+a3vqFRvNsRd1DE+5ZqQHbOVbnsStk3PZppaByMg+AZZMx56OUk2pZCgvpCwj6LIixqwuxNKPxmJf45RyOsPUXwCwkq9UD4me5jksTPPkt3oeUWw1ZSSF8F/141moWsGxSnd5NxCbPUWGoRfYcHc865E70nN4WrZkM7RFI/s5mvQtuj8dRL67JUEwvdvEDO0EBz21FV/iOracXd2omlTUSK+wYrWGtiwQwEgr4r5bimxDKy9L8UlaJZ+ONhLTP8ecTHYkaU1C75sLX9ZYd5YtqjiNGsNF+wdW6WrXrQiWeyrGK7ZwbA7lagSxIa7yeqnKDjdkcJvQXCYGLM9AMBKWeJaOpwqZ+dOunMDLd5VZrDCU2lpCSJ1M="
EOF
echo "Adding keys from the public key file $AUTH_KEYS_FQN to the user-data file"
while IFS= read -r key; do
echo " - $key" >> "$BOX_NBD_OVERLAY_DIR/init/user-data"
done < <(grep -v '^ *#' < "$AUTH_KEYS_FQN")
VM_IMAGE_DIR="$BOX_NBD_OVERLAY_DIR"
#old . /usr/local/bin/toxcore_create-ga.sh || exit 4
cat > "$BOX_NBD_OVERLAY_DIR/init/user-data" << \EOF
#!/bin/bash
# typically only executes on first boot
echo "############# user_data executing ##############"
#grep gentoo /etc/shadow
sed -e 's/#-:ALL:ALL/+:gentoo:ALL/' -i /etc/security/access.conf
PW=`echo $PASS | openssl passwd -1 --stdin `
grep -q ^gentoo /etc/passwd || \
useradd --gid 4 --uid 1000 --home-dir /home/gentoo \
--comment Gentoo --password "$PW" \
-G adm,wheel --shell /bin/bash gentoo
usermod --password "$PW" -G adm,wheel gentoo
# root
usermod --password '$1$1Ho4y/W8$5VymfKWWAhLxwkkPZiWTZ1' root
# unlock account
passwd -u gentoo
passwd -u root
sed -e 's/# %wheel /%wheel /' -i /etc/sudoers
sed -e 's/PasswordAuthentication no/PasswordAuthentication yes/' -i /etc//ssh/sshd_config
sed -e 's/PermitRootLogin.*/PermitRootLogin yes/' -i /etc//ssh/sshd_config
grep net.ipv4.ip_forward=1 /etc/sysctl.conf || \
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
cd /etc/init.d
[ -e net.eth0 ] || ln -s net.lo net.eth0
for elt in i o linuxPen19 ; do
grep -q $elt /etc/fstab && continue
echo "$elt /mnt/$elt virtiofs defaults 0 0" >> /etc/fstab
done
#grep gentoo /etc/shadow
EOF
echo "Generating the cidata ISO file $BOX_NBD_OVERLAY_DIR/images/${HOSTNAME}-cidata.iso"
(
cd "$BOX_NBD_OVERLAY_DIR/init/"
genisoimage \
-output "$BOX_NBD_OVERLAY_DIR/images/${HOSTNAME}-cidata.img" \
-volid cidata \
-rational-rock \
-joliet \
-input-charset utf-8 \
user-data meta-data
) || exit 5
MACCMD=
if [[ -n $MAC ]]; then
MACCMD="--mac=${MAC}"
fi
[ -f ${BOX_NBD_OVERLAY_DIR}/images/${HOSTNAME}.img ] || exit 5
[ -f $BOX_NBD_OVERLAY_DIR/images/${HOSTNAME}-cidata.img ] || exit 6
# libvirt.libvirtError: /usr/lib/qemu/qemu-bridge-helper --use-vnet --br=-c --fd=31: failed to communicate with bridge helper: stderr=failed to parse default acl file `/etc/qemu/bridge.conf'
if [ ! -f "/etc/qemu/bridge.conf" ] ; then
echo allow $BRIDGE >> "/etc/qemu/bridge.conf"
elif ! grep $BRIDGE "/etc/qemu/bridge.conf" ; then
echo allow $BRIDGE >> "/etc/qemu/bridge.conf"
fi
if [ $BRIDGE = virbr0 ] ; then
network=default
# 192.168.122.248/24
elif [ $BRIDGE = virbr1 ] ; then
network=Whonix-External
else
WARN unrecognized $BRIDGE
fi
if [ "$network" != '' ] ; then
virsh net-list | grep -q $network || \
virsh net-start $network
else
network=default
fi
file=/etc/libvirt/qemu/networks/$network.xml
if [ ! -f $file ] ; then
WARN no network file $file
elif ! grep '<range ' $file ; then
WARN no 'DHCP <range> in network file' $file
fi
declare -a LARGS
LARGS=(
--name="${HOSTNAME}" \
--osinfo "$OSINFO" \
--import \
--disk "path=${BOX_NBD_OVERLAY_DIR}/images/${HOSTNAME}.img,format=qcow2" \
--disk "path=$BOX_NBD_OVERLAY_DIR/images/${HOSTNAME}-cidata.img,device=cdrom" \
--ram="${RAM}" \
--vcpus="${VCPUS}" \
--autostart \
--hvm \
--arch x86_64 \
--accelerate \
--check-cpu \
--force \
--watchdog=default \
--channel type=spicevmc,target.type=virtio,target.name=com.redhat.spice.0 \
--channel type=unix,target.type=virtio,target.name=org.qemu.guest_agent.0 \
--rng /dev/urandom \
--os-variant detect=on,name=$OSINFO \
--noautoconsole \
)
# not type=qemu-vdagent
NETWORK="--network network=$network,model=virtio"
if [ -n "$NETWORK" ] ; then
LARGS+=(
$NETWORK \
)
fi
LARGS+=(
# --graphics spice,listen=socket \
--boot init=/sbin/init
--console pty
--video vga
--memorybacking source.type=memfd,access.mode=shared
--filesystem /,/mnt/linuxPen19 \
)
INFO virt-install "${LARGS[@]}"
# squelch warnings
python3.sh `which virt-install` "${LARGS[@]}" || exit 7
# --debug
#? --shmem name=shmem_server,type="memfd",mode="shared"
# --shmem name=shmem0 ivshmem device is not supported with this QEMU binary
# was --graphics vnc,listen=0.0.0.0
# --osinfo "$OSINFO" \
# Make a backup of the VM's XML definition file
virsh dumpxml "${HOSTNAME}" > "${BOX_NBD_OVERLAY_DIR}/xml/${HOSTNAME}.xml" || exit 8
INFO wrote xml `ls -l ${BOX_NBD_OVERLAY_DIR}/xml/${HOSTNAME}.xml`
if [ -n "$VERBOSE" ]; then
set +xv
fi
# problems: type=qemu-vdagent unix unix=on
# problems: type="spicevmc
# ERROR Unknown --channel options: ['unix']
cp "${BOX_NBD_OVERLAY_DIR}/xml/${HOSTNAME}.xml" \
"${BOX_NBD_OVERLAY_DIR}/xml/${HOSTNAME}.xml".new
cat > /tmp/ga.works <<EOF
<channel type="unix">
<source mode="bind" path="/var/lib/libvirt/qemu/channel/target/domain-25-gentoo1/org.qemu.guest_agent.0"/>
<target type="virtio" name="org.qemu.guest_agent.0" state="connected"/>
<address type="virtio-serial" controller="0" bus="0" port="2"/>
</channel>
EOF
cat > /tmp/sp.works <<EOF
<channel type="spicevmc">
<target type="virtio" name="com.redhat.spice.0" state="disconnected"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
EOF
# Show running VMs
virsh list | grep "${HOSTNAME}" && INFO "${HOSTNAME}" || {
ERROR "${HOSTNAME}" ; exit 9$? ; }
# use the following passwordless demonstration key for testing or
# replace with your own key pair
#
# -----BEGIN OPENSSH PRIVATE KEY-----
# b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
# NhAAAAAwEAAQAAAYEA0QiQkNVA/ULJVg0sOT8LL22tFrH9aTuIaMOQbTWmZ9MS2aU6tp6h
# RCbIVJHf8wlhew1soZjaYUPHPlPsHJnTVXINqSNZD8atFWcwX2e3A8IY4Hi7CL0171Ph1U
# bbF4eHORZVF6UY3/8fmt76hUbzbEXdQxPuWakB2zlW57ErZNz2aaWgcjIPgGWTMeejlJNq
# WQoL6QsI+iyIsasLsTSj8ZiX+OUcjrD1F8AsJKvVA+JnuY5LEzz5Ld6HlFsNWUkhfBf9eN
# ZqFrBsUp3eTcQmz1FhqEX2HB3POuRO9JzeFq2ZDO0RSP7OZr0Lbo/HUS+uyVBML3bxAztB
# Ac9tRVf4jq2nF3dqJpU1EivsGK1hrYsEMBIK+K+W4psQysvS/FJWiWfjjYS0z/HnEx2JGl
# NQu+bC1/WWHeWLao4jRrDRfsHVulq160Ilnsqxiu2cGwO5WoEsSGu8nqpyg43ZHCb0FwmB
# izPQDASlniWjqcKmfnTrpzAy3eVWawwlNpaQkidTAAAFgGKSj8diko/HAAAAB3NzaC1yc2
# EAAAGBANEIkJDVQP1CyVYNLDk/Cy9trRax/Wk7iGjDkG01pmfTEtmlOraeoUQmyFSR3/MJ
# YXsNbKGY2mFDxz5T7ByZ01VyDakjWQ/GrRVnMF9ntwPCGOB4uwi9Ne9T4dVG2xeHhzkWVR
# elGN//H5re+oVG82xF3UMT7lmpAds5VuexK2Tc9mmloHIyD4BlkzHno5STalkKC+kLCPos
# iLGrC7E0o/GYl/jlHI6w9RfALCSr1QPiZ7mOSxM8+S3eh5RbDVlJIXwX/XjWahawbFKd3k
# 3EJs9RYahF9hwdzzrkTvSc3hatmQztEUj+zma9C26Px1EvrslQTC928QM7QQHPbUVX+I6t
# pxd3aiaVNRIr7BitYa2LBDASCvivluKbEMrL0vxSVoln442EtM/x5xMdiRpTULvmwtf1lh
# 3li2qOI0aw0X7B1bpatetCJZ7KsYrtnBsDuVqBLEhrvJ6qcoON2Rwm9BcJgYsz0AwEpZ4l
# o6nCpn5066cwMt3lVmsMJTaWkJInUwAAAAMBAAEAAAGAEuz77Hu9EEZyujLOdTnAW9afRv
# XDOZA6pS7yWEufjw5CSlMLwisR83yww09t1QWyvhRqEyYmvOBecsXgaSUtnYfftWz44apy
# /gQYvMVELGKaJAC/q7vjMpGyrxUPkyLMhckALU2KYgV+/rj/j6pBMeVlchmk3pikYrffUX
# JDY990WVO194Dm0buLRzJvfMKYF2BcfF4TvarjOXWAxSuR8www050oJ8HdKahW7Cm5S0po
# FRnNXFGMnLA62vN00vJW8V7j7vui9ukBbhjRWaJuY5rdG/UYmzAe4wvdIEnpk9xIn6JGCp
# FRYTRn7lTh5+/QlQ6FXRP8Ir1vXZFnhKzl0K8Vqh2sf4M79MsIUGAqGxg9xdhjIa5dmgp8
# N18IEDoNEVKUbKuKe/Z5yf8Z9tmexfH1YttjmXMOojBvUHIjRS5hdI9NxnPGRLY2kjAzcm
# gV9Rv3vtdF/+zalk3fAVLeK8hXK+di/7XTvYpfJ2EZBWiNrTeagfNNGiYydsQy3zjZAAAA
# wBNRak7UrqnIHMZn7pkCTgceb1MfByaFtlNzd+Obah54HYIQj5WdZTBAITReMZNt9S5NAR
# M8sQB8UoZPaVSC3ppILIOfLhs6KYj6RrGdiYwyIhMPJ5kRWF8xGCLUX5CjwH2EOq7XhIWt
# MwEFtd/gF2Du7HUNFPsZGnzJ3e7pDKDnE7w2khZ8CIpTFgD769uBYGAtk45QYTDo5JroVM
# ZPDq08Gb/RhIgJLmIpMwyreVpLLLe8SwoMJJ+rihmnJZxO8gAAAMEA0lhiKezeTshht4xu
# rWc0NxxD84a29gSGfTphDPOrlKSEYbkSXhjqCsAZHd8S8kMr3iF6poOk3IWSvFJ6mbd3ie
# qdRTgXH9Thwk4KgpjUhNsQuYRHBbI59Mo+BxSI1B1qzmJSGdmCBL54wwzZmFKDQPQKPxiL
# n0Mlc7GooiDMjT1tbuW/O1EL5EqTRqwgWPTKhBA6r4PnGF150hZRIMooZkD2zX6b1sGojk
# QpvKkEykTwnKCzF5TXO8+wJ3qbcEo9AAAAwQD+Z0r68c2YMNpsmyj3ZKtZNPSvJNcLmyD/
# lWoNJq3djJN4s2JbK8l5ARUdW3xSFEDI9yx/wpfsXoaqWnygP3PoFw2CM4i0EiJiyvrLFU
# r3JLfDUFRy3EJ24RsqbigmEsgQOzTl3xfzeFPfxFoOhokSvTG88PQji1AYHz5kA7p6Zfaz
# Ok11rJYIe7+e9B0lhku0AFwGyqlWQmS/MhIpnjHIk5tP4heHGSmzKQWJDbTskNWd6aq1G7
# 6HWfDpX4HgoM8AAAALaG9sbWFuYkBhcmM=
# -----END OPENSSH PRIVATE KEY-----
#

View file

@ -0,0 +1,61 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
# from https://github.com/earlruby/create-vm/
[ -f /usr/local/bin/usr_local_tput.bash ] && \
. /usr/local/bin/usr_local_tput.bash || {
DBUG() { echo DEBUG $* ; }
INFO() { echo INFO $* ; }
WARN() { echo WARN $* ; }
ERROR() { echo ERROR $* ; }
}
prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=toxcore
# delete-vm - Delete a virtual machine created with create-vm
# Copyright 2018-2023 Earl C. Ruby III
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
VM=$1
# Set VM_IMAGE_DIR environment variable to override default storage location for VMs
VM_IMAGE_DIR=${VM_IMAGE_DIR:-"${HOME}/vms/virsh"}
VM_IMAGE="${VM_IMAGE_DIR}/images/$VM.img"
CI_IMAGE="${VM_IMAGE_DIR}/images/$VM-cidata.img"
usage()
{
cat << EOF
usage: $0 vmname
EOF
}
if [[ -z $VM ]]; then
usage
exit 1
fi
if [[ -e $VM_IMAGE ]]; then
# VM exists
virsh destroy "$VM"
virsh undefine "$VM"
rm -fv "$VM_IMAGE" "$CI_IMAGE"
else
echo "Cannot find an VM image file named '$VM_IMAGE'. Attempting undefine..."
virsh undefine "$VM"
fi

View file

@ -0,0 +1,55 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
# from https://github.com/earlruby/create-vm/
[ -f /usr/local/bin/usr_local_tput.bash ] && \
. /usr/local/bin/usr_local_tput.bash || {
DBUG() { echo DEBUG $* ; }
INFO() { echo INFO $* ; }
WARN() { echo WARN $* ; }
ERROR() { echo ERROR $* ; }
}
prog=`basename $0 .bash`
PREFIX=/usr/local
ROLE=toxcore
. /usr/local/etc/testforge/testforge.bash
[ -n "$HOSTVMS_VAR_LOCAL" ] && PREFIX=$HOSTVMS_VAR_LOCAL
# get-node-ip - Get the IP address of a VM managed by virsh.
# Copyright 2018-2023 Earl C. Ruby III
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
usage()
{
cat << EOF
usage: $0 hostname
This script will take a virsh-managed VM hostname and return the IP address.
EOF
}
HOSTNAME=$1
if [[ -z $HOSTNAME ]]; then
echo "ERROR: Hostname is required"
usage
exit 1
fi
MAC=$(virsh domiflist $HOSTNAME | awk '{ print $5 }' | tail -2 | head -1)
arp -a | grep $MAC | awk '{ print $2 }' | sed 's/[()]//g'
INFO MAC=$MAC arp=$arp

View file

@ -0,0 +1,70 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
[ -z "$prog" ] && prog=`basename $0 .bash`
[ -z "$USER" ] && USER=$( id -un )
[ -z "$DEBUG" ] && DEBUG=0
if [ -n "$TERM" ] ; then
# vars that can be used to change font color
blue=$(tput setaf 6)
cyan=$(tput setaf 5)
green=$(tput setaf 2)
yellow=$(tput setaf 3)
red=$(tput setaf 1)
normal=$(tput sgr0) # default color
else
blue=
cyan=
green=
yellow=
red=
normal=
fi
FTAL () {
echo ${red}FATL:${normal} $*
exit $1
}
ftal () { FTAL >&2 "$@" ; }
panic () { FTAL >&2 "$@" ; }
ERROR () {
echo ${red}EROR:${normal} $*
return 0
}
error () { ERROR >&2 $* ; }
WARN () {
echo ${yellow}WARN:${normal} $*
return 0
}
warn () { WARN >&2 $* ; }
USAGE () {
echo ${yellow}USAGE:${normal} $*
return 0
}
usage () { USAGE >&2 $* ; }
INFO () {
echo ${green}INFO:${normal} $*
return 0
}
info () { INFO >&2 $* ; }
DBUG () {
[ -z "$DEBUG" -o "$DEBUG" -eq 0 ] || echo ${blue}DBUG:${normal} $*
return 0
}
dbug () { DBUG >&2 $* ; }
debug () { [ "$DEBUG" = "1" ] && echo >&2 ${cyan}DBUG:${normal} $* ; return 0 ; }
usage () {
echo ${yellow}USAGE:${normal} $*
return 0
}
USAGE () { usage $* ; }

View file

@ -0,0 +1,36 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
[ -z "$prog" ] && prog=`basename $0 .bash`
[ -z "$USER" ] && USER=$( id -un )
[ -f /usr/local/bin/usr_local_tput.bash ] && \
. /usr/local/bin/usr_local_tput.bash
## box_gentoo_emerge
box_gentoo_emerge () {
[ "$#" -lt 1 ] && return 0
local elt
declare -a ARGS
for elt in "$@" ; do
[ -z "$elt" ] && continue
grep -q "^$elt$" /var/lib/portage/world && continue
ls /var/db/pkg/"$elt"-[0-9]* 2>/dev/null >/dev/null && continue
qlist -IsS "$elt" | grep -q "^$elt" && continue
equery l -f "^$elt$" | grep '^.I' && continue
ARGS+=($elt)
done
[ "${#ARGS[@]}" -eq 0 ] && exit 0
INFO "${ARGS[@]}"
/usr/local/sbin/box_gentoo_emerge.bash "${ARGS[@]}" || return $?
return 0
}
base=usr_local_base
# DBUG 0=$0
if [ -x /usr/bin/basename ] && [ $( /usr/bin/basename -- $0 ) = $base'.bash' -o $( basename -- $0 ) = $base'.sh' ] ; then
[ "$#" -eq 0 ] && exit 0
[ "$#" -eq 1 ] && [ "$1" = '-h' -o "$1" = '--help' ] && \
echo USAGE: $0 && grep '^[a-z].*()\|^## ' $0 | sed -e 's/().*//'|sort && exit 0
eval "$@"
exit $?
fi

View file

@ -0,0 +1,76 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
[ -z "$TERM" ] && exit 0
[ -z "$prog" ] && prog=`basename $0 .bash`
[ -z "$USER" ] && USER=$( id -un )
[ -z "$DEBUG" ] && DEBUG=0
if [ -n "$TERM" ] ; then
# vars that can be used to change font color
blue=$(tput setaf 6)
cyan=$(tput setaf 5)
green=$(tput setaf 2)
yellow=$(tput setaf 3)
red=$(tput setaf 1)
normal=$(tput sgr0) # default color
else
blue=
cyan=
green=
yellow=
red=
normal=
fi
FATL () {
[ $# -eq 1 ] && code=1
[ $# -gt 1 ] && code=$1 && shift
echo ${red}FATL:${normal} $*
exit 1
}
ftal () { FATL >&2 "$@" ; }
panic () { FATL >&2 "$@" ; }
PANIC () { FATL >&2 "$@" ; }
ERROR () {
echo ${red}EROR:${normal} $*
return 0
}
error () { ERROR >&2 $* ; }
WARN () {
echo ${yellow}WARN:${normal} $*
return 0
}
warn () { WARN >&2 $* ; }
USAGE () {
echo ${yellow}USAGE:${normal} $*
return 0
}
usage () { USAGE >&2 $* ; }
INFO () {
echo ${green}INFO:${normal} $*
return 0
}
info () { INFO >&2 $* ; }
DBUG () {
[ -z "$DEBUG" ] || [ "$DEBUG" = 0 ] || echo ${blue}DBUG:${normal} $*
return 0
}
dbug () { DBUG >&2 $* ; }
debug () { [ "$DEBUG" = "1" ] && echo >&2 ${cyan}DBUG:${normal} $* ; return 0 ; }
usage () {
echo ${yellow}USAGE:${normal} $*
return 0
}
USAGE () { usage $* ; }
ols_are_we_connected () { route | grep -q ^default ; return $? ; }

View file

@ -0,0 +1,35 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# pkuczynski/parse_yaml.sh
prog=$( basename $0 .bash )
ROLE=base
# FixMe: lists should be space delineated not comma
parse_yaml() {
local prefix
local depth
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
[ "$#" -eq 2 ] && prefix=$2 || prefix=""
[ "$#" -gt 2 ] && depth=$3 || depth=""
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {
if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn="";
for (i=0; i<indent; i++) {vn=(vn)(vname[i])("'$depth'")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
if [ -x /usr/bin/basename ] && [ $( basename -- $0 ) = 'yaml_to_bash.bash' -o $( basename -- $0 ) = 'parse_yaml.sh' ] ; then
parse_yaml "$@"
fi

View file

@ -0,0 +1,34 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# pkuczynski/parse_yaml.sh
prog=$( basename $0 .bash )
ROLE=base
# FixMe: lists should be space delineated not comma
# Read YAML file from Bash script
# Credits: https://gist.github.com/pkuczynski/8665367
# Updated to support single quotes
parse_yaml() {
local prefix
local depth
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
[ "$#" -gt 1 ] && prefix=$2 || prefix=""
[ "$#" -gt 2 ] && depth=$3 || depth=""
sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-ne "s|^\($s\)\($w\)$s:$s'\(.*\)'$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("'$depth'")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
if [ -x /usr/bin/basename ] && [ $( basename -- $0 ) = 'yaml_to_bash2.bash' -o $( basename -- $0 ) = 'parse_yaml2.sh' ] ; then
parse_yaml "$@"
fi

View file

@ -0,0 +1,68 @@
#!/usr/bin/env bash
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# shellcheck disable=SC1003
prog=$( basename $0 .bash )
ROLE=base
# github.com/jasperes/bash-yaml/script/yaml.sh
# Based on https://gist.github.com/pkuczynski/8665367
parse_yaml() {
local yaml_file=$1
local prefix=$2
local s
local w
local fs
s='[[:space:]]*'
w='[a-zA-Z0-9_.-]*'
fs="$(echo @|tr @ '\034')"
(
sed -e '/- [^\“]'"[^\']"'.*: /s|\([ ]*\)- \([[:space:]]*\)|\1-\'$'\n'' \1\2|g' |
sed -ne '/^--/s|--||g; s|\"|\\\"|g; s/[[:space:]]*$//g;' \
-e "/#.*[\"\']/!s| #.*||g; /^#/s|#.*||g;" \
-e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)${s}[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" |
awk -F"$fs" '{
indent = length($1)/2;
if (length($2) == 0) { conj[indent]="+";} else {conj[indent]="";}
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s%s=(\"%s\")\n", "'"$prefix"'",vn, $2, conj[indent-1],$3);
}
}' |
sed -e 's/_=/+=/g' |
awk 'BEGIN {
FS="=";
OFS="="
}
/(-|\.).*=/ {
gsub("-|\\.", "_", $1)
}
{ print }'
) < "$yaml_file"
}
create_variables() {
local yaml_file="$1"
local prefix="$2"
eval $(parse_yaml "$yaml_file" "$prefix")
}
if [ -x /usr/bin/basename ] && [ $( basename -- $0 ) = 'yaml_to_bash3.bash' -o $( basename -- $0 ) = 'parse_yaml3.sh' ] ; then
[ "$#" -eq 0 ] && echo "USAGE: $0 yamlfile [ prefix ]" && exit 1
file=$1
shift
[ "$#" -gt 1 ] && prefix=$1 || prefix=""
echo "DEBUG: $file $prefix"
create_variables $file $prefix
fi

View file

@ -0,0 +1,4 @@
# -*-mode: conf; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
# This is an auto-generated file - DO NOT EDIT
# Edit the fragments in /usr/local/etc/ansible/ansible.cfg/

View file

@ -0,0 +1 @@
[defaults]

View file

@ -0,0 +1,44 @@
# its a pretty broken debugger - fix it
# debug = true
inventory_enabled=yaml
# strategy_plugins = /usr/local/lib/python2.7/site-packages/mitogen-0.2.9-py2.7.egg/ansible_mitogen/plugins/strategy
# strategy_plugins = /usr/local/lib/python2.7/site-packages/ansible_mitogen/plugins/strategy
# do this in the env to make it easy to pop in and out
# strategy = mitogen_linear
# yaml dense unixy yaml oneline selective skippy stderr myyaml actionable
stdout_callback = yaml
# skippy
display_skipped_hosts = no
# stderr
# /usr/local/lib/python2.7/site-packages/ansible/plugins/callback/default.py
display_failed_stderr = yes
log_path = var/tmp/2021/01/10/linuxKick150154/base_proxy.log
# callback_plugins = /g/TestForge/src/ansible/lib/plugins/
# http://docs.ansible.com/ansible/intro_configuration.html#command-warnings
# callback_whitelist = timer
command_warnings = False
deprecation_warnings = False
display_args_to_stdout = False
error_on_undefined_vars = True
force_color = False
#! fatal: [localhost]: FAILED! => {"changed": false, "cmd": "/bin/lsblk --list --noheadings --paths --output NAME,UUID --exclude 2", "msg": "Timer expired after 30 seconds", "rc": 257}
gather_timeout = 120
handler_includes_static = True
# Ansible by default will override variables in specific precedence orders, as described in Variables.
# When a variable of higher precedence wins, it will replace the other value.
#?! hash_behaviour = merged
local_tmp = /var/tmp
# library = /usr/share/ansible
library = /g/TestForge/src/ansible/library
nocows = 0
retry_files_enabled = False
roles_path = /g/TestForge/src/ansible/roles
# exists?
plugins_path = /g/TestForge/src/ansible/library/plugins

View file

@ -0,0 +1,14 @@
host_key_checking = False
# http://chrisbergeron.com/2018/06/08/ansible_performance_tuning/
gathering = smart
fact_caching = jsonfile
fact_caching_connection = var/tmp/.ansible_fact_cache
forks = 5
timeout = 90
# This sets the interval (in seconds) of Ansible internal processes polling each other. Lower values
# improve performance with large playbooks at the expense of extra CPU load. Higher values are more
# suitable for Ansible usage in automation scenarios, when UI responsiveness is not required but CPU usage
# might be a concern. Default corresponds to the value hardcoded in 2.1: was 1
internal_poll_interval=5

View file

@ -0,0 +1,5 @@
# new 2.8
# https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html
string_conversion_action = error
conditional_bare_variables = false

View file

@ -0,0 +1,3 @@
# https://thepracticalsysadmin.com/turbocharge-your-ansible-playbooks/
[ssh_connection]
pipelining = True

View file

@ -0,0 +1,3 @@
[inventory]
enable_plugins = yaml

View file

@ -0,0 +1,3 @@
[chroot_connection]
# exe = /usr/local/sbin/base_chroot.bash
exe = /bin/chroot

View file

@ -0,0 +1,519 @@
#!/bin/bash
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
# prog=rc.local
PREFIX=/usr/local
ROLE=local
export PATH=$PATH:/usr/local/sbin:/usr/local/bin
if [ -x /sbin/rc-service ] ; then
local_rc_service () { rc-service "$@" ; }
local_rc_update () { rc-update "$@" ; }
elif [ -x /bin/systemctl ] ; then
local_rc_service () {
systemctl list-units --no-pager | grep -q $1 && \
echo INFO: /usr/sbin/service "$@" || \
echo WARN: /usr/sbin/service "$@"
/usr/sbin/service "$@" 2>/dev/null
return $?
}
local_rc_update () {
if [ "$#" -eq 0 ] ; then
systemctl list-units --no-pager
return $?
fi
dir=$1 ; shift ;
svc=$1 ; shift ;
if [ $dir = add ] ; then
dire=enable
elif [ $dir = del ] ; then
dire=disable
else
dire=$dir
fi
echo INFO: $prog systemctl --no-pager $dire $svc "$@"
systemctl --no-pager $dire $svc "$@"
return $?
}
elif [ -x /usr/sbin/service ] ; then
local_rc_service () {
/usr/sbin/service --status-all 2>&1 | grep -q $1 && \
echo INFO: /usr/sbin/service "$@" || \
echo WARN: /usr/sbin/service "$@"
/usr/sbin/service "$@" 2>/dev/null
return $?
}
local_rc_update () {
if [ "$#" -eq 0 ] ; then
/usr/sbin/service --status-all 2>&1 | sed -e 's/.* //'
return $?
fi
dir=$1 ; shift ;
svc=$1 ; shift ;
# disable|enable |remove
if [ $dir = add ] ; then
dire=enable
elif [ $dir = del ] ; then
dire=disable
else
dire=$dir
fi
update-rc.d $svc $dire || echo WARN: update-rc.d $svc $dir $dire
}
fi
proxy_rc_service () { local_rc_service $* ; }
proxy_rc_update () { local_rc_update $* ; }
grep -q root=/dev/vda /proc/cmdline
PROXY_IS_VDA=$?
## local_disable_lid
local_disable_lid () {
# https://bbs.archlinux.org/viewtopic.php?id=72779
echo LID0 > /proc/acpi/wakeup
# https://forums.linuxmint.com/viewtopic.php?f=208&t=106532
if [ -f /etc/UPower/UPower.conf ] ; then
[ -f /etc/UPower/UPower.conf.bak ] || \
cp -p /etc/UPower/UPower.conf /etc/UPower/UPower.conf.bak
grep -q '^IgnoreLid=true' /etc/UPower/UPower.conf || \
sed -e 's@#*IgnoreLid=.*@IgnoreLid=true@' -i /etc/UPower/UPower.conf
fi
if [ -f /etc/systemd/logind.conf ] ; then
[ -f /etc/systemd/logind.conf.bak ] || \
cp -p /etc/systemd/logind.conf /etc/systemd/logind.conf.bak
grep -q '^HandleLidSwitch=ignore' /etc/systemd/logind.conf || \
sed -e 's@^#*HandleLidSwitch=.*@HandleLidSwitch=ignore@' -i /etc/systemd/logind.conf
fi
return 0
}
## local_guest_neutersystemd
local_config_neutersystemd () {
[ ! -f /lib/lsb/init-functions.d/40-systemd ] || \
mv /lib/lsb/init-functions.d/40-systemd /lib/lsb/.40-systemd
return 0
}
## local_guest_fstab_config
local_guest_fstab_config () {
[ -d /mnt/mnt ] || mkdir /mnt/mnt
grep -q 9p /etc/fstab || {
echo mnt /mnt/mnt 9p trans=virtio,version=9p2000.L,posixacl,msize=10485760,cache=mmap \
>> /etc/fstab
}
# failsafe
grep 9p /etc/modules-load.d/*conf 2>/dev/null >/dev/null || \
cat > /etc/modules-load.d/9p.conf << EOF
9p
9pnet
9pnet_virtio
EOF
lsmod | grep -q 9pnet_virtio || modprobe -a `cat /etc/modules-load.d/*.conf`
return 0
}
## local_guest_config
local_guest_bootstrap () {
local_guest_fstab_config
return 0
}
## local_guest_config
local_guest_config () {
local_guest_bootstrap
local_guest_config_neutersystemd
[ -d /etc/qemu ] || mkdir /etc/qemu
[ -f /etc/qemu/qemu-ga.conf ] || cat > /etc/qemu/qemu-ga.conf <<EOF
[general]
daemon=false
method=virtio-serial
path=/dev/virtio-ports/org.qemu.guest_agent.0
pidfile=/run/qemu-ga.pid
statedir=/run
verbose=true
retry-path=false
blacklist=
logfile=/var/log/libvirtd/qemu-ga.log
EOF
[ -d /var/log/libvirtd/ ] || mkdir /var/log/libvirtd/
[ -f /etc/default/qemu-guest-agent.diff ] || cat > /etc/default/qemu-guest-agent.diff <<EOF
*** /etc/default/qemu-guest-agent.dst 2021-01-05 03:28:20.579117119 +0000
--- /etc/default/qemu-guest-agent 2021-08-27 20:26:36.234739996 +0000
***************
*** 1 ****
! DAEMON_ARGS="--logfile /var/log/libvirtd/qemu-ga.log"
--- 1 ----
! DAEMON_ARGS="--logfile /var/log/libvirtd/qemu-ga.log --verbose --pidfile /run/qemu-ga.pid"
EOF
[ ! -f /etc/default/qemu-guest-agent ] || \
[ -f /etc/default/qemu-guest-agent.dst ] || \
patch -z .st -b /etc/default/qemu-guest-agent \
< /etc/default/qemu-guest-agent.diff
return 0
}
## local_guest_modules_load
local_guest_modules_load () {
for file in /usr/local/etc/modules-load.d/vda*conf ; do
[ -s $file ] || continue
base=`basename $file`
[ -e /etc/modules-load.d/$base ] && continue
echo "# from $file" > /etc/modules-load.d/$base
grep -v '^#' $file >> /etc/modules-load.d/$base
done
# old
if [ -d /usr/local/etc/modules-load.d/ ] ; then
ls /etc/modules-load.d/vda*conf 2>/dev/null >/dev/null || \
ln -s /usr/local/etc/modules-load.d/vda*conf /etc/modules-load.d
fi
return 0
}
# all
## local_lightdm_on_text
local_lightdm_on_text () {
return 0
[ ! -f /usr/sbin/lightdm ] && return 0
if [ ! -f /usr/sbin/lightdm.bin ] ; then
[ -f /usr/sbin/lightdm.bad ] && mv /usr/sbin/lightdm.bad /usr/sbin/lightdm.bin
[ ! -f /usr/sbin/lightdm.bin ] && mv /usr/sbin/lightdm /usr/sbin/lightdm.bin
if [ -f /usr/sbin/lightdm.bin ] && [ -f /usr/sbin/lightdm ] ; then
cat > /usr/sbin/lightdm << EOF
#!/bin/sh
grep -q ' text ' /proc/cmdline && exit 0
exec /usr/sbin/lightdm.bin "$@"
EOF
chmod 755 /usr/sbin/lightdm
fi
fi
return 0
}
## local_guest_start_services
local_guest_start_services () { local_guest_start ; }
## local_guest_start
local_guest_start () {
local_guest_modules_load
lsmod | grep -q 9pnet_virtio || \
grep -hv '#' /etc/modules-load.d/vda*.conf | xargs modprobe --all
# local_start_and_add_services $*
exit 0
}
## local_guest_add_xorg_conf
local_guest_add_xorg_conf () {
[ -f /etc/X11/xorg.conf.d/80_qxl.conf ] || \
grep -q 'Drive.*qxl' /etc/X11/xorg.conf.d/*.conf || \
cat > /etc/X11/xorg.conf.d/80_qxl.conf << EOF
# BEGIN ANSIBLE MANAGED BLOCK proxy whonix_guest.yml
Section "Device"
Identifier "qxl"
Driver "qxl"
Option "DPI" "96 x 96"
Option "ENABLE_IMAGE_CACHE" "True"
Option "ENABLE_FALLBACK_CACHE" "False"
Option "ENABLE_SURFACES" "False"
EndSection
# END ANSIBLE MANAGED BLOCK proxy whonix_guest.yml
EOF
return 0
}
## local_guest_status
local_guest_status () {
if [ ! -f /var/log/libvirtd/qemu-ga.log ] ; then
echo WARN: missing /var/log/libvirtd/qemu-ga.log
elif grep -q critical: /var/log/libvirtd/qemu-ga.log ; then
echo ERROR: critical /var/log/libvirtd/qemu-ga.log
fi
return 0
}
# vda
## local_host_symlink_usr_src
local_host_symlink_etc_fstab () {
# guest
[ -h /etc/fstab ] && [ -f /etc/fstab.vda ] && \
rm -f /etc/fstab && ln -s /etc/fstab.vda /etc/fstab
return 0
}
## local_host_make_dmcrypt_swap
local_host_make_dmcrypt_swap () {
local two five
if ! grep -q '/dev/mapper\|/dev/sd\|/dev/dm' /proc/swaps ; then
blkid > ~/blkid.txt
five=`grep _05E ~/blkid.txt | head -1`
if [ $? -eq 0 -a -n "$five" ] ; then
two=`echo $five | sed -e 's/_.*//' -e 's/.*="//'`_02SWAP
if ! grep $two ~/blkid.txt ; then
dev=`echo $five | sed -e 's/:.*//' -e 's/5/2/'`
[ $? -eq 0 -a -n "$dev" ] && mkswap -L $two $dev
fi
grep $two /etc/conf.d/dmcrypt && local_rc_service dmcrypt restart || echo WARN: $two not in /etc/conf.d/dmcrypt
grep -q '/dev/mapper\|/dev/sd\|/dev/dm' /proc/swaps || local_rc_service swap restart
# if its not in fstab
grep -q '/dev/mapper\|/dev/sd\|/dev/dm' /proc/swaps || swapon /dev/mapper/cryptswap*
fi
fi
return 0
}
# all
local_start_services () { local_start_and_add_services ; }
## local_start_and_add_services
local_start_and_add_services () {
for elt in $*; do
local_rc_service $elt status >/dev/null || local_rc_service $elt start
local_rc_update | grep -q $elt || local_rc_update add $elt
done
return 0
}
# all
## local_manual_stop_services
local_manual_stop_services () {
# set these to stop now and restart them manually as we configure them
# rsync on debian
for elt in $* ; do
local_rc_service $elt status >/dev/null && local_rc_service $elt stop
local_rc_update | grep -q $elt && local_rc_update del $elt
done
return 0
}
# host
## local_host_symlink_usr_src
local_host_symlink_usr_src () {
local dir
# broken
dir=`cat /proc/cmdline|sed -e 's/.*BOOT_IMAGE=kernel-pentoo-x86_64/linux/' -e 's/_.*//'`
WD=$PWD
cd /usr/src
if [ -d $dir ] ; then
rm -f linux
ln -s $dir linux || echo WARN: $PWD/$dir not found
fi
cd $WD
return 0
}
# host
## local_host_restart_psmouse
local_host_restart_psmouse () {
local_rc_service gpm status && local_rc_service gpm stop
rmmod psmouse; sleep 1; modprobe psmouse proto=exps
local_rc_service gpm start
return 0
}
# host
## local_host_restart_intel_sound
local_host_restart_intel_sound () {
which aplay >/dev/null 2>/dev/null || return 0
# both
if ! aplay -L | grep -q default:CARD=PCH ; then
rmmod snd_hda_intel ;
sleep 5
modprobe snd_hda_intel enable=1 ;
sleep 1
aplay -L >/dev/null || exit 2
fi
return 0
}
## local_kicksecure
local_kicksecure () {
local_guest || exit 1$?
return 0
}
## local_gateway
local_gateway () {
local_guest || exit 1$?
return 0
}
ELTS="sdwdate rads"
## local_guest
local_guest () {
# grep -q text /proc/cmdline && local_lightdm_on_text
local_all
local_guest_config
local_guest_start
if [ -d /etc/apt ] ; then
# bootstrap for ansible
if ! apt-cache search openssh-server | grep -q Size ; then
apt-get install openssh-server
fi
local_start_and_add_services ssh
if grep -q text /proc/cmdline ; then
local_manual_stop_services graphical lightdm rads
fi
fi
# local_manual_mask_services $ELTS
return 0
}
## local_host
local_host () {
local_host_crit_boot || exit 1$?
local_disable_lid
local_host_restart_intel_sound
local_host_restart_psmouse
local_all
return 0
}
# local_null_machineid
local_null_machineid () {
[ -s /etc/machine-id ] && cp /dev/null /etc/machine-id
return 0
}
## local_all
local_all () {
local_host_crit_boot || exit 2
uuidgen > /etc/machine-id
local_config_neutersystemd
local_null_machineid
touch /var/log/boot
chmod 775 /usr/local/*bin/*sh
local_neuter_gvfs
( cd /var/tmp && rm -rf ansible-local-* Temp-* ssh-* pulse-* .xfsm-ICE-* )
local_systemd_stop_and_mask
return 0
}
## local_manual_mask_services
local_manual_mask_services () {
if [ -d /usr/local/etc/systemd/ ] ; then
local_systemd_stop_and_mask $* || return 1$?
elif [ -x /usr/sbin/update-rc.d ] ; then
/usr/sbin/invoke-rc.d $1 stop
/usr/sbin/update-rc.d $1 remove || return 2$?
elif [ /sbin/rc-update ] ; then
/sbin/rc-service $1 stop
/sbin/rc-update $1 del || return 3$?
fi
return 0
}
# local_guest_neutersystemd
local_guest_neutersystemd () {
local_systemd_stop_and_mask
return $?
}
## local_systemd_stop_and_mask
local_systemd_stop_and_mask () {
[ -d /lib/systemd/system/ ] || return 0
[ $# -eq 0 ] && [ -d /usr/local/etc/systemd/ ] && \
set - `grep -l -v '#\|@\.service' /usr/local/etc/systemd/*.mask`
for file in $* ; do
[ -e /lib/systemd/system/$file ] || continue
elt=`basename $file`
systemctl is-enabled $elt 2>/dev/null >/dev/null || continue
echo INFO: local_systemd_stop_and_mask systemctl disable $elt
systemctl disable --now $elt && systemctl mask $elt
# [ -h /etc/systemd/system/$file ]
# [ `readlink /etc/systemd/system/$file ` = /dev/null ]
done
return 0
}
## local_neuter_gvfs
local_neuter_gvfs () {
[ -d /usr/local/share/dbus-1/services ] || exit 0
cd /usr/local/share/dbus-1/services
for file in /usr/share/dbus-1/services/*vfs* ; do
sed -e 's@^Exec=.*@Exec=/bin/false@' > `basename $file`
done
}
# local_link_linux
local_link_linux () {
sed < /proc/cmdline -e 's@.*BOOT_IMAGE=vmlinuz-@linux-@' -e 's/[_ ].*//'| \
while read line ; do
[ -z "$line" ] && continue
[ -d "/usr/src/$line" ] || { echo WARN: /usr/src/$line ; continue ; }
rm -f /usr/src/linux
echo INFO: /usr/src/$line /usr/src/linux
ln -s /usr/src/$line /usr/src/linux
done
return 0
}
# local_host_crit_boot
local_host_crit_boot () {
[ -d /mnt/l/syslinux ] || return 0
local a=`grep BOOT_IMAGE /proc/cmdline |sed -e 's/.*BOOT_IMAGE=//' -e 's/ .*//'`
[ -n "$a" ] || return 1
[ -f "/boot/$a" ] || return 2
[ -f "/mnt/l/syslinux/$a" ] || return 3
diff "/boot/$a" "/mnt/l/syslinux/$a" || {
/usr/local/bin/base_wall.bash $prog 'CRIT: ' "/boot/$a" "/mnt/l/syslinux/$a"
return 4
}
a=`grep initrd= /proc/cmdline |sed -e 's/.*initrd=//' -e 's/ .*//' -e 's/.*,//'`
[ -n "$a" ] || return 11
[ -f "/boot/$a" ] || return 12
[ -f "/mnt/l/syslinux/$a" ] || return 13
diff "/boot/$a" "/mnt/l/syslinux/$a" || {
/usr/local/bin/base_wall.bash $prog 'CRIT: ' "/boot/$a" "/mnt/l/syslinux/$a"
return 14
}
return 0
}
base=local
if [ -x /usr/bin/basename ] && [ `/usr/bin/basename -- $0` = $base'.bash' ] ; then
[ "$#" -eq 1 ] && [ "$1" = '-h' -o "$1" = '--help' ] && \
echo USAGE: $0 && grep '^[a-z].*()\|^## ' $0 | sed -e 's/().*//'| sort \
&& exit 0
"$@"
exit $?
fi

View file

@ -0,0 +1,5 @@
debug-shell.service
multi-user.target.wants/swap-file-creator.service
swap-file-creator.service
systemd-backlight@.service
systemd-backlight@backlight.service

View file

@ -0,0 +1,159 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
prog=$( basename $0 .bash )
ROLE=base
# export PATH=$PATH:/usr/local/bin
. /usr/local/bin/usr_local_tput.bash
# MUST be silent
error () { retval=$1 ; shift; ERROR $prog $* >&2 ; exit $retval ; }
usage () { echo "USAGE: $prog chroot-dir [command args] -" $* >&2 ; exit 1 ; }
warn () { : ; }
info () { : ; }
debug () { : ; }
# must be run as root
[ "$( id -u )" -ne "0" ] && error 1 "must be run as root"
[ -x /bin/chroot ] && EXE=/bin/chroot
[ -x /usr/sbin/chroot ] && EXE=/usr/sbin/chroot # debian
setcap CAP_SYS_PTRACE=+ep $EXE
if [ "$#" -eq "0" ] ; then
usage "give an absolute directory name as argument"
fi
LARGS=""
CMD=""
while true; do
case "$1" in
'-'*)
LARGS="$1"
shift
;;
*)
break
;;
esac
done
[ -z "$LARGS" ] && LARGS="--userspec=0:0"
root=$1
shift
if [ ! -d "$root" ] ; then
error 1 "directory not found - $root"
fi
# unix partition
[ -d $root/lost+found ] || WARN "No $root/lost+found"
# linux partition
[ -e $root/usr/src/ ] || WARN "No $root/usr/src"
# check for /dev/loop devices - up to 255 on android
[ -e /dev/loop1 ] || \
( cd /dev && \
for i in 0 1 2 3 4 5 6 7 ; do
[ -e loop$i ] && continue
mknod loop$i b 7 $i
chmod 660 loop$i
chgrp disk loop$i
done )
cd $root || error 6 "Can't cd to $root"
# sbin/boostrap_chroot.bash
for file in .bashrc .bash_profile .bash_logout .emacs ; do
[ -f $root/root/$file ] && continue
cp -p /root/$file $root/root/
done
for file in tmp usr/tmp var/tmp ; do
[ -d $file ] && continue
mkdir $file || error 8 " missing directory $file"
chmod 1777 $file
done
# df /var/tmp | grep -q sd.12 || mount /var/tmp
for file in proc sys dev dev/pts dev/shm usr ; do
[ -d $file ] && continue
mkdir $file || error 9 "Cant mkdir $file"
chmod 755 $file
done
if false ; then
[ -e proc/self ] || mount -o bind /proc $root/proc || error 10
# https://forums.gentoo.org/viewtopic-t-1061422-start-0.html
[ -e dev/null ] || mount -o bind /dev $root/dev || error 11
# what happens to dev/shm ? its own memory?
# required for ansible and firefox
df -a | grep -q $root/dev/shm || mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 12
[ -e dev/pts/ptmx ] || \
mount -t devpts -o rw,relatime,gid=5,mode=620,ptmxmode=000 devpts $root/dev/pts || error 13
else
# https://wiki.gentoo.org/wiki/Chroot
[ -e dev/loop0 ] || \
{ mount --rbind /dev $root/dev ; mount --make-rslave $root/dev ; } \
|| error 10 mount --rbind /dev $root/dev
[ -e proc/self ] || mount -t proc /proc $root/proc \
|| error 11 mount -t proc /proc
[ -e sys/block ] || \
{ mount --rbind /sys $root/sys ; mount --make-rslave $root/sys ; } \
|| error 12 --rbind /sys $root/sys
df -a | grep -q $root/dev/shm || \
mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 14 $root/dev/shm
df -a | grep -q $root/tmp || mount --rbind /tmp $root/tmp \
|| error 13 mount --rbind /tmp $root/tmp
# https://wiki.gentoo.org/wiki/Project:X86/Chroot_Guide
[ -e dev/pts/ptmx ] || \
mount -o bind /dev/pts $root/dev/pts || error 14 mount -o bind /dev/pts $root/dev/pts
fi
# user
if [ -d $root/$HOME -a -f ~/.Xauthority ] ; then
cp ~/.Xauthority $root/$HOME
cp ~/.xauth* $root/$HOME
fi
base=$( basename $root )
[ -e ./start.rc ] || cat > ./start.rc << EOF
# env-update && . /etc/profile
export PS1='\${tty}\\u@${base}:\\W\\$ '
EOF
[ -z "$DISPLAY" ] || grep -q DISPLAY ./start.rc || \
echo export DISPLAY=\"$DISPLAY\" >> ./start.rc
# openpty failed: 'out of pty devices'
# root@Flati:11# d /dev/pts/
# total 6
# 2 ./ 4 ../
# You'll also want to copy over resolv.conf in order to have proper DNS name
# resolution from inside the chroot:
cp -L /etc/resolv.conf etc || error 16 "Cant cp -L /etc/resolv.conf"
EARGS="CHROOT=$root PATH=/usr/sbin:/usr/bin:/sbin:/bin"
#? set these to root or derive them? what about -l?
EELTS="$EELTS TERM DISPLAY HOME LANG LC_ALL"
[ -z "$LC_COLLATE" ] && EELTS="$EELTS LC_COLLATE" || EARGS="$EARGS LC_COLLATE=C"
. /usr/local/bin/proxy_export.bash >/dev/null
EELTS="$EELTS http_proxy https_proxy socks_proxy no_proxy"
for elt in $EELTS ; do
EARGS="$EARGS $( env|grep ^${elt}= )"
done
# mesg: ttyname failed: Success
tty=$( tty 2>/dev/null )
[ $? -eq 0 -a -n "$tty" ] && EARGS="$EARGS TTY=$tty"
# was /bin/bash -l
[ "$#" -eq 0 ] && set -- /bin/bash -i -l
# Now you can chroot into your new system. Use env before chroot to ensure that no
# environment variables from the installation media are used by your new system:
#? PATH=$PATH
# info chroot $LARGS $root /usr/bin/env -i $EARGS "$@"
exec $EXE $LARGS $root /usr/bin/env -i $EARGS "$@"

View file

@ -0,0 +1,155 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
prog=$( basename $0 .bash )
ROLE=base
. /usr/local/bin/usr_local_tput.bash
# MUST be silent
usage () { echo "USAGE: $prog chroot-dir [command args] -" $* >&2 ; exit 1 ; }
error () { retval=$1 ; shift; ERROR "$prog" $* >&2 ; exit $retval ; }
warn () { WARN "$prog" $* >&2 }
info () { INFO "$prog" $* >&2 }
debug () { DBUG "$prog" $* >&2 }
# must be run as root
[ "$( id -u )" -ne "0" ] && error 1 "must be run as root"
if [ "$#" -eq "0" ] ; then
usage "give an absolute directory name as argument"
fi
LARGS=""
CMD=""
while true; do
case "$1" in
'-'*)
LARGS="$1"
shift
;;
*)
break
;;
esac
done
[ -z "$LARGS" ] && LARGS="--userspec=0:0"
root=$1
shift
if [ ! -d "$root" ] ; then
error "directory not found - $root"
fi
# unix partition
[ -d $root/lost+found ] || warn "No $root/lost+found"
# linux partition
[ -e $root/usr/src/ ] || warn "No $root/usr/src"
# check for /dev/loop devices
[ -e /dev/loop1 ] || \
( cd /dev && \
for i in 0 1 2 3 4 5 6 7 ; do
[ -e loop$i ] && continue
mknod loop$i b 7 $i
chmod 660 loop$i
chgrp disk loop$i
done )
cd $root || error 6 "Can't cd to $root"
# sbin/boostrap_chroot.bash
for file in .bashrc .bash_profile .bash_logout .emacs ; do
[ -f $root/root/$file ] && continue
cp -p /root/$file $root/root/
done
for file in tmp usr/tmp var/tmp ; do
[ -d $file ] && continue
mkdir $file || error 8 " missing directory $file"
chmod 1777 $file
done
for file in proc sys dev dev/pts dev/shm usr ; do
[ -d $file ] && continue
mkdir $file || error 9 "Cant mkdir $file"
chmod 755 $file
done
if false ; then
[ -e proc/self ] || mount -o bind /proc $root/proc || error 10
# https://forums.gentoo.org/viewtopic-t-1061422-start-0.html
[ -e dev/null ] || mount -o bind /dev $root/dev || error 11
# what happens to dev/shm ? its own memory?
# required for ansible and firefox
df -a | grep -q $root/dev/shm || mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 12
[ -e dev/pts/ptmx ] || \
mount -t devpts -o rw,relatime,gid=5,mode=620,ptmxmode=000 devpts $root/dev/pts || error 13
else
# https://wiki.gentoo.org/wiki/Chroot
[ -e dev/null ] || \
{ mount --rbind /dev $root/dev ; mount --make-rslave $root/dev ; } \
|| error 10 mount --rbind /dev $root/dev
[ -e proc/self ] || mount -t proc /proc $root/proc \
|| error 11 mount -t proc /proc
[ -e sys/block ] || \
{ mount --rbind /sys $root/sys ; mount --make-rslave $root/sys ; } \
|| error 12 --rbind /sys $root/sys
df -a | grep -q $root/dev/shm || \
mount -t tmpfs -o noexec,size=5% tmpfs $root/dev/shm || error 14 $root/dev/shm
# https://wiki.gentoo.org/wiki/Project:X86/Chroot_Guide
[ -e dev/pts/ptmx ] || \
mount -o bind /dev/pts $root/dev/pts || error 14 mount -o bind /dev/pts $root/dev/pts
fi
# user
if [ -d $root/$HOME -a -f ~/.Xauthority ] ; then
cp ~/.Xauthority $root/$HOME
cp ~/.xauth* $root/$HOME
fi
base=$( basename $root )
[ -e ./start.rc ] || cat > ./start.rc << EOF
# env-update && . /etc/profile
export PS1='\${tty}\\u@${osl}${base}:\\W\\$ '
EOF
[ -z "$DISPLAY" ] || grep -q DISPLAY ./start.rc || \
echo export DISPLAY=\"$DISPLAY\" >> ./start.rc
# You'll also want to copy over resolv.conf in order to have proper DNS name
# resolution from inside the chroot:
cp -L /etc/resolv.conf etc || error 16 "Cant cp -L /etc/resolv.conf"
EARGS="CHROOT=$root PATH=/usr/sbin:/usr/bin:/sbin:/bin"
#? set these to root or derive them? what about -l?
EELTS="$EELTS TERM DISPLAY HOME LANG LC_ALL"
[ -z "$LC_COLLATE" ] && EELTS="$EELTS LC_COLLATE" || EARGS="$EARGS LC_COLLATE=C"
. /usr/local/bin/proxy_export.bash >/dev/null
EELTS="$EELTS http_proxy https_proxy socks_proxy no_proxy"
for elt in $EELTS ; do
EARGS="$EARGS $( env|grep ^${elt}= )"
done
[ -n "$BOX_DEBIAN10_VAR_APT_ARCHIVES" ] && \
EARGS="$EARGS $BOX_DEBIAN10_VAR_APT_ARCHIVES=$BOX_DEBIAN10_VAR_APT_ARCHIVES"
# mesg: ttyname failed: Success
tty=$( tty 2>/dev/null )
[ $? -eq 0 -a -n "$tty" ] && EARGS="$EARGS TTY=$tty"
# was /bin/bash -l
[ "$#" -eq 0 ] && set -- /bin/bash -i -l
# Now you can chroot into your new system. Use env before chroot to ensure that no
# environment variables from the installation media are used by your new system:
INFO capsh --caps="CAP_SYS_PTRACE+ep CAP_SYS_CHROOT+ep" --keep=1 -- /usr/sbin/chroot $LARGS $root /usr/bin/env -i $EARGS "$@"
echo >$root/tmp/$$.bash \
capsh '--caps="CAP_SYS_PTRACE+ep CAP_SYS_CHROOT+ep"' --keep=1 -- /tmp/$$.sh
echo >$root/tmp/$$.sh \
'`which env`' -i $EARGS "$@"
capsh --caps="CAP_SYS_PTRACE+ep CAP_SYS_CHROOT+ep" --keep=1 --chroot=$root -- /tmp/$$.bash
# --chroot=$root -c /usr/bin/env -- -i $EARGS "$@"
# exec chroot $LARGS $root /usr/bin/env -i $EARGS "$@"

View file

@ -0,0 +1,42 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
ROLE=base
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash
error () { ERROR "$prog $2" ; exit $1 ; }
# must be run as root
if [ "$( id -u )" != "0" ] ; then
echo ERROR: $0 run as root
exit 0
fi
if [ "$#" -eq "0" ] ; then
error 2 "give an absolute directory name as argument"
fi
root=$1
if [ ! -d "$1" ] ; then
error 3 "give an absolute directory name for chroot - $root"
fi
mount | grep $root/ | while read a on elt rest ; do
umount $elt || { ERROR "unmounting $elt" ; exit 5 ; }
done
mount | grep bind | while read a on elt rest ; do
umount $elt || { ERROR "unmounting $elt" ; exit 6 ; }
done
umount -R $root
lsof $root/usr 2>/dev/null \
| sed -e 's@^[a-z]* *@@' -e 's@ .*@@' \
| grep -v "$$\\|COMMAND" | sort -r -u | while read pid ; do
INFO "killing $pid"
kill $pid
sleep 10
#? kill -9 $pid
done
exit 0

View file

@ -0,0 +1,44 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
ROLE=base
. /usr/local/bin/usr_local_tput.bash || exit 2
[ "$DEBUG" = 1 ] && patch=patch || patch=echo
TODIR=/
[ $# -eq 0 ] && set -- *
INFO patching $@ in $PWD
find "$@" -name \*.diff |while read file ; do
echo $file
relf=$( echo $file | sed -e 's/^root//' )
base=$( echo $relf | sed -e 's/.diff$//' )
dest="${TODIR}$base"
if [ ! -f $dest ] && head -1 $file | grep -q /dev/null ; then
cp /dev/null $dest
$patch -b -z .dst $dest < $file
continue
fi
if [ ! -f $dest ] ; then
WARN BAD PATCH file missing dest=$dest for patch $file
continue
fi
if [ -f $dest.dst ] ; then
[ $dest -nt $file ] && DBUG $dest.dst done || WARN $dest -nt $PWD/$file
continue
fi
$patch -b -z .dst $dest < $file 2>$base.err
retval=$?
if [ $? -eq 0 ] ; then
INFO patched $file
else
WARN patch ERROR $file `cat $base.err`
[ -s $base.err ] || rm -f $base.err
fi
[ -f $dest.rej ] && WARN $dest.rej exists
done
exit 0

View file

@ -0,0 +1,69 @@
#!/bin/sh
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash
ROLE=base
. /usr/local/bin/usr_local_base.bash || exit 2
. ~/.bash_logout
# these can hang unmounting partitions
pkill dirmngr
pkill bootlogd
[ -x /var/local/bin/privacy_home_cleaner.bash ] && /var/local/bin/privacy_home_cleaner.bash
[ -f ~/Makefile ] && grep -q ^stop: ~/Makefile && \
{ cd ~ ; make stop || exit 2 ; }
a=`virsh list | wc -l`
[ $? -eq 0 -a -n "$a" -a "$a" -gt 0 ] && proxy_whonix_host.bash stop
local_base_umount () {
local mount
cd /mnt
mount=`mount`
for file in linux* ; do
echo $mount | grep -q " on /mnt/$file " || continue
echo /mnt/$file
umount -R /mnt/$file || exit 1
done
# not l - a b f d n u x i j k o q w e h z
for file in ? ; do
echo $mount | grep -q " on /mnt/$file " || continue
# echo /mnt/$file
umount /mnt/$file || echo WARN: $prog error umounting /mnt/$file
done
umount -a
}
local_base_umount # || exit 3
# should be 0
NUM=`losetup -a |grep -c -v home`
if [ $NUM -gt 0 ] ; then
losetup -a |grep -v home
echo losetup still mounted
exit 5
fi
sleep 10
umount -a -t ntfs-3g
# should be 1
NUM=`ps ax | grep mount.ntfs-3g | grep -v grep | wc -l`
if [ $NUM -ge 1 ] ; then
ps ax | grep mount.ntfs-3g | grep -v grep
echo ERROR: mount.ntfs-3g still running
exit 6
fi
INFO Calling shutdown
if [ $# -lt 1 ] ; then
shutdown -r now
else
shutdown $*
fi

View file

@ -0,0 +1,88 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; encoding: utf-8-unix -*-
set -e
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash
ROLE=base
. /usr/local/bin/usr_local_tput.bash
error () { ERROR "$0 $2" ; exit $1 ; }
VERS=15.0.1.5.4
TYPE=XFCE
HTTP_DIR=/g/Privacy/net/Http
URL=download.whonix.org/ova/$VERS/Kicksecure-${TYPE}-$VERS
TMPDIR=URL=$HTTP_DIR/download.whonix.org/ova/
NBD_DEV=/dev/nbd1
if [ ! -f $HTTP_DIR/$URL.ova ] ; then
wget -xcP $HTTP_DIR/ https://$URL.ova || error 2 wget
fi
[ -d $TMPDIR ] || mkdir -p $TMPDIR || error 3 $TMPDIR
cd $TMPDIR || error 4 cd $TMPDIR
if [ ! -f Kicksecure-${TYPE}-$VERS-disk001.vmdk ] ; then
echo INFO: $HTTP_DIR/$URL.ova
tar xvf $HTTP_DIR/$URL.ova || error 4 tar
fi
if [ ! -f Kicksecure-${TYPE}-${VERS}-disk001.qcow2 ] ; then
echo INFO: Kicksecure-${TYPE}-$VERS-disk001.qcow2
qemu-img convert -O qcow2 Kicksecure-${TYPE}-$VERS-disk001.vmdk Kicksecure-${TYPE}-$VERS-disk001.qcow2
fi
# must be run as root
if [ "$( id -u )" != "0" ] ; then
echo ERROR: $0 run as root
exit 0
fi
if [ "$#" -eq "0" ] ; then
root=/mnt/qcow2/KickXFCE150154
else
root=$1
fi
[ -d "$root" ] || mkdir $root
if [ ! -d "$root" ] ; then
error 3 "give an absolute directory name for chroot - $root"
fi
if [ ! -e ${NBD_DEV}p1 ] ; then
echo INFO: qemu-nbd -c ${NBD_DEV} Kicksecure-${TYPE}-$VERS-disk001.qcow2
qemu-nbd -c ${NBD_DEV} Kicksecure-${TYPE}-${VERS}-disk001.qcow2
fi
fdisk -l ${NBD_DEV} | grep ${NBD_DEV}p1 || exit 6
df | grep " $root" || mount ${NBD_DEV}p1 $root
[ -d /usr/local/tmp/wheels ] || \
( cd /usr/local/tmp ; bash /usr/local/sbin/bootstrap_wheels.bash ; )
[ -d $root/usr/local/tmp ] || \
{ mkdir $root/usr/local/tmp ; chmod 1777 $root/usr/local/tmp ; }
[ -d $root/usr/local/tmp/wheels ] || \
cp -rip /usr/local/tmp/wheels $root/usr/local/tmp/wheels
[ -d $root/usr/local/sbin ] || \
{ mkdir $root/usr/local/sbin ; }
[ -f $root/usr/local/sbin/bootstrap_pip_ansible.bash ] || \
{ cp -p /usr/local/sbin/bootstrap_*.bash $root/usr/local/sbin ; }
[ -d $root/usr/local/etc/ssl ] || \
{ mkdir $root/usr/local/etc/ssl ; }
[ -f /usr/local/etc/ssl/cacert-testforge.pem -a \
! -f $root//usr/local/etc/ssl/cacert-testforge.pem ] && \
cp -p /usr/local/etc/ssl/cacert-testforge.pem $root/usr/local/etc/ssl/cacert-testforge.pem
. /usr/local/bin/proxy_export.bash
echo INFO: /usr/local/sbin/update_chroot.bash $root
echo BOX_DEBIAN10_VAR_APT_ARCHIVES=/mnt/o/Cache/Apt/Debian/10.6/var/cache/apt/archives
echo BOX_BOXUSER_PLAY_PIP_CACHE=/mnt/o/Cache/Pip
echo BOX_USER_NAME=user
echo export http_proxy=$http_proxy
echo export https_proxy=$https_proxy
echo export socks_proxy=$socks_proxy
echo /usr/local/sbin/bootstrap_pip_ansible.bash

View file

@ -0,0 +1,56 @@
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
ROLE=hostvms
export LANG=en_US.UTF-8
kernel=5.0.8-pentoo
hostname=pentoo
cd /lib/modules/$kernel
# These interfere with installing virtualbox-guest-additions requried for vboxsf
[ -f kernel/drivers/staging/vboxvideo/vboxvideo.ko.xz ] && \
mv kernel/drivers/staging/vboxvideo/vboxvideo.ko.xz kernel/drivers/staging/vboxvideo/vboxvideo.ko.xz.dst
[ -f kernel/drivers/virt/vboxguest/vboxguest.ko.xz ] && \
mv kernel/drivers/virt/vboxguest/vboxguest.ko.xz kernel/drivers/virt/vboxguest/vboxguest.ko.xz.dst
depmod -a 5.0.8-pentoo
cd /etc/modprobe.d/
if [ ! -f blacklist.conf.dst ] ; then
mv blacklist.conf blacklist.conf.dst
cp blacklist.conf.dst blacklist.conf
fi
# maybe not all are needed
for elt in drm vbox video ttm ; do
grep "blacklist $elt" blacklist.conf || \
echo "blacklist $elt" >> blacklist.conf
done
cd /etc/ssh/
if [ ! -f sshd_config.dst ] ; then
mv sshd_config sshd_config.dst
cp sshd_config.dst sshd_config
fi
#FixMe: nano sshd_config
rc-update add NetworkManager
rc-update add sshd default
cd /root/
date_slash=$( date +%Y/%m/%d )
[ -d var/tmp/$hostname/$date_slash ] || mkdir -p var/tmp/$hostname/$date_slash
cd var/tmp/Pentoo/$date_slash
eix brltty | grep -q Installed && \
emerge -C brltty>emerge-C_brltty.log 2>&1
if [ ! /etc/portage/make.conf.dst ] ; then
mv /etc/portage/make.conf /etc/portage/make.conf.dst
cp /etc/portage/make.conf.dst /etc/portage/make.conf
fi
# FixMe: nano /etc/portage/make.conf
emerge -fp =app-emulation/virtualbox-guest-additions-6.0.6>virtualbox-guest-additions-6.0.6.lis 2>&1
# get the files...
emerge -vb =app-emulation/virtualbox-guest-additions-6.0.6>virtualbox-guest-additions-6.0.6.log 2>&1
rc-update add virtualbox-guest-additions

View file

@ -0,0 +1,509 @@
#!/bin/bash -e
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
PREFIX=/usr/local
ROLE=base
shopt -o -s pipefail
DEBUG=1
. /usr/local/bin/usr_local_tput.bash
[ $( id -u ) -eq 0 ] || { ERROR "this must be run as root" ; exit 1 ; }
. /usr/local/bin/proxy_export.bash
WD=$PWD
MV=mv
COPY="ln -s"
PYVER=3
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$BASE_PYTHON2_MINOR" ] && \
BASE_PYTHON2_MINOR=$( python2 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
[ -z "$BASE_PYTHON3_MINOR" ] && \
BASE_PYTHON3_MINOR=$( python3 --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
if [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib
elif [ -z "$LIB" -a -d /usr/lib64/python$PYTHON_MINOR/site-packages ] ; then
LIB=lib64
elif [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/dist-packages ] ; then
LIB=lib
mkdir -p /usr/local/lib/python$PYTHON_MINOR/site-packages
ln -s /usr/local/lib/python$PYTHON_MINOR/dist-packages \
/usr/local/lib/python$PYTHON_MINOR/site-packages
elif [ -z "$LIB" -a -d /usr/lib/python$PYTHON_MINOR/dist-packages ] ; then
LIB=lib64
mkdir -p /usr/local/lib64/python$PYTHON_MINOR/site-packages
ln -s /usr/local/lib64/python$PYTHON_MINOR/dist-packages \
/usr/local/lib64/python$PYTHON_MINOR/site-packages
elif [ -z "$LIB" -a -d /usr/lib/python$PYVER/dist-packages ] ; then
LIB=lib
mkdir -p /usr/local/lib/python$PYTHON_MINOR/site-packages
ln -s /usr/local/lib/python$PYTHON_MINOR/dist-packages \
/usr/local/lib/python$PYTHON_MINOR/site-packages
elif [ -z "$LIB" -a -d /usr/lib/python$PYVER/dist-packages ] ; then
LIB=lib64
mkdir -p /usr/local/lib64/python$PYTHON_MINOR/site-packages
ln -s /usr/local/lib64/python$PYTHON_MINOR/dist-packages \
/usr/local/lib64/python$PYTHON_MINOR/site-packages
fi
if [ -z "$LIB" ] ; then
ERROR LIB=$LIB empty - no /usr/lib*/python$PYTHON_MINOR/site-packages
exit 3
elif [ -n "$LIB" -a ! -d /usr/$LIB/python$PYTHON_MINOR/site-packages ] ; then
ERROR LIB=$LIB but no /usr/$LIB/python$PYTHON_MINOR/site-packages
exit 3
fi
INFO LIB=$LIB /usr/$LIB/python$PYTHON_MINOR/site-packages
[ -z "$UPTMP" ] && UPTMP=$PREFIX/tmp
# With packer the files we need are not on the host - they are pushed up and $UPTMP is populated with:
PDIRS="authorized_keys archives boxuser_pip_cache root_pip_cache cacert.pem wheels"
# With vagrant the files may have been tarred on the host and be in their cannonical positions.
# We symlink to files under vagrant to /tmp to leave the packer scripts untouched.
# With packer and docker we can remote mount partitions and not even copy them up to the guest.
[ -n "$TESTF_DEBIAN10_VAR_APT_ARCHIVES" ] && [ -d "$TESTF_DEBIAN10_VAR_APT_ARCHIVES/" ] && \
[ ! -e $UPTMP/archives ] && ln -s $TESTF_DEBIAN10_VAR_APT_ARCHIVES/ $UPTMP/archives
ln -s $TESTF_DEBIAN10_VAR_APT_ARCHIVES/*.deb /var/cache/apt/archives 2>/dev/null
[ -n "$HOSTVMS_BOXUSER_PLAY_PIP_CACHE" ] && [ -e "$HOSTVMS_BOXUSER_PLAY_PIP_CACHE" ] && \
[ ! -e $UPTMP/boxuser_pip_cache ] && ln -s $HOSTVMS_BOXUSER_PLAY_PIP_CACHE/ $UPTMP/boxuser_pip_cache
[ -n "$HOSTVMS_ROOT_PLAY_PIP_CACHE" ] && [ -d "$HOSTVMS_ROOT_PLAY_PIP_CACHE/" ] && \
[ ! -e $UPTMP/root_pip_cache ] && ln -s "$HOSTVMS_ROOT_PLAY_PIP_CACHE/" $UPTMP/root_pip_cache
[ -d /usr/local/etc/testforge ] || mkdir -p /usr/local/etc/testforge
export PLAY_PIP_CERT="/usr/local/etc/ssl/cacert-testforge.pem"
[ -f $PLAY_PIP_CERT ] && \
[ ! -e $UPTMP/cacert.pem ] && ln -s $PLAY_PIP_CERT $UPTMP/cacert.pem
# config_file = os.environ.get('PIP_CONFIG_FILE', None)
# /usr/$LIB/python2.7/site-packages/pip/_internal/configuration.py
bootstrap_mkdir () { mkdir -p $1 ; chgrp $BOX_ALSO_GROUP $1 ; }
[ -d /usr/local/tmp ] || { mkdir -p /usr/local/tmp ; chmod 1777 /usr/local/tmp ; }
site_packages=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages
[ -d $site_packages ] || bootstrap_mkdir $site_packages
[ -f $site_packages/__init__.py ] || touch $site_packages/__init__.py
if [ ! -d /usr/local/tmp/wheels ] ; then
cd /usr/local
sh sbin/bootstrap_wheels.bash || exit 4
fi
[ ! -d $UPTMP/wheels/ ] && [ $UPTMP/ != /usr/local/tmp/ ] && \
ln -s /usr/local/tmp/wheels $UPTMP/wheels
# But with vagrant or docker we may have mounted the HOST partitions that contain the files
# [ -z "$TESTF_UBUNTU16_VAR_APT_ARCHIVES" ] && TESTF_UBUNTU16_VAR_APT_ARCHIVES -> $UPTMP/archives
[ -d /etc/portage -a -z "$BOX_USER_NAME" ] && BOX_USER_NAME=vagrant
[ -d /etc/apt -a -z "$BOX_USER_NAME" ] && BOX_USER_NAME=devuan
[ -z "$BOX_USER_HOME" ] && BOX_USER_HOME=/home/$BOX_USER_NAME
[ -z "$BOX_ALSO_GROUP" ] && BOX_ALSO_GROUP=adm
[ -z "$LOGDIR" ] && LOGDIR=$PREFIX/tmp
[ -d $LOGDIR ] || { mkdir $LOGDIR ; chmod 1777 $LOGDIR ; }
# not needed: --no-binary :all: --upgrade-strategy only-if-needed
# not yet: --user
PIP_ARGS=""
PIP_INSTALL_ARGS="--disable-pip-version-check --prefix=$PREFIX"
scripts="ansible ansible-playbook ansible-pull ansible-doc ansible-galaxy ansible-console ansible-connection ansible-vault"
[ -d /etc/apt ] && export DEBIAN_FRONTEND=noninteractive
export PIP_DEFAULT_TIMEOUT=60
ANSIBLE_VER="2.9.10"
#2? PYYAML_VER="3.12"
ansible_tgz=ansible-$ANSIBLE_VER.tar.gz
#2? yaml_tgz=PyYAML-$PYYAML_VER.tar.gz
if [ -n "$BOX_USER_NAME" ] ; then
# Packer will not have created this and we will need it early.
[ -d $BOX_USER_HOME ] || \
bootstrap_mkdir $BOX_USER_HOME
#? useradd -d $BOX_USER_HOME -G root -m $BOX_USER_NAME
# If you want to use your own private key for packer
[ -d $BOX_USER_HOME/.ssh ] || \
bootstrap_mkdir $BOX_USER_HOME/.ssh
if [ -f $UPTMP/authorized_keys ] ; then
$COPY $UPTMP/authorized_keys $BOX_USER_HOME/.ssh && \
chmod 600 $BOX_USER_HOME/.ssh/authorized_keys
fi
chmod 700 $BOX_USER_HOME/.ssh/
fi
[ -d /etc/apt -a -d /var/cache/apt/archives ] || mkdir -p /var/cache/apt/archives
# If you upload your cache of Ubuntu .debs, it cuts down on the downloading
[ -d $UPTMP/archives ] && \
$COPY $UPTMP/archives/*.deb /var/cache/apt/archives 2>/dev/null
# leave this for cleanup:
# rm -rf $UPTMP/archives
# If you upload your cache of pip files, it cuts down on the downloading
if [ -d $UPTMP/boxuser_pip_cache ] ; then
bootstrap_mkdir $BOX_USER_HOME/.cache/ && \
cp -rip $UPTMP/boxuser_pip_cache $BOX_USER_HOME/.cache/pip && \
chown -R ${BOX_USER_NAME}.{BOX_ALSO_GROUP} $BOX_USER_HOME/.cache/pip && \
chmod -R g+rw $BOX_USER_HOME/.cache/pip && \
chmod -R o-w $BOX_USER_HOME/.cache/pip
fi
if [ -d $UPTMP/root_pip_cache ] ; then
bootstrap_mkdir /root/.cache/ && \
cp -rip $UPTMP/root_pip_cache /root/.cache/pip && \
chown -R root.root /root/.cache/pip && \
chmod -R g+rw /root/.cache/pip && \
chmod -R o-w /root/.cache/pip
fi
if [ -d /etc/apt ] ; then
if ! route | grep -q ^default ; then
DBUG "Not connected; skipping apt-get update"
elif [ ! -f /var/log/dpkg.log ] ; then
apt-get update # || exit 4
fi
which unzip || ! [ -f /var/cache/apt/archives/unzip_*_amd64.deb ] || \
dpkg -i /var/cache/apt/archives/unzip_*_amd64.deb
which curl || [ ! -f /var/cache/apt/archives/curl_*_amd64.deb ] || \
dpkg -i /var/cache/apt/archives/curl_*_amd64.deb \
/var/cache/apt/archives/libcurl4_*_amd64.deb \
/var/cache/apt/archives/libcurl4-openssl-dev_*_amd64.deb
apt-get install -y --force-yes wget unzip openssl || true
[ -f /usr/include/Python.h ] || \
apt-get install -y --force-yes \
libffi-dev libssl-dev python3-dev python3-pycparser \
python3-coverage || \
echo WARN you must run apt-get update
# msg: Could not find `coverage` module. ?python3-apt ?
elif [ -d /etc/portage ] ; then
# FixMe: put these in wheels?
[ -x /usr/bin/unzip ] || which unzip 2>/dev/null || emerge -vb app-arch/unzip
[ -x /usr/bin/wget ] || which wget 2>/dev/null || emerge -vb net-misc/wget
which openssl 2>/dev/null || timeout 600 emerge -vb dev-libs/openssl
# openssl installs:
# dev-python/pyopenssl-19.1.0
# dev-python/six-1.13.0
# dev-python/cryptography-2.8
# dev-python/cffi-1.12.3:0/1.12.3
# dev-python/pycparser-2.19-r1
# dev-python/ply-3.11:0/3.11
# virtual/python-ipaddress-1.0-r1
# dev-python/ipaddress-1.0.23
# virtual/python-enum34-2
# dev-python/enum34-1.1.6-r1
python$PYVER -c 'import OpenSSL' 2>/dev/null || \
timeout 600 emerge -vb dev-python/pyopenssl
python$PYVER -c 'import pycparser' 2>/dev/null || \
timeout 600 emerge -vb dev-python/pycparser
python$PYVER -c 'import yaml' 2>/dev/null || \
timeout 600 emerge -vb dev-python/pyyaml
DBUG "Gentoo Installed openssl and wget"
fi
# On a CORP laptop off the VPN we may need some CAs
[ -d $PREFIX/etc/ssl ] || mkdir -p $PREFIX/etc/ssl
[ ! -f $PLAY_PIP_CERT ] && \
[ -f $UPTMP/cacert.pem ] && \
$COPY $UPTMP/cacert.pem $PLAY_PIP_CERT
# pip gets confused
# or just delete $PREFIX/$LIB/python$PYTHON_MINOR/dist-packages afterwards
PYTHON_MINOR=$( python$PYVER --version 2>&1| sed -e 's@^.* @@' -e 's@\.[0-9]*$@@' )
site_packages=$PREFIX/$LIB/python$PYTHON_MINOR/site-packages
[ -d $site_packages ] || bootstrap_mkdir $site_packages
[ -f $site_packages/__init__.py ] || touch $site_packages/__init__.py
if [ -d /etc/apt ] ; then
dist_packages=$PREFIX/lib/python$PYTHON_MINOR/dist-packages
WD=$PWD
if [ -d $dist_packages ] ; then
cd $PREFIX/lib/python$PYTHON_MINOR
ln -s $site_packages .
cd $WD
fi
fi
# we will use $PREFIX/bin/python3.bash NOT $PREFIX/bin/python3.sh
# to not conflict with what Ansible will push later/before.
if [ ! -e $PREFIX/bin/python$PYVER.bash ] ; then
INFO "bootstrapping $PREFIX/bin/python$PYVER.bash"
cat > $PREFIX/bin/python$PYVER.bash << EOF
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
# from bootstrap_pip_ansible.bash
. /usr/local/bin/usr_local_tput.bash || exit 2
PREFIX=/usr/local
# pip gets confused
dist_packages=$site_packages
dist_packages=\$dist_packages:\${dist_packages}/pip/_vendor
if [ -z "$PYTHONPATH" ] ; then
export PYTHONPATH=\$dist_packages
else
export PYTHONPATH=\$PYTHONPATH:\$dist_packages
fi
exec python$PYVER "\$@"
EOF
chmod 755 $PREFIX/bin/python$PYVER.bash
fi
# pip may be loaded in the base iso
if [ -x $PREFIX/bin/python$PYVER.bash ] && \
$PREFIX/bin/python$PYVER.bash -c 'import pip' 2>/dev/null ; then
INFO pip$VER already installed
elif [ ! -d $UPTMP/wheels/ ] ; then
WARN $UPTMP/wheels not found
else
# we may be without the VPN/proxy but on a corporate laptop
# with a hosed chain of Certificate Authorities for the MITM proxy
# in which case http://bootstrap.pypa.io/get-pip.py will not work,
# so effective but groddy:
# just unzip the wheels into site-packages and force-reinstall later
cd $UPTMP/wheels/
INFO "installing pip - unzipping wheels into $site_packages"
for file in *.whl ; do
#a=$( echo $file | sed -e 's/-.*//' )
#b=$( basename $a|sed -e 's/Py//'|tr '[A-Z]' '[a-z]' )
#python$PYVER -c "import $b" 2>/dev/null >/dev/null && continue
unzip -n $file -d $site_packages >/dev/null
done
# morons
# -rwx------ 1 root root 8866 Jun 11 2018 /usr/local/$LIB/python$PYTHON_MINOR/site-packages/idna-2.7.dist-info/METADATA
find $site_packages -type d -exec chmod a+rx '{}' \;
find $site_packages -type f -exec chmod a+r '{}' \;
chgrp -R "$BOX_ALSO_GROUP" $site_packages
# hack in a PYTHONPATH for our unzipped wheels - removed later
for elt in pip ; do # is wheel needed?
INFO "Installing $elt"
# use $PYVER.bash for bootstrap - $PYVER.bash will come later
[ -f $PREFIX/bin/$elt$PYVER.bash ] || \
cat > $PREFIX/bin/$elt$PYVER.bash << EOF
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
export PLAY_PIP_CERT=$PIP_CERT
export PYTHONPATH=${site_packages}
export PYTHONPATH=\$PYTHONPATH:${site_packages}/pip/_vendor
#? FixMe: narrow to InsecurePlatformWarning
python$PYVER -W ignore -m $elt "\$@"
EOF
chmod 755 $PREFIX/bin/$elt$PYVER.bash
$PREFIX/bin/$elt$PYVER.bash --help >/dev/null
DBUG "Installed $elt$PYVER.bash"
done
fi
# do I still need this
#if [ -x $PREFIX/bin/pip$PYVER ] && [ -d $site_packages ] ; then
# export PYTHONPATH=$site_packages:$site_packages/pip/_vendor
#fi
if [ ! -x $PREFIX/bin/pip$PYVER.sh ] ; then
ERROR "Failed to Install pip$PYVER at $PREFIX/bin/pip$PYVER.sh"
exit 3
elif ! $PREFIX/bin/python$PYVER.bash -m pip -V ; then
ERROR "Failed to run pip$PYVER at $PREFIX/bin/pip$PYVER"
exit 4
fi
if [ -f $PLAY_PIP_CERT ] ; then
if [ ! -f $site_packages/pip/_vendor/requests/cacert.pem.dst ] && \
[ -f $site_packages/pip/_vendor/requests/cacert.pem ] && \
[ ! -h $site_packages/pip/_vendor/requests/cacert.pem ] ; then
mv $site_packages/pip/_vendor/requests/cacert.pem \
$site_packages/pip/_vendor/requests/cacert.pem.dst
fi
if [ ! -h $site_packages/pip/_vendor/requests/cacert.pem ] ; then
rm -f $site_packages/pip/_vendor/requests/cacert.pem
fi
[ -e $site_packages/pip/_vendor/requests/cacert.pem ] || \
ln -s $PLAY_PIP_CERT $site_packages/pip/_vendor/requests/cacert.pem
INFO linked $PLAY_PIP_CERT $site_packages/pip/_vendor/requests/cacert.pem
fi
# dont use -CAfile $UPTMP/cacert.pem - we want it to fail if we need the cert
if ! route | grep -q ^default ; then
DBUG "Not connected; skipping SSL Certificate Authority chain"
elif [ -n "$https_proxy" ] ; then
proxy=`echo "$https_proxy" | sed -e 's/https*:\/*//'`
openssl s_client -connect pypi.org:443 --proxy $proxy </dev/null | \
grep -q 'unable to get local issuer certificate' && \
echo "WARN: it looks like you have a hosed SSL Certificate Authority chain"
else
openssl s_client -connect pypi.org:443 </dev/null | \
grep -q 'unable to get local issuer certificate' && \
echo "WARN: it looks like you have a hosed SSL Certificate Authority chain"
fi
$PREFIX/bin/pip$PYVER.sh --version || exit 5
[ -d /usr/local/src ] || { bootstrap_mkdir /usr/local/src ; }
[ -d /usr/local/bin ] || { bootstrap_mkdir /usr/local/bin ; }
if [ -f "$PLAY_PIP_CERT" ] ; then
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS --cert $PLAY_PIP_CERT"
else
WARN "PLAY_PIP_CERT not found $PIP_CERT"
fi
if [ ! -f /etc/wgetrc ] ; then
sh $WD/bootstrap_proxy.bash
fi
# pip uses curl - and has a config file PIP_CONFIG
DBUG "http_proxy=$http_proxy https_proxy=$https_proxy"
if [ -n "$https_proxy" ] ; then
INFO "Adding to PIP_INSTALL_ARGS --proxy=$https_proxy"
elif [ -f /etc/wgetrc ] && grep ^http_proxy /etc/wgetrc ; then
proxy=$( grep ^http_proxy /etc/wgetrc|sed -e 's@.*=@--proxy=@' )
INFO "Adding to PIP_INSTALL_ARGS $proxy"
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS $proxy"
fi
# lengthen the timeout in case you are on a slow line
# or /etc/pip.conf
# [global]
# timeout = 60
cd $PREFIX/src || exit 6
boostrap_pip_ansible () {
local WD=$PWD
DBUG "$PREFIX/bin/pip$PYVER.sh install $PIP_INSTALL_ARGS $UPTMP/wheels/$ansible_tgz"
# install from the file to keep the version pinned
sudo -u $"$BOX_USER_NAME" \
$PREFIX/bin/pip$PYVER.sh $PIP_ARGS install \
$PIP_INSTALL_ARGS $UPTMP/wheels/$ansible_tgz \
>> $LOGDIR/pip_install_pip_ansible.log 2>&1 || {
ERROR pip$PYVER.sh $PIP_ARGS install $PIP_INSTALL_ARGS $ansible_tgz
tail $LOGDIR/pip_install_pip_ansible.log
exit 8
}
return 0
}
boostrap_patch_ansible () {
local WD=$PWD
[ -d /usr/local/patches/base ] || return 0
[ -f /usr/local/sbin/base_patch_from_diff.bash ] || return 0
cd /usr/local/patches/base || return 1
[ -d usr/local/src/ansible-$ANSIBLE_VER ] || return 0
# this vacuumns all diff files below the root
/usr/local/sbin/base_patch_from_diff.bash usr/local/src/ansible-$ANSIBLE_VER
return 0
}
boostrap_setup_ansible () {
local WD=$PWD
cd /usr/local/src
[ -d ansible-$ANSIBLE_VER ] || tar xfz $UPTMP/wheels/$ansible_tgz
cd ansible-$ANSIBLE_VER
/usr/local/sbin/base_patch_from_diff.bash usr/local/src/ansible-$ANSIBLE_VER
RARGS=" --user $RARGS"
# RARGS=" --install-layout=unix $RARGS"
export PYTHONPATH=/usr/local/$LIB/python$PYTHON_MINOR/site-packages
DBUG "/usr/local/bin/python$PYVER.bash setup.py install $RARGS"
sudo -u $"$BOX_USER_NAME" \
/usr/local/bin/python$PYVER.bash setup.py install $RARGS \
>> install.log
retval=$?
cd $WD
return $retval
}
# NOW we use our fresh pip to install ansible from source, into /usr/local
if [ -d $PREFIX/src/ansible-$ANSIBLE_VER ] ; then
INFO already installed $PREFIX/src/ansible-$ANSIBLE_VER
elif [ ! -f $UPTMP/wheels/$ansible_tgz ] ; then
ERROR tgz missing $UPTMP/wheels/$ansible_tgz
exit 7
else
if false ; then
boostrap_pip_ansible
else
boostrap_setup_ansible
[ $? -eq 0 ] || { ERROR installing ansible ; tail install.log ; exit 8 ; }
fi
boostrap_patch_ansible
if [ -d /etc/portage/ ] ; then
[ -d /etc/portage/profile ] || mkdir /etc/portage/profile
grep -q app-admin/ansible-$ANSIBLE_VER /etc/portage/profile/package.provided || \
echo app-admin/ansible-$ANSIBLE_VER >> /etc/portage/profile/package.provided
fi
cd $PREFIX/bin
[ -e ansible-doc ] || { ERROR installing ansible-doc ; exit 9 ; }
grep "#\!.$PREFIX/bin/python$PYVER.bash" ansible-doc || \
sed -e "s@^#\!.*python.*@#\!${PREFIX}/bin/python$PYVER.bash@" -i $scripts
fi
ansible --version || exit 10
if [ -f $PLAY_PIP_CERT ] ; then
export PLAY_PIP_CERT=$PIP_CERT
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS --cert $PLAY_PIP_CERT"
else
WARN "PLAY_PIP_CERT not found $PIP_CERT"
fi
[ ! -f /etc/wgetrc ] || sh $WD/bootstrap_proxy.bash
# pip uses curl - and has a config file PIP_CONFIG
DBUG "http_proxy=$http_proxy https_proxy=$https_proxy"
if [ -n "$https_proxy" ] ; then
INFO "Adding to PIP_INSTALL_ARGS --proxy=$https_proxy"
elif [ -f /etc/wgetrc ] && grep ^http_proxy /etc/wgetrc ; then
proxy=$( grep ^http_proxy /etc/wgetrc|sed -e 's@.*=@--proxy=@' )
INFO "Adding to PIP_INSTALL_ARGS $proxy"
PIP_INSTALL_ARGS="$PIP_INSTALL_ARGS $proxy"
fi
cd $PREFIX/src
# install pycurl as a test of pip and a requisite for proxyauth.py
if ! $PREFIX/bin/python$PYVER.bash -c 'import curl' 2>/dev/null ; then
if [ -d /etc/apt ] ; then
apt-get install -y --force-yes libcurl4-openssl-dev \
2>&1 | tee $LOGDIR/apt-get_install_libcurl4-openssl-dev.log
elif [ -d /etc/portage ] ; then
[ -x /usr/bin/curl ] || which curl 2>/dev/null || emerge -vb curl
fi
#? --allow-unverified pycurl
if ! route | grep -q ^default ; then
INFO "Not connected; not installing pycurl"
elif $PREFIX/bin/pip$PYVER.sh install $PIP_INSTALL_ARGS pycurl >> $LOGDIR/pip_install_pycurl.log 2>&1 ; then
INFO "Installed pycurl from pip with $PREFIX/bin/pip install $PIP_INSTALL_ARGS"
# We dont fail the packer build if it errors - just fix it and rerun
$PREFIX/bin/python$PYVER.bash -c 'import curl; print curl.__file__' || true
else
WARN "Installing pycurl failed with $PREFIX/bin/pip install $PIP_INSTALL_ARGS"
cat $LOGDIR/pip_install_pycurl.log
fi
fi
[ -e /usr/local/bin/python$PYVER.sh ] || \
[ -h /usr/local/bin/python$PYVER.sh ] || \
ln -s /usr/local/bin/python$PYVER.bash /usr/local/bin/python$PYVER.sh
find /usr/local/$LIB/python$PYTHON_MINOR/site-packages/ansible/modules/ -name \*.py \
-exec grep -q /usr/bin/python '{}' \; -print \
-exec sed -e "1,3s@#!/usr/bin/python@#!/usr/local/bin/python$PYVER.bash@" -i '{}' \;
exit 0

View file

@ -0,0 +1,61 @@
#!/bin/bash
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
set -e
shopt -o -s pipefail
prog=$( basename $0 .bash )
ROLE=base
. /usr/local/bin/usr_local_tput.bash
[ -z "$UPTMP"] && UPTMP=/usr/local/tmp
# [ $( id -u ) -eq 0 ] || { ERROR "this must be run as root" ; exit 1 ; }
# consider PIP_CONFIG_FILE [defaults] ini
export PLAY_PIP_CERT="/usr/local/etc/ssl/cacert-testforge.pem"
if [ -n "$http_proxy" ] || [ -n "$https_proxy" ] ; then
INFO "proxy.sh YES http_proxy=$http_proxy https_proxy=$https_proxy"
if [ -d /etc/portage ] ; then
grep ^http_proxy /etc/portage/make.conf || \
cat >> /etc/portage/make.conf << EOF
# BEGIN ANSIBLE MANAGED BLOCK proxy
http_proxy="$http_proxy"
https_proxy="$https_proxy"
# END ANSIBLE MANAGED BLOCK proxy
EOF
elif [ ! -f /etc/apt/apt.conf.d/80proxy.conf ] || ! grep -q Proxy /etc/apt/apt.conf.d/80proxy.conf ; then \
cat > /etc/apt/apt.conf.d/80proxy.conf << EOF
# BEGIN ANSIBLE MANAGED BLOCK proxy
Acquire::http::Proxy "$http_proxy";
Acquire::https::Proxy "$https_proxy";
# END ANSIBLE MANAGED BLOCK proxy
EOF
fi
# FixMe: should be able to remove check_certificate = off now
[ -z "$no_proxy" ] && no_proxy=localhost,127.0.0.1
if [ ! -f /etc/wgetrc ] || grep -q "^http_proxy=$http_proxy" /etc/wgetrc ; then
cat >> /etc/wgetrc << EOF
# BEGIN ANSIBLE MANAGED BLOCK proxy
http_proxy=$http_proxy
https_proxy=$https_proxy
no_proxy=$no_proxy
ca-certificate=$PLAY_PIP_CERT
check_certificate = on
quiet = on
# END ANSIBLE MANAGED BLOCK proxy
EOF
fi
else
INFO "proxy.sh NO http_proxy=$http_proxy https_proxy=$https_proxy"
grep -q "^check_certificate = on" /etc/wgetrc || \
cat >> /etc/wgetrc << EOF
# BEGIN ANSIBLE MANAGED BLOCK proxy
check_certificate = on
quiet = on
# END ANSIBLE MANAGED BLOCK proxy
EOF
fi
exit 0

View file

@ -0,0 +1,11 @@
#!/bin/bash
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
set -e
ROLE=base
WD=$PWD
cd tmp
exit 0
[ -d wheels ] || mkdir wheels
cd wheels

View file

@ -0,0 +1,62 @@
#!/bin/sh
# -*- mode: sh; tab-width: 8; coding: utf-8-unix -*-
# in box, unix generic, builder generic
ROLE=hostvms
PREFIX=/var/local
prog=$( basename $0 .bash )
. /usr/local/bin/usr_local_tput.bash
if [ -d /etc/portage ] ; then
# maybe we should delete ALL the package.use and package.mask?
# we did most of them as workarounds or to set the distfiles.zip
rm -f "/etc/portage/package.use/grub.sh"
fi
### CLEANUP TO SHRINK THE BOX ###
# a fresh install probably shouldn't nag about news
# chroot "" /usr/bin/eselect news read all > /dev/null 2>&1
INFO "delete in /tmp and /var/tmp"
rm -rf /tmp/*
rm -rf /var/tmp/*
# there's some leftover junk by gem installation in the root folder
# don't know where this is from (/root/.gem/specs/rubygems.org%80/...), but it should go...
# we use a global ruby by default
# ...probably hard coded path by mistake, report to upstream? Which upstream?!?
[ -d /root/.gem ] && rm -rf /root/.gem
INFO "cleaning kernel"
ls -l /usr/src 2>/dev/null && \
for elt in /usr/src/linux-*/ ; do
[ -f .config ] || continue
INFO "kernel make clean in $elt"
[ -d "$elt" ] || continue
( cd "$elt" && make clean )
done
[ -f /root/bin/packer_clean_distfiles.bash ] && sh /root/bin/packer_clean_distfiles.bash
INFO "fill all free hdd space with zeros"
if df | grep /boot$ ; then
dd if=/dev/zero of="/boot/EMPTY" bs=1M 2>/dev/null
rm "/boot/EMPTY"
sync
fi
dd if=/dev/zero of="/EMPTY" bs=1M 2>/dev/null
rm "/EMPTY"
sync
INFO "fill all swap space with zeros and recreate swap"
cat /proc/swaps |grep ^/ | cut -f 1 -d ' '| while read dev ; do
swapoff $dev || continue
shred -n 0 -z $dev
# FixMe: label?
mkswap $dev
sync
done
exit 0

View file

@ -0,0 +1,51 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
prog=$( basename $0 .bash )
ROLE=base
LOG_DIR=/usr/local/var/logs/portage
[ -d $LOG_DIR ] || mkdir -p $LOG_DIR
declare -a ARGS
if [ "$#" -eq 1 ] ; then
ARGS=( "$1" )
LOG=$( basename $1 ).log
elif [ "$#" -eq 0 ] ; then
ARGS="@world"
LOG=world.log
elif false && [ -f world.lib ] ; then # ?
ARGS="$( grep -v '^#' world.lib )"
LOG=world.log
else
ARGS=("$@")
LOG=world.log
fi
if mount | grep -q ' on /mnt/tmp' ; then
export TMPDIR=/mnt/tmp
# else
# echo "WARN: /mnt/tmp not mounted"
fi
# --changed-deps --deep --update
LARGS="-vb --changed-use --with-bdeps=y --changed-deps-report"
LARGS="$LARGS --backtrack=30 --ignore-built-slot-operator-deps=y --keep-going"
# Skips the packages specified on the command-line that have already been installed.
LARGS="$LARGS --noreplace"
# LARGS="$LARGS --exclude "
LOG=$LOG_DIR/$LOG
export PYTHONPATH=
echo INFO: $LARGS $ARGS >> $LOG 2>&1
nice python$BASE_PYTHON3_MINOR $( which emerge ) $LARGS $ARGS >> $LOG 2>&1
[ $? -ne 0 ] && exit $?
if grep ImportError $LOG ; then
echo ERROR: ImportError $ARGS && exit 10
elif grep ParseError $LOG ; then
echo ERROR: ParseError $ARGS && exit 11
elif grep 'Your current profile is invalid' $LOG ; then
echo ERROR: Your current profile is invalid $ARGS && exit 12
fi
exit 0

View file

@ -0,0 +1,26 @@
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
# filter
ROLE=base
[ -z "$CACHE" ] && CACHE=/mnt/o/Cache/Apt/Debian/10.6
[ -d "$CACHE" ] || exit 1$?
[ -d /etc/apt ] || exit 0
cd $CACHE || exit 2
[ -d var/cache/apt/archives ] || mkdir -p var/cache/apt/archives
find *.deb -type f -name \*.deb | while read file; do
base=$( basename $file )
[ ! -d /var/cache/apt/archives/ ] || \
[ -e /var/cache/apt/archives/$base ] || ln -s $PWD/$file /var/cache/apt/archives/$base
[ -f var/cache/apt/archives/$base -a ! -h var/cache/apt/archives/$base ] && rm var/cache/apt/archives/$base
[ -e var/cache/apt/archives/$base ] || ln -s $PWD/$file var/cache/apt/archives/$base
done
exit 0

View file

@ -0,0 +1,13 @@
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
ROLE=base
[ "$#" -eq 0 ] && set -- *.elts
for elt in "$@" ; do
base=$( basename $elt .elts )
[ -f $base.uris ] && continue
apt-get install --print-uris $( cat $elt ) > $base.uris 2>$base.errs
done
exit 0

View file

@ -0,0 +1,31 @@
#!/bin/sh
# -*-mode: sh; tab-width: 8; coding: utf-8-unix -*-
# filter or .uris
ROLE=base
[ -z "$CACHE" ] && CACHE=/mnt/o/Cache/Apt/Debian/10.6
[ -d "$CACHE" ] || mkdir $CACHE # || exit 1$?
# debian --print-uris
if [ $? -eq 0 ] ; then
# filter
grep 'https*://' | \
sed -e 's@ftp://[^ ]*@@g' -e 's@.*https*://@https://@g' -e "s@'.*@@g" | \
while read line ; do
for url in $line ; do
base=`basename "$url"`
pre=`sed -e "s@https*://@${CACHE}@" <<< $url`
[ -e $pre ] && break
echo $line
break
done
done
fi
for elt in "$@" ; do
base=$( basename $elt .elts )
[ -s $base.urls ] && continue
sh $0 < $elt > $base.urls
[ -s $base.urls ] || rm $base.urls
done
exit 0

View file

@ -0,0 +1,70 @@
#!/bin/bash
# filter - arguments are to wget - quoted?
prog=$( basename $0 .bash )
prog=ScurlU
ROOTDIR=/mnt/i/net/Http
ROLE=base
CACHE=/usr/portage/distfiles
. /usr/local/bin/proxy_curl_lib.bash
route | grep -q ^def || { echo ERROR: not connected ; exit 1 ; }
. /usr/local/bin/usr_local_tput.bash
FETCHCOMMAND='/usr/local/bin/scurl.bash --force-directories --directory-prefix "\${DISTDIR}" -- "\${URI}"'
# RARGS="--retry 1 --connect-timeout 10"
if [ "$#" -eq 0 ] ; then
LARGS="--force-directories --directory-prefix $ROOTDIR"
else
LARGS="$@"
fi
cp /dev/null /tmp/$prog$$.urls
# //www.simplesystems.org/users/bfriesen/public-key.txt no https:
# https://opencoder.net/WayneDavison.key cloudflare 403
# https://www.simplesystems.org/users/bfriesen/public-key.txt 503
# https://tiswww.case.edu/php/chet/gpgkey.asc 500 timeout
# https://botan.randombit.net/pgpkey.txt no tls1.3
# https://sourceware.org/elfutils/ftp/gpgkey-1AA44BE649DE760A.gpg no tls1.3
# https://gnutls.org/gnutls-release-keyring.gpg no tls1.3
retval=0
# NOT 1.3 -e 's@^https://distfiles.gentoo.org/distfiles/[^ ]* https://pypi.python.org/@https://pypi.python.org/@'
grep ^http | \
sed -e 's@ftp://[^ ]*@@' \
-e 's/http:/https:/' \
-e 's@^https://distfiles.gentoo.org/distfiles/openpgp-keys-[^ ]*.asc @@' \
-e 's@https*://distfiles.gentoo.org@https://gentoo.osuosl.org@g' \
-e 's@https://gentoo.osuosl.org@https://mirror.leaseweb.com/gentoo@g' \
-e 's@https*://download.sourceforge.net@https://download.sourceforge.net@g' | \
while read urls ; do
url=`echo $urls|sed -e 's@ .*@@'`
base=`basename "$url"`
[ -e $CACHE/$base ] && echo $CACHE/$base && continue
base=`echo $url | sed -e 's@ .*@@' -e 's@https*://@@'`
[ -e $ROOTDIR/"$base" ] && echo $ROOTDIR/"$base" && continue
for url in $urls ; do
for no in "${NOTLSV3[@]}" ; do
[[ $url =~ $no ]] && continue
done
domain=`sed -e 's@/.*@@' <<< $base`
ip=`tor-resolve $domain`
if [ $? -eq 0 -a -n "$ip" ] ; then
a=`proxy_ami_cloudflared $ip`
[ $? -eq 0 -a "$a" = True ] && \
WARN $url Cloudflared $ip $no && \
continue
fi
DBUG $prog /usr/local/bin/scurl.bash $LARGS -- $RARGS $url
/usr/local/bin/scurl.bash $LARGS -- $RARGS $url || {
retval=$?
continue
}
break
done
done
exit $retval

View file

@ -0,0 +1,62 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
shopt -s nullglob || exit 1
prog=`basename $0 .bash`
ROLE=base
export PATH=/sbin:$PATH
PREFIX=/usr/local
. /usr/local/bin/usr_local_tput.bash || exit 2
DEST=$PREFIX/portage/testforge/sec-keys
FROM=/usr/portage/sec-keys
cd /
grep /~sam/ /usr/portage/sec-keys/*/*d| \
sed -e 's@.*/@@' -e 's/"//' -e 's/.*-//'|grep -v P | \
while read f;do
b=`ls /usr/portage/distfiles/*"$f"`|| continue;
a=`readlink "$b"`;
echo $a;[ -h "$a" ] && continue;
echo $b;
done | \
sed -e 's@\.\./\.\.@/i@'|zip -m9 --symlinks sam.zip -@
cd $FROM
#
tar cf - *-* | tar xf - --keep-newer-files -C $DEST 2>/dev/null >/dev/null
[ -d $DEST ] || mkdir -p $DEST
cd $FROM
i=0
for dir in *-*; do
[ -d $dir ] || continue
[ -d $DEST/$dir ] || mkdir $DEST/$dir
ls $dir/*ebuild >/dev/null 2>/dev/null || { WARN no *ebuild in $dir ; continue ; }
for file in $dir/*ebuild ; do
[ -f $DEST/$file ] && [ $DEST/$file -nt $FROM/$file ] && continue
sed -e 's/^LICENSE=/RESTRICT="mirror"\nLICENSE=/' > $DEST/$file < $FROM/$file
if grep -q 'Mirrored from ' $FROM/$file ; then
url="`grep 'Mirrored from ' $FROM/$file|sed -e 's/.*Mirrored from //' -e 's/ .*//'`"
if [ -n "$url" ] ; then
i=`expr $i + 1`
rep=`sed -e 's/[$]/\\\\$/g' -e 's/[&]/\\\\&/g' <<< $url`
# could change some keyservers here
rep=`sed -e 's/http:/https:/' <<< $rep`
DBUG rep="$rep"
sed -e "s@https://dev.gentoo.org/.sam/[^ \"]*@$rep@" \
-i $DEST/$file
fi
fi
cd $DEST/$dir
for dfile in $dir/*ebuild ; do
ddir=`dirname $dfile`
cd $ddir
ebuild manifest *ebuild
done
cd $DEST
done
done
INFO $i $DEST

View file

@ -0,0 +1,90 @@
# -*- mode: Makefile; tab-width: 8; coding: utf-8-unix -*-
PENV=env http_proxy=http://127.0.0.1:3128 \
https_proxy=http://127.0.0.1:3128 \
no_proxy="localhost,127.0.0.1"
NENV=env no_proxy=localhost,127.0.0.1 \
https_proxy= socks_proxy= http_proxy= \
default:: test
.SUFFIXES: .yml .json
.yml.json:
yaml2json.bash < $< > $@
test:: test_test test_net test_local
test_net::
$(MAKE) $(MFLAGS) TARGET=ipleak.net PDB="" ENV="$(PENV)" targets cleanup
$(MAKE) $(MFLAGS) TARGET=python.org PDB="" ENV="$(PENV)" targets cleanup
test_local::
$(MAKE) $(MFLAGS) TARGET=polipo PDB="" ENV="" targets cleanup
test_test::
which firefox || exit 0
$(NENV) /var/local/bin/python2.bash selenium_test.py test
$(MAKE) $(MFLAGS) cleanup
test_keepassxc::
[ ! -f /home/devuan/Passwords.kdbx ] || \
( cd .. ; \
ANSIBLE_KEEPASSXC_PASSWORD=foobar ansible -i hosts.yml \
-c local -m ansible-keepassxc \
-a 'database=/home/devuan/Passwords.kdbx entry=test_h@creep.im group=/Root/Xmpp/Chat' \
localhost )
debug:: tests/selenium_test-python.org-firefox.json
$(PENV) /var/local/bin/python2.bash -m pdb selenium_test.py test
$(PENV) /var/local/bin/python2.bash -m pdb selenium_test.py $<
cleanup::
@ps ax | grep -v grep | grep geckodriver && killall geckodriver /usr/bin/geckodriver 2>/dev/null || true
@ps ax | grep -v grep | grep /firefox && killall /usr/lib64/firefox/firefox 2>/dev/null || true
@ps ax | grep -v grep | grep phantomjs && killall phantomjs 2>/dev/null || true
targets::
# [ -z "${DISPLAY}" ] && xvfb-run $(MAKE) $(MFLAGS) TARGET=$(TARGET) ENV="" /tmp/firefox-$(TARGET).log \
# || $(MAKE) $(MFLAGS) TARGET=$(TARGET) ENV="$(ENV)" /tmp/firefox-$(TARGET).log
$(MAKE) $(MFLAGS) TARGET=$(TARGET) ENV="$(ENV) MOZ_HEADLESS=1" /tmp/firefox-$(TARGET).log
$(MAKE) $(MFLAGS) TARGET=$(TARGET) ENV="$(ENV)" /tmp/phantomjs-$(TARGET).log
/tmp/chromium-$(TARGET).log::
/tmp/firefox-$(TARGET).log:: tests/selenium_test-$(TARGET)-firefox.json clean
rm -f /tmp/test_ipleak.net_firefox_*
$(ENV) /var/local/bin/python2.bash $(PDB) selenium_test.py tests/selenium_test-$(TARGET)-firefox.json > \
/tmp/firefox-$(TARGET).out \
&& jq .results < /tmp/firefox-$(TARGET).out > /tmp/firefox-$(TARGET).json \
|| echo ERROR: $@
[ ! -f /tmp/firefox-$(TARGET).log ] || cat /tmp/firefox-$(TARGET).log
[ ! -f /tmp/geckodriver-$(TARGET).log ] || cat /tmp/geckodriver-$(TARGET).log
[ ! -f /tmp/test_$(TARGET)_failed.png ] || fbi /tmp/test_$(TARGET)_failed.png
/tmp/waterfox-$(TARGET).log:: tests/selenium_test-$(TARGET)-waterfox.json clean
rm -f /tmp/test_ipleak.net_waterfox_*
$(ENV) /var/local/bin/python2.bash $(PDB) selenium_test.py tests/selenium_test-$(TARGET)-waterfox.json > \
/tmp/waterfox-$(TARGET).out \
&& jq .results < /tmp/waterfox-$(TARGET).out > /tmp/waterfox-$(TARGET).out \
|| echo ERROR: $@
[ ! -f /tmp/waterfox-$(TARGET).log ] || cat /tmp/waterfox-$(TARGET).log
[ ! -f /tmp/geckodriver-$(TARGET).log ] || cat /tmp/geckodriver-$(TARGET).log
[ ! -f /tmp/test_$(TARGET)_failed.png ] || fbi /tmp/test_$(TARGET)_failed.png
/tmp/phantomjs-$(TARGET).log:: tests/selenium_test-$(TARGET)-phantomjs.json clean
rm -f /tmp/test_ipleak.net_phantomjs_*
$(ENV) /var/local/bin/python2.bash $(PDB) selenium_test.py tests/selenium_test-$(TARGET)-phantomjs.json > \
/tmp/phantomjs-$(TARGET).out \
&& jq .results < /tmp/phantomjs-$(TARGET).out > /tmp/phantomjs-$(TARGET).json \
|| echo ERROR: $@
[ ! -f /tmp/phantomjs-$(TARGET).log ] || cat /tmp/phantomjs-$(TARGET).log
[ ! -f /tmp/ghostdriver-$(TARGET).log ] || cat /tmp/ghostdriver-$(TARGET).log
[ ! -f /tmp/test_$(TARGET)_failed.png ] || fbi /tmp/test_$(TARGET)_failed.png
@ps ax | grep -v grep | grep phantomjs && killall phantomjs 2>/dev/null || true
tests/selenium_test-$(TARGET)-phantomjs.json:: tests/selenium_test-$(TARGET)-firefox.json
sed -e 's/geckodriver/ghostdriver/' -e 's/firefox/phantomjs/' < $< > $@
clean::
@rm -f /tmp/firefox-$(TARGET).log /tmp/geckodriver-$(TARGET).log
@rm -f /tmp/phantomjs-$(TARGET).log /tmp/ghostdriver-$(TARGET).log
@rm -f /tmp/test_$(TARGET)_failed.png
@rm -f geckodriver.log ghostdriver.log

View file

@ -0,0 +1 @@
ansible-keepassxc.py

View file

@ -0,0 +1,190 @@
#!/usr/bin/python
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
IMPORT_ERR = None
try:
# import _argon2_xffi_bindings
import pykeepass as keepass
except ImportError:
IMPORT_ERR = traceback.format_exc()
DOCUMENTATION = r'''
---
module: ansible-keepassxc
short_description: Module to read credentials from KeePassXC
version_added: "0.0.1"
description: Module to read credentials from KeePassXC
options:
database:
description: Path to database file
required: true
type: str
password:
description: Database Password
required: true
type: str
keyfile:
description: Path to key file
required: false
type: str
entry:
description: Entry name for the attribute to fetch
required: true
type: str
group:
decription: Group name that the Entry belongs to
required: false
type: str
author:
- Jeremy Lumley (@jlumley)
'''
EXAMPLES = r'''
# Fetch the credentials for the server_1 entry in any group
- name: Fetch server_1 credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "s3cure_p4550rd"
entry: "server_1"
# Fetch the reddit entry in the social group
- name: Fetching reddit credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "sup3r_s3cure_p4550rd"
entry: "reddit"
group: "social"
# Fetch a custom strig attribute from the github entry
- name: Fetch Github API Token
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "d0pe_s3cure_p4550rd"
keyfile: "/secrets/top_secret_key"
entry: "github"
group: "development"
'''
RETURN = r'''
# Return values
username:
description: Username of entry if present
type: str
returned: always
sample: 's3cr3t_us3r'
password:
description: Password of entry if present
type: str
returned: always
sample: 's3cr3t_p455word'
url:
description: Url of entry if present
type: str
returned: always
sample: 'http://reddit.com'
custom_fields:
description: dictionary containing all custom fields
type: dict
returned: always
sample: False
no_log:
description: suppress logging of password
type: bool
returned: never
sample: False
'''
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
database = dict(type='str', required=True),
password = dict(type='str', required=False,
default=os.environ.get('ANSIBLE_KEEPASSXC_PASSWORD')),
keyfile = dict(type='str', required=False, default=None),
entry = dict(type='str', required=True),
group = dict(type='str', required=False),
no_log = dict(type='bool', required=False, default=False),
)
# seed the result dict in the object
result = dict(
changed=False,
username='',
password='',
url='',
custom_fields={}
)
# Currently no support for a check_mode this maybe added later if
# functionality to modify the database is added later
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=False,
no_log=False
)
if IMPORT_ERR:
module.fail_json(
msg=missing_required_lib("pykeepass"),
exception=IMPORT_ERR
)
# unlock local keepass database
try:
kp = keepass.PyKeePass(
module.params['database'],
password=module.params['password'],
keyfile=module.params['keyfile'])
except keepass.exceptions.CredentialsError:
module.fail_json(msg='Invalid Credentials')
# find entry
entry = kp.find_entries(
title=module.params['entry'],
group=module.params['group']
)
# fail is entry is not present
if not entry:
module.fail_json(msg=f"Unable to find entry: {module.params['entry']}")
else:
entry = entry[0]
custom_field_keys = entry._get_string_field_keys(exclude_reserved=True)
custom_fields = dict()
for key in custom_field_keys:
custom_fields[key] = entry.get_custom_property(key)
result = dict (
changed=False,
username=entry.username,
password=entry.password,
url=entry.url,
custom_fields=custom_fields
)
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,69 @@
*** ansible-keepassxc.py.dst 2022-04-07 15:14:39.222017589 +0000
--- ansible-keepassxc.py 2022-04-07 15:12:28.010013156 +0000
***************
*** 2,11 ****
--- 2,22 ----
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
+ import os
+ import traceback
+ from ansible.module_utils.basic import AnsibleModule, missing_required_lib
+
+ IMPORT_ERR = None
+ try:
+ import _argon2_xffi_bindings
+ import pykeepass as keepass
+ except ImportError:
+ IMPORT_ERR = traceback.format_exc()
+
DOCUMENTATION = r'''
---
module: ansible-keepassxc
short_description: Module to read credentials from KeePassXC
***************
*** 89,112 ****
type: dict
returned: always
sample: False
'''
- from ansible.module_utils.basic import AnsibleModule, missing_required_lib
- import traceback
-
- IMPORT_ERR = None
- try:
- import pykeepass as keepass
- except ImportError:
- IMPORT_ERR = traceback.format_exc()
-
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
database = dict(type='str', required=True),
! password = dict(type='str', required=True),
keyfile = dict(type='str', required=False, default=None),
entry = dict(type='str', required=True),
group = dict(type='str', required=False),
)
--- 100,115 ----
type: dict
returned: always
sample: False
'''
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
database = dict(type='str', required=True),
! password = dict(type='str', required=False,
! default=os.environ.get('ANSIBLE_KEEPASSXC_PASSWORD')),
keyfile = dict(type='str', required=False, default=None),
entry = dict(type='str', required=True),
group = dict(type='str', required=False),
)

View file

@ -0,0 +1,180 @@
#!/usr/bin/python
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: ansible-keepassxc
short_description: Module to read credentials from KeePassXC
version_added: "0.0.1"
description: Module to read credentials from KeePassXC
options:
database:
description: Path to database file
required: true
type: str
password:
description: Database Password
required: true
type: str
keyfile:
description: Path to key file
required: false
type: str
entry:
description: Entry name for the attribute to fetch
required: true
type: str
group:
decription: Group name that the Entry belongs to
required: false
type: str
author:
- Jeremy Lumley (@jlumley)
'''
EXAMPLES = r'''
# Fetch the credentials for the server_1 entry in any group
- name: Fetch server_1 credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "s3cure_p4550rd"
entry: "server_1"
# Fetch the reddit entry in the social group
- name: Fetching reddit credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "sup3r_s3cure_p4550rd"
entry: "reddit"
group: "social"
# Fetch a custom strig attribute from the github entry
- name: Fetch Github API Token
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "d0pe_s3cure_p4550rd"
keyfile: "/secrets/top_secret_key"
entry: "github"
group: "development"
'''
RETURN = r'''
# Return values
username:
description: Username of entry if present
type: str
returned: always
sample: 's3cr3t_us3r'
password:
description: Password of entry if present
type: str
returned: always
sample: 's3cr3t_p455word'
url:
description: Url of entry if present
type: str
returned: always
sample: 'http://reddit.com'
custom_fields:
description: dictionary containing all custom fields
type: dict
returned: always
sample: False
'''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
import traceback
IMPORT_ERR = None
try:
import pykeepass as keepass
except ImportError:
IMPORT_ERR = traceback.format_exc()
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
database = dict(type='str', required=True),
password = dict(type='str', required=True),
keyfile = dict(type='str', required=False, default=None),
entry = dict(type='str', required=True),
group = dict(type='str', required=False),
)
# seed the result dict in the object
result = dict(
changed=False,
username='',
password='',
url='',
custom_fields={}
)
# Currently no support for a check_mode this maybe added later if
# functionality to modify the database is added later
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=False
)
if IMPORT_ERR:
module.fail_json(
msg=missing_required_lib("pykeepass"),
exception=IMPORT_ERR
)
# unlock local keepass database
try:
kp = keepass.PyKeePass(
module.params['database'],
password=module.params['password'],
keyfile=module.params['keyfile'])
except keepass.exceptions.CredentialsError:
module.fail_json(msg='Invalid Credentials')
# find entry
entry = kp.find_entries(
title=module.params['entry'],
group=module.params['group']
)
# fail is entry is not present
if not entry:
module.fail_json(msg=f"Unable to find entry: {module.params['entry']}")
else:
entry = entry[0]
custom_field_keys = entry._get_string_field_keys(exclude_reserved=True)
custom_fields = dict()
for key in custom_field_keys:
custom_fields[key] = entry.get_custom_property(key)
result = dict (
changed=False,
username=entry.username,
password=entry.password,
url=entry.url,
custom_fields=custom_fields
)
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()

View file

@ -0,0 +1 @@
https://github.com/jlumley/ansible-keepassxc/raw/main/keepassxc.py

View file

@ -0,0 +1,93 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2014, Jakub Jirutka <jakub@jirutka.cz>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
DOCUMENTATION = '''
---
module: eselect
author: Jakub Jirutka
version_added: "unknown"
short_description: Module for Gentoo's eselect
description:
- Module for Gentoo's multi-purpose configuration and management tool eselect.
options:
module:
description:
- Name of the eselect module to run.
required: true
action:
description:
- Action of the eselect module to run.
default: set
options:
description:
- An optional options for the eselect module (space separated).
required: false
aliases: [value, target]
'''
EXAMPLES = '''
- eselect: module=editor target=/usr/bin/vim
- eselect: module=postgresql action=reset
'''
def run_eselect(module, *args):
cmd = 'eselect --brief --colour=no %s' % ' '.join(args)
rc, out, err = module.run_command(cmd)
if rc != 0:
module.fail_json(cmd=cmd, rc=rc, stdout=out, stderr=err,
msg='eselect failed')
else:
return out
def action_set(module, emodule, target):
current = run_eselect(module, emodule, 'show').strip()
if target != current:
run_eselect(module, emodule, 'set', target)
return True
else:
return False
def main():
module = AnsibleModule(
argument_spec={
'module': {'required': True},
'action': {'default': 'set'},
'options': {'aliases': ['value', 'target'], 'default': ''}
}
)
emodule, action, options = (module.params[key] for key in ['module', 'action', 'options'])
changed = True
msg = ''
if action == 'set':
changed = action_set(module, emodule, options)
else:
msg = run_eselect(module, emodule, action, options)
module.exit_json(changed=changed, msg=msg)
# import module snippets
from ansible.module_utils.basic import *
main()

View file

@ -0,0 +1,4 @@
1649339287010 geckodriver INFO geckodriver 0.20.0
1649339287356 geckodriver INFO Listening on 127.0.0.1:59175
1649339399259 geckodriver INFO geckodriver 0.20.0
1649339399263 geckodriver INFO Listening on 127.0.0.1:15991

View file

@ -0,0 +1,180 @@
#!/usr/bin/python
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: ansible-keepassxc
short_description: Module to read credentials from KeePassXC
version_added: "0.0.1"
description: Module to read credentials from KeePassXC
options:
database:
description: Path to database file
required: true
type: str
password:
description: Database Password
required: true
type: str
keyfile:
description: Path to key file
required: false
type: str
entry:
description: Entry name for the attribute to fetch
required: true
type: str
group:
decription: Group name that the Entry belongs to
required: false
type: str
author:
- Jeremy Lumley (@jlumley)
'''
EXAMPLES = r'''
# Fetch the credentials for the server_1 entry in any group
- name: Fetch server_1 credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "s3cure_p4550rd"
entry: "server_1"
# Fetch the reddit entry in the social group
- name: Fetching reddit credentials
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "sup3r_s3cure_p4550rd"
entry: "reddit"
group: "social"
# Fetch a custom strig attribute from the github entry
- name: Fetch Github API Token
jlumley.jlumley.ansible-keepassxc:
database: "/secrets/db.kdbx"
password: "d0pe_s3cure_p4550rd"
keyfile: "/secrets/top_secret_key"
entry: "github"
group: "development"
'''
RETURN = r'''
# Return values
username:
description: Username of entry if present
type: str
returned: always
sample: 's3cr3t_us3r'
password:
description: Password of entry if present
type: str
returned: always
sample: 's3cr3t_p455word'
url:
description: Url of entry if present
type: str
returned: always
sample: 'http://reddit.com'
custom_fields:
description: dictionary containing all custom fields
type: dict
returned: always
sample: False
'''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
import traceback
IMPORT_ERR = None
try:
import pykeepass as keepass
except ImportError:
IMPORT_ERR = traceback.format_exc()
def run_module():
# define available arguments/parameters a user can pass to the module
module_args = dict(
database = dict(type='str', required=True),
password = dict(type='str', required=True),
keyfile = dict(type='str', required=False, default=None),
entry = dict(type='str', required=True),
group = dict(type='str', required=False),
)
# seed the result dict in the object
result = dict(
changed=False,
username='',
password='',
url='',
custom_fields={}
)
# Currently no support for a check_mode this maybe added later if
# functionality to modify the database is added later
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=False
)
if IMPORT_ERR:
module.fail_json(
msg=missing_required_lib("pykeepass"),
exception=IMPORT_ERR
)
# unlock local keepass database
try:
kp = keepass.PyKeePass(
module.params['database'],
password=module.params['password'],
keyfile=module.params['keyfile'])
except keepass.exceptions.CredentialsError:
module.fail_json(msg='Invalid Credentials')
# find entry
entry = kp.find_entries(
title=module.params['entry'],
group=module.params['group']
)
# fail is entry is not present
if not entry:
module.fail_json(msg=f"Unable to find entry: {module.params['entry']}")
else:
entry = entry[0]
custom_field_keys = entry._get_string_field_keys(exclude_reserved=True)
custom_fields = dict()
for key in custom_field_keys:
custom_fields[key] = entry.get_custom_property(key)
result = dict (
changed=False,
username=entry.username,
password=entry.password,
url=entry.url,
custom_fields=custom_fields
)
# in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,339 @@
# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# Based on chroot.py (c) 2013, Maykel Moya <mmoya@speedyrails.com>
# (c) 2013, Michael Scherer <misc@zarb.org>
# (c) 2015, Toshio Kuratomi <tkuratomi@ansible.com>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
import sys
__metaclass__ = type
DOCUMENTATION = """
author: Jesse Pretorius <jesse@odyssey4.me>
connection: community.libvirt.libvirt_qemu
short_description: Run tasks on libvirt/qemu virtual machines
description:
- Run commands or put/fetch files to libvirt/qemu virtual machines using the qemu agent API.
notes:
- Currently DOES NOT work with selinux set to enforcing in the VM.
- Requires the qemu-agent installed in the VM.
- Requires access to the qemu-ga commands guest-exec, guest-exec-status, guest-file-close, guest-file-open, guest-file-read, guest-file-write.
version_added: "2.10"
options:
remote_addr:
description: Virtual machine name
default: inventory_hostname
vars:
- name: ansible_host
executable:
description: Shell to use for execution inside container
default: /bin/sh
vars:
- name: ansible_executable
virt_uri:
description: libvirt URI to connect to to access the virtual machine
default: qemu:///system
vars:
- name: ansible_libvirt_uri
"""
import base64
import json
import libvirt
import libvirt_qemu
import shlex
import traceback
from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.plugins.shell.powershell import _parse_clixml
from ansible.utils.display import Display
from functools import partial
from os.path import exists, getsize
display = Display()
REQUIRED_CAPABILITIES = [
{'enabled': True, 'name': 'guest-exec', 'success-response': True},
{'enabled': True, 'name': 'guest-exec-status', 'success-response': True},
{'enabled': True, 'name': 'guest-file-close', 'success-response': True},
{'enabled': True, 'name': 'guest-file-open', 'success-response': True},
{'enabled': True, 'name': 'guest-file-read', 'success-response': True},
{'enabled': True, 'name': 'guest-file-write', 'success-response': True}
]
class Connection(ConnectionBase):
''' Local libvirt qemu based connections '''
transport = 'community.libvirt.libvirt_qemu'
# TODO(odyssey4me):
# Figure out why pipelining does not work and fix it
has_pipelining = False
has_tty = False
def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
self._host = self._play_context.remote_addr
# Windows operates differently from a POSIX connection/shell plugin,
# we need to set various properties to ensure SSH on Windows continues
# to work
if getattr(self._shell, "_IS_WINDOWS", False):
self.has_native_async = True
self.always_pipeline_modules = True
self.module_implementation_preferences = ('.ps1', '.exe', '')
self.allow_executable = False
def _connect(self):
''' connect to the virtual machine; nothing to do here '''
super(Connection, self)._connect()
if not self._connected:
self._virt_uri = self.get_option('virt_uri')
self._display.vvv(u"CONNECT TO {0}".format(self._virt_uri), host=self._host)
try:
self.conn = libvirt.open(self._virt_uri)
except libvirt.libvirtError as err:
self._display.vv(u"ERROR: libvirtError CONNECT TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
self._connected = False
raise AnsibleConnectionFailure(to_native(err))
self._display.vvv(u"FIND DOMAIN {0}".format(self._host), host=self._host)
try:
self.domain = self.conn.lookupByName(self._host)
except libvirt.libvirtError as err:
raise AnsibleConnectionFailure(to_native(err))
request_cap = json.dumps({'execute': 'guest-info'})
response_cap = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_cap, 5, 0))
self.capabilities = response_cap['return']['supported_commands']
self._display.vvvvv(u"GUEST CAPABILITIES: {0}".format(self.capabilities), host=self._host)
missing_caps = []
for cap in REQUIRED_CAPABILITIES:
if cap not in self.capabilities:
missing_caps.append(cap['name'])
if len(missing_caps) > 0:
self._display.vvv(u"REQUIRED CAPABILITIES MISSING: {0}".format(missing_caps), host=self._host)
raise AnsibleConnectionFailure('Domain does not have required capabilities')
display.vvv(u"ESTABLISH {0} CONNECTION".format(self.transport), host=self._host)
self._connected = True
def exec_command(self, cmd, in_data=None, sudoable=True):
""" execute a command on the virtual machine host """
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
cmd_args_list = shlex.split(to_native(cmd, errors='surrogate_or_strict'))
if getattr(self._shell, "_IS_WINDOWS", False):
# Become method 'runas' is done in the wrapper that is executed,
# need to disable sudoable so the bare_run is not waiting for a
# prompt that will not occur
sudoable = False
# Generate powershell commands
cmd_args_list = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False)
# TODO(odyssey4me):
# Implement buffering much like the other connection plugins
# Implement 'env' for the environment settings
# Implement 'input-data' for whatever it might be useful for
request_exec = {
'execute': 'guest-exec',
'arguments': {
'path': cmd_args_list[0],
'capture-output': True,
'arg': cmd_args_list[1:]
}
}
request_exec_json = json.dumps(request_exec)
display.vvv(u"GA send: {0}".format(request_exec_json), host=self._host)
# TODO(odyssey4me):
# Add timeout parameter
try:
result_exec = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_exec_json, 5, 0))
except libvirt.libvirtError as err:
self._display.vv(u"ERROR: libvirtError EXEC TO {0}\n{1}".format(self._virt_uri, to_native(err)), host=self._host)
sys.stderr.write(u"ERROR: libvirtError EXEC TO {0}\n{1}\n".format(self._virt_uri, to_native(err)))
self._connected = False
raise AnsibleConnectionFailure(to_native(err))
display.vvv(u"GA return: {0}".format(result_exec), host=self._host)
request_status = {
'execute': 'guest-exec-status',
'arguments': {
'pid': result_exec['return']['pid']
}
}
request_status_json = json.dumps(request_status)
display.vvv(u"GA send: {0}".format(request_status_json), host=self._host)
# TODO(odyssey4me):
# Work out a better way to wait until the command has exited
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_status), host=self._host)
while not result_status['return']['exited']:
result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_status), host=self._host)
if result_status['return'].get('out-data'):
stdout = base64.b64decode(result_status['return']['out-data'])
else:
stdout = b''
if result_status['return'].get('err-data'):
stderr = base64.b64decode(result_status['return']['err-data'])
else:
stderr = b''
# Decode xml from windows
if getattr(self._shell, "_IS_WINDOWS", False) and stdout.startswith(b"#< CLIXML"):
stdout = _parse_clixml(stdout)
display.vvv(u"GA stdout: {0}".format(to_text(stdout)), host=self._host)
display.vvv(u"GA stderr: {0}".format(to_text(stderr)), host=self._host)
return result_status['return']['exitcode'], stdout, stderr
def put_file(self, in_path, out_path):
''' transfer a file from local to domain '''
super(Connection, self).put_file(in_path, out_path)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._host)
if not exists(to_bytes(in_path, errors='surrogate_or_strict')):
raise AnsibleFileNotFound(
"file or module does not exist: %s" % in_path)
request_handle = {
'execute': 'guest-file-open',
'arguments': {
'path': out_path,
'mode': 'wb+'
}
}
request_handle_json = json.dumps(request_handle)
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
# TODO(odyssey4me):
# Handle exception for file/path IOError
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
for chunk in iter(partial(in_file.read, BUFSIZE), b''):
try:
request_write = {
'execute': 'guest-file-write',
'arguments': {
'handle': result_handle['return'],
'buf-b64': base64.b64encode(chunk).decode()
}
}
request_write_json = json.dumps(request_write)
display.vvvvv(u"GA send: {0}".format(request_write_json), host=self._host)
result_write = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_write_json, 5, 0))
display.vvvvv(u"GA return: {0}".format(result_write), host=self._host)
except Exception:
traceback.print_exc()
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
request_close = {
'execute': 'guest-file-close',
'arguments': {
'handle': result_handle['return']
}
}
request_close_json = json.dumps(request_close)
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
def fetch_file(self, in_path, out_path):
''' fetch a file from domain to local '''
super(Connection, self).fetch_file(in_path, out_path)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._host)
request_handle = {
'execute': 'guest-file-open',
'arguments': {
'path': in_path,
'mode': 'r'
}
}
request_handle_json = json.dumps(request_handle)
display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host)
result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_handle), host=self._host)
request_read = {
'execute': 'guest-file-read',
'arguments': {
'handle': result_handle['return'],
'count': BUFSIZE
}
}
request_read_json = json.dumps(request_read)
display.vvv(u"GA send: {0}".format(request_read_json), host=self._host)
with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file:
try:
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0))
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
while not result_read['return']['eof']:
result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0))
display.vvvvv(u"GA return: {0}".format(result_read), host=self._host)
out_file.write(base64.b64decode(result_read['return']['buf-b64']))
except Exception:
traceback.print_exc()
raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path))
request_close = {
'execute': 'guest-file-close',
'arguments': {
'handle': result_handle['return']
}
}
request_close_json = json.dumps(request_close)
display.vvv(u"GA send: {0}".format(request_close_json), host=self._host)
result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0))
display.vvv(u"GA return: {0}".format(result_close), host=self._host)
def close(self):
''' terminate the connection; nothing to do here '''
super(Connection, self).close()
self._connected = False

View file

@ -0,0 +1 @@
https://github.com/ansible-community/community.libvirt-1.0.0/plugins/connection/libvirt_qemu.py

View file

@ -0,0 +1,750 @@
#!/usr//local/bin/python2.sh
# -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
# From: github.com/napalm255/ansible-selenium/library/selenium_test.py
# (c) 2016, Brad Gibson <napalm255@gmail.com>
#
# This file is a 3rd Party module for Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
"""Ansible Selenium Module."""
DOCUMENTATION = '''
---
module: selenium_test
author: "Brad Gibson"
version_added: "2.3"
short_description: Run selenium tests
requires: [ selenium>=3.0.2 ]
description:
- Run selenium tests against provided URL.
- Use Clicks, Typing, Waiting and Assertions.
options:
url:
required: true
description:
- URL to run selenium tests against.
browser:
required: false
default: "phantomjs"
choices: [ "phantomjs", "firefox", "chrome" ]
description:
- Browser to use for testing.
browser_executable:
required: false
default: ""
browser_log:
required: false
default: ""
browser_timeout:
required: false
default: 30
browser_service_args:
required: false
default: []
webdriver_executable:
required: false
default: ""
webdriver_log:
required: false
default: ""
width:
required: false
default: 1024
description:
- Browser screen width.
height:
required: false
default: 768
description:
- Browser screen height.
title:
required: false
description:
- Title to validate after initial load.
screenshot:
required: false
default: false
description:
- Enable/Disable screenshots.
screenshot_when:
required: false
default: [ "error" ]
choices: [ "all", "start", "end", "error" ]
description:
- Enable/Disable screenshots.
screenshot_type:
required: false
default: "base64"
choices: [ "base64", "file" ]
description:
- Screenshot format.
screenshot_path:
required: false
default: "/tmp"
description:
- Screenshot path.
screenshot_prefix:
required: false
default: "selenium_"
description:
- Screenshot file prefix.
implicit_wait:
required: false
default: 20
description:
- Implicit wait value when loading webpage.
explicit_wait:
required: false
default: 2
description:
- Explicit wait value when loading webpage.
steps:
required: true
description:
- Steps to perform.
validate_cert:
required: false
default: true
description:
- Validate SSL certificate.
'''
EXAMPLES = '''
# run basic check against given url
- selenium_test: url=http://www.python.org
'''
# selenium/webdriver/remote/webdriver.py
_W3C_CAPABILITY_NAMES = frozenset([
'acceptInsecureCerts',
'browserName',
'browserVersion',
'platformName',
'pageLoadStrategy',
'proxy',
'setWindowRect',
'timeouts',
'unhandledPromptBehavior',
])
_OSS_W3C_CONVERSION = {
'acceptSslCerts': 'acceptInsecureCerts',
'version': 'browserVersion',
'platform': 'platformName'
}
# caps['proxy']['proxyType'] = caps['proxy']['proxyType'].lower()
# selenium-3.9.0-py2.7.egg/selenium/webdriver/common/proxy.py
ELTS = ['autodetect', 'ftpProxy', 'httpProxy', 'proxyAutoconfigUrl', 'sslProxy', 'noProxy', 'socksProxy', 'socksUsername', 'socksPassword']
def add_to_capabilities(self, proxyTypeString, capabilities):
"""
DIRECT = ProxyTypeFactory.make(0, 'DIRECT') # Direct connection, no proxy (default on Windows).
MANUAL = ProxyTypeFactory.make(1, 'MANUAL') # Manual proxy settings (e.g., for httpProxy).
PAC = ProxyTypeFactory.make(2, 'PAC') # Proxy autoconfiguration from URL.
RESERVED_1 = ProxyTypeFactory.make(3, 'RESERVED1') # Never used.
AUTODETECT = ProxyTypeFactory.make(4, 'AUTODETECT') # Proxy autodetection (presumably with WPAD).
SYSTEM = ProxyTypeFactory.make(5, 'SYSTEM') # Use system settings (default on Linux).
UNSPECIFIED = ProxyTypeFactory.make(6, 'UNSPECIFIED') # Not initialized (for internal use).
"""
proxy_caps = {}
proxy_caps['proxyType'] = proxyTypeString
for elt in ELTS:
proxy_caps[elt] = getattr(self, elt)
capabilities['proxy'] = proxy_caps
# pylint: disable = wrong-import-position
import sys,os # noqa
try:
if sys.version_info < (3, 0):
from urlparse import urlparse # noqa
else:
from urllib.parse import urlparse # noqa
URLPARSE_INSTALLED_ERR = ''
except ImportError as e:
URLPARSE_INSTALLED_ERR = 'ERROR: selenium_test.py urllib.parse import urlparse not imported.\n' + str(e)
from ansible.module_utils.basic import AnsibleModule, jsonify # noqa
try:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException
SELENIUM_INSTALLED_ERR = ''
except ImportError as e:
SELENIUM_INSTALLED_ERR = 'ERROR: selenium_test.py selenium not imported.\n' + str(e)
class AnsibleSelenium(object):
"""Ansible Selenium Class."""
def __init__(self, module):
"""Init."""
self.module = module
self.arg = lambda: None
for arg in self.module.params:
setattr(self.arg, arg, self.module.params[arg])
self.steps_num = len(self.arg.steps) - 1
self.result = {'changed': False,
'failed': False,
'results': {
'steps': [],
'num': self.steps_num
}}
self.browser_oFd = None
self.browser = self._browser()
def __enter__(self):
"""Enter by loading website and return self."""
# validate url
url_parsed = urlparse(self.arg.url)
if url_parsed.scheme not in ['http', 'https']:
self.failed('invalid url scheme: ' + url_parsed.scheme)
if not url_parsed.netloc:
self.failed('invalid url: empty netloc')
# load browser
self.browser.get(self.arg.url)
self.result['browser_closed'] = False
# validate title
if not self.arg.title:
#?mike how is this used? Set it to None if missing or blank?
self.result['results']['title'] = None
elif self.arg.title in self.browser.title:
self.result['results']['title'] = True
else:
self.result['results']['title'] = False
self.failed('title "' +self.browser.title +'" does not contain: ' + self.arg.title)
# process steps
self.steps()
return self
def __exit__(self, type, value, traceback):
"""Exit by closing and quitting the browser."""
# pylint: disable = redefined-builtin
if self.browser_oFd:
self.browser_oFd.close()
self.browser_oFd = None
try: self.browser.close()
except: pass
try: self.browser.quit()
except: pass
self.result['browser_closed'] = True
def _browser(self):
"""Select browser and return object."""
name = self.arg.browser
if 'phantomjs' in name:
return self._phantomjs()
elif 'firefox' in name:
return self._firefox()
elif 'chrome' in name:
return self._chrome()
else:
raise RuntimeError("Unrecognized browser " +name)
def _dRaw_proxy(self):
# FixMe? socks_proxy
dRaw = dict()
# SYSTEM
dRaw["proxyType"] = "MANUAL"
if ('no_proxy' in os.environ and os.environ['no_proxy']):
dRaw['noProxy'] = os.environ['no_proxy']
else:
dRaw['noProxy'] = 'localhost,127.0.0.1'
if os.environ['http_proxy']:
o = urlparse(os.environ['http_proxy'])
if o.scheme not in ['http', 'https']:
self.failed('invalid http_proxy url scheme: ' + o.scheme)
if not o.netloc:
self.failed('invalid http_proxy url: empty netloc')
PROXY_HOST, PROXY_PORT = o.netloc.split(':')
# 'http://' +
dRaw['httpProxy'] = PROXY_HOST +':' +PROXY_PORT
if os.environ['https_proxy']:
o = urlparse(os.environ['https_proxy'])
if o.scheme not in ['http', 'https']:
self.failed('invalid https_proxy url scheme: ' + o.scheme)
if not o.netloc:
self.failed('invalid https_proxy url: empty netloc')
PROXY_HOST, PROXY_PORT = o.netloc.split(':')
# 'https://' +
dRaw['sslProxy'] = PROXY_HOST +':' +PROXY_PORT
return dRaw
def _phantomjs(self):
"""Use PhantomJS browser."""
# Adding the list of possibilities (integer values) for the "network.proxy.type".
# 0 - Direct connection (or) no proxy.
# 1 - Manual proxy configuration
# 2 - Proxy auto-configuration (PAC).
# 4 - Auto-detect proxy settings.
# 5 - Use system proxy settings.
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# DesiredCapabilities.PHANTOMJS.copy()
import warnings
warnings.filterwarnings("ignore", "Selenium support for PhantomJS has been deprecated.*", UserWarning)
dCapabilities = {
"browserName": "phantomjs",
"browserVersion": "",
"platform": "ANY",
"javascriptEnabled": True,
}
if not self.arg.browser_executable:
self.arg.browser_executable = 'phantomjs'
service_args = self.arg.browser_service_args
service_args += ['--ssl-protocol=any','--web-security=no']
if ('http_proxy' in os.environ and os.environ['http_proxy']) or \
('https_proxy' in os.environ and os.environ['https_proxy']):
dRaw = self._dRaw_proxy()
dCapabilities['proxy'] = dRaw
# bogus - old
# --proxy-type=<val> 'http' (default), 'none' (disable completely), or 'socks5'
service_args += ['--proxy='+dRaw['sslProxy'], '--proxy-type='+'http']
# --ssl-protocol=TLSv1.2
# --ssl-certificates-path= the location for custom CA certificates (if none set, uses SSL_CERT_DIR)
if not self.arg.validate_cert:
service_args.append('--ignore-ssl-errors=true')
if False:
# Starts in 'Remote WebDriver mode' (embedded GhostDriver): '[[<IP>:]<PORT>]' (default '127.0.0.1:8910')
service_args.append('----webdriver=' +'127.0.0.1:8910')
# WebDriver Logging Level: (supported: 'ERROR', 'WARN', 'INFO', 'DEBUG') (default 'INFO') (NOTE: needs '--webdriver')
service_args.append('----webdriver-loglevel' +'INFO')
if self.arg.webdriver_log:
service_args += ['--webdriver-logfile='+self.arg.webdriver_log]
# service_args : A List of command line arguments to pass to PhantomJS
driver = webdriver.PhantomJS(service_args=service_args,
desired_capabilities=dCapabilities)
driver.set_window_size(self.arg.width, self.arg.height)
driver.set_page_load_timeout(self.arg.implicit_wait)
return driver
def _firefox(self):
"""Use Firefox browser."""
# pylint: disable = no-self-use
dCapabilities = {
"browserName": "firefox",
"acceptInsecureCerts": True,
}
if self.arg.validate_cert:
dCapabilities["acceptInsecureCerts"] = False
# from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
# firefox_profile = FirefoxProfile(profile_directory=None)
# warnings.warn("Please use FirefoxOptions to set browser profile", DeprecationWarning,
if ('http_proxy' in os.environ and os.environ['http_proxy']) or \
('https_proxy' in os.environ and os.environ['https_proxy']):
dRaw = self._dRaw_proxy()
from selenium.webdriver.common.proxy import Proxy
dRaw["proxyType"] = "MANUAL"
oProxy = Proxy(raw=dRaw)
#dRawCopy = dRaw.copy()
#dRawCopy["proxyType"] = "MANUAL".lower()
#? dCapabilities['proxy'] = dRawCopy
else:
oProxy = None
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
if not self.arg.browser_executable:
# their code looks for firefox or iceweasel
self.arg.browser_executable = 'firefox'
# should use FirefoxBinary.which() to make sure its on the PATH
self.arg.browser_executable = which(self.arg.browser_executable)
assert self.arg.browser_executable
# A file object to redirect the firefox process output to. It can be sys.stdout.
# morons: not a file
if not self.arg.browser_log:
self.browser_oFd = None
else:
self.browser_oFd = open(self.arg.browser_log, 'w')
firefox_binary = FirefoxBinary(firefox_path=self.arg.browser_executable, log_file=self.browser_oFd)
# firefox_binary.add_command_line_options()
if self.arg.webdriver_executable == 'legacy':
dCapabilities["marionette"] = False
self.arg.webdriver_executable = ''
else:
dCapabilities["marionette"] = True
if not self.arg.webdriver_executable:
self.arg.webdriver_executable = 'geckodriver'
if self.arg.webdriver_log:
log_path = self.arg.webdriver_log
else:
log_path = "geckodriver.log"
self.arg.webdriver_executable = which(self.arg.webdriver_executable)
assert self.arg.webdriver_executable
# options overrides capabilities
# As some of the options, such as `firefox_profile` and
# `options.profile` are mutually exclusive, precedence is
# given from how specific the setting is. `capabilities` is the
# least specific keyword argument, followed by `options`,
# followed by `firefox_binary` and `firefox_profile`.
#geckodriver
# -v Log level verbosity (-v for debug and -vv for trace level)
# -b, --binary <BINARY> Path to the Firefox binary
# --log <LEVEL> Set Gecko log level [possible values: fatal, error, warn, info, config, debug, trace]
service_args = self.arg.browser_service_args
kwargs = dict(firefox_profile=None,
firefox_binary=firefox_binary,
timeout=self.arg.browser_timeout,
capabilities=dCapabilities,
proxy=oProxy,
executable_path=self.arg.webdriver_executable,
options=None,
log_path=log_path,
firefox_options=None,
service_args=service_args)
driver = webdriver.Firefox(**kwargs)
return driver
def _chrome(self):
"""Use Chrome browser."""
# pylint: disable = no-self-use
if not self.arg.webdriver_executable:
self.arg.webdriver_executable = "chromedriver"
if not self.arg.browser_executable:
self.arg.browser_executable = '/opt/chromium-browser/chromium-launcher.sh'
if not self.arg.browser_service_args:
self.arg.browser_service_args = None
if not self.arg.webdriver_log:
self.arg.webdriver_log = None
# options get added to desired_capabilities - desired_capabilities.update(options.to_capabilities())
# warnings.warn('use options instead of chrome_options', DeprecationWarning)
kwargs = dict(executable_path=self.arg.webdriver_executable,
port=0,
options=None,
service_args=self.arg.browser_service_args,
desired_capabilities=None,
service_log_path=self.arg.webdriver_log,
chrome_options=None)
# selenium/webdriver/chrome/webdriver.py IGNORES the following arguments
# proxy=None, keep_alive=False, file_detector=None, to
# selenium-3.9.0-py2.7.egg/selenium/webdriver/remote/webdriver.py
driver = webdriver.Chrome(**kwargs)
return driver
def failed(self, msg, step=None):
"""Failed."""
# self.result['failed'] = True
self.result['msg'] = msg
self.result['failed'] = True
if step:
step['error'] = True
step['msg'] = msg
when = self.arg.screenshot_when
if 'all' in when or 'error' in when:
step['screenshot'] = self.screenshot('failed')
self.result['results']['steps'].append(step)
else:
self.result['results']['screenshot'] = self.screenshot('failed')
# cmd=cmd, rc=rc, stdout=out, stderr=err,
self.module.fail_json(**self.result)
def screenshot(self, suffix='default'):
"""Screenshot."""
details = {}
if 'base64' in self.arg.screenshot_type:
base64 = self.browser.get_screenshot_as_base64()
details['base64'] = base64
elif 'file' in self.arg.screenshot_type:
path = '%s/%s%s.png' % (self.arg.screenshot_path,
self.arg.screenshot_prefix,
suffix)
self.browser.get_screenshot_as_file(path)
details['file'] = path
return details
def keys(self, step, step_result):
"""Keys."""
step_result['keys'] = False
try:
keys_method = getattr(self.browser, step['keys']['type'])
if 'text' in step['keys']:
value = step['keys']['text']
assert value and value.lower() != 'undefined'
keys_method(step['keys']['value']).send_keys(value)
if 'key' in step['keys']:
key_type = getattr(Keys, step['keys']['key'])
assert key_type and key_type.lower() != 'undefined'
keys_method(step['keys']['value']).send_keys(key_type)
except KeyError:
self.failed('configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('type error. check syntax.', step_result)
except NoSuchElementException:
self.failed('no such element.', step_result)
step_result['keys'] = True
return step_result
def click(self, step, step_result):
"""Click."""
step_result['click'] = False
try:
click_method = getattr(self.browser, step['click']['type'])
click_method(step['click']['text']).click()
except KeyError:
self.failed('KeyError click configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('AttributeError. check syntax.', step_result)
except NoSuchElementException:
self.failed('no such element.', step_result)
step_result['click'] = True
return step_result
def wait_for(self, step, step_result):
"""Wait for."""
step_result['wait_for'] = False
try:
waitfor_method = getattr(EC, step['wait_for']['method'])
waitfor_type = getattr(By, step['wait_for']['type'])
waitfor_text = step['wait_for']['text']
except KeyError:
self.failed('KeyError wait_for configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('method or type error. check syntax.', step_result)
try:
WebDriverWait(self.browser, self.arg.explicit_wait).until(
waitfor_method((waitfor_type, waitfor_text))
)
except TimeoutException:
self.failed('failure waiting for element.', step_result)
step_result['wait_for'] = True
return step_result
def asserts(self, step, step_result):
"""Assertions.
/usr/lib64/python2.7/site-packages/selenium/webdriver/remote/webdriver.py
def find_element_by_id(self, id_):
def find_elements_by_id(self, id_):
def find_element_by_xpath(self, xpath):
def find_elements_by_xpath(self, xpath):
def find_element_by_link_text(self, link_text):
def find_elements_by_link_text(self, text):
def find_element_by_partial_link_text(self, link_text):
def find_elements_by_partial_link_text(self, link_text):
def find_element_by_name(self, name):
def find_elements_by_name(self, name):
def find_element_by_tag_name(self, name):
def find_elements_by_tag_name(self, name):
def find_element_by_class_name(self, name):
def find_elements_by_class_name(self, name):
def find_element_by_css_selector(self, css_selector):
def find_elements_by_css_selector(self, css_selector):
def find_element(self, by=By.ID, value=None):
def find_elements(self, by=By.ID, value=None):
"""
step_result['assert'] = False
step_result['assert_results'] = []
for aidx, item in enumerate(step['assert']):
step_result['assert_results'].append(False)
try:
assert_method = getattr(self.browser, item['type'])
assert assert_method(item['text'])
except KeyError:
self.failed('configuration failure. check syntax.',
step_result)
except NoSuchElementException:
self.failed('no such element: ' +item['type'] +' - ' +item['text'], step_result)
step_result['assert_results'][aidx] = True
step_result['assert'] = True
return step_result
def steps(self):
"""Loop through steps."""
for idx, step in enumerate(self.arg.steps):
step_result = {'id': idx,
'screenshot': 'no'}
if 'name' in step:
step_result['name'] = step['name']
if 'keys' in step:
step_result.update(self.keys(step, step_result))
if 'click' in step:
step_result.update(self.click(step, step_result))
if 'wait_for' in step:
step_result.update(self.wait_for(step, step_result))
if 'assert' in step:
step_result.update(self.asserts(step, step_result))
when = self.arg.screenshot_when
if self.arg.screenshot:
capture = False
if 'all' in when:
capture = True
elif 'start' in when and idx is 0:
capture = True
elif 'end' in when and idx is self.steps_num:
capture = True
if capture:
suffix = idx
if 'name' in step:
suffix = '%s_%s' % (idx, step['name'])
step_result['screenshot'] = self.screenshot(suffix)
self.result['results']['steps'].append(step_result)
def which(fname):
"""Returns the fully qualified path by searching Path of the given
name"""
for pe in os.environ['PATH'].split(os.pathsep):
checkname = os.path.join(pe, fname)
if os.access(checkname, os.X_OK) and not os.path.isdir(checkname):
return checkname
return None
def test():
# https://intoli.com/blog/running-selenium-with-headless-firefox/
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
# Set the MOZ_HEADLESS environment variable which casues Firefox to start in headless mode.
if not 'MOZ_HEADLESS' in os.environ: os.environ['MOZ_HEADLESS'] = "1"
# Select your Firefox binary.
firefox_path = '/usr/bin/firefox'
assert os.path.isfile(firefox_path)
binary = FirefoxBinary(firefox_path=firefox_path, log_file=sys.stdout)
# Start selenium with the configured binary.
driver = webdriver.Firefox(firefox_binary=binary)
# Visit this webpage.
driver.get("http://localhost:3128/")
heading_element = driver.find_element_by_xpath('//*[@href="doc/"]')
if heading_element:
textContent = heading_element.get_property('textContent').strip()
print('textContent = ' +textContent)
assert textContent == 'The Polipo manual'
else:
print("Heading element not found!")
driver.get("http://localhost:9090/")
heading_element = driver.find_element_by_xpath('//*[@href="/+history/FrontPage"]')
if heading_element:
textContent = heading_element.get_property('textContent').strip()
print('textContent = ' +textContent)
assert textContent == 'History'
else:
print("Heading element not found!")
driver.quit()
# Ideally, we could instruct Firefox to run in headless mode by including the -headless flag when running the
# binary with something like
# binary.add_command_line_options('-headless')
# However, on current versions of Firefox (up to and including Nightly 58.0a1) running on Windows 10 this
# flag doesn?t seem to work. Luckily, we can achieve the same effect by setting the MOZ_HEADLESS environment
# variable either from the command line with set MOZ_HEADLESS=1 or from the python script itself as above.
return 0
def main():
"""Main."""
# pylint: disable = too-many-branches
from ansible.module_utils.basic import _load_params,_ANSIBLE_ARGS
if len(sys.argv) > 1:
if not os.path.isfile(sys.argv[1]):
raise RuntimeError('ERROR: ' +'file not found ' +sys.argv[1])
# this allows us to leave stdin alone for pdb
try:
with open(sys.argv[1], 'rb') as fd:
_ANSIBLE_ARGS = fd.read()
except Exception as e:
raise RuntimeError('ERROR: ' +'file not read ' +repr(sys.argv) +str(e))
try:
module = AnsibleModule(
# check_invalid_arguments=False,
argument_spec=dict(
url=dict(type='str', required=True),
browser=dict(type='str', default='phantomjs',
choices=['phantomjs', 'firefox', 'chrome']),
browser_executable=dict(type='path', default=""),
browser_log=dict(type='path', default=""),
browser_timeout=dict(type='int', default=30),
browser_service_args=dict(type='list', default=[]),
# For firefox - if this is "legacy" marionette will not be used -
# The legacy driver provided and maintained by the Selenium project
# doesn't work for Firefox 48 or higher, and will never work for newer versions of Firefox.
webdriver_executable=dict(type='path', default=""),
webdriver_log=dict(type='str', default=""),
width=dict(type='int', default=1024),
height=dict(type='int', default=768),
title=dict(type='str', default=""),
screenshot=dict(type='bool', default=False),
screenshot_when=dict(type='list', default=['error']),
screenshot_type=dict(type='str', default='base64',
choices=['file', 'base64']),
screenshot_path=dict(type='str', default='/tmp'),
screenshot_prefix=dict(type='str', default='selenium_'),
steps=dict(type='list', required=True),
explicit_wait=dict(type='int', default=2),
implicit_wait=dict(type='int', default=20),
validate_cert=dict(type='bool', default=True),
),
supports_check_mode=False
)
except Exception as e:
results = {'failed': True, 'msg': 'ERROR: selenium_test.py AnsibleModule failed ' +str(e)}
print('\n' +jsonify(results))
sys.exit(1)
# check urlparse dependency
if URLPARSE_INSTALLED_ERR:
dArgs=dict(error=True, msg=URLPARSE_INSTALLED_ERR)
module.fail_json(**dArgs)
# check selenium dependency
if SELENIUM_INSTALLED_ERR:
dArgs=dict(error=True, msg=SELENIUM_INSTALLED_ERR)
module.fail_json(**dArgs)
try:
# initiate module
results = {'failed': True, 'msg': 'ERROR: selenium_test.py something went wrong'}
with AnsibleSelenium(module) as sel:
results = sel.result
module.exit_json(**results)
except Exception as e:
results = {'failed': True, 'msg': 'ERROR: selenium_test.py AnsibleSelenium failed ' +str(e)}
print('\n' +jsonify(results))
sys.exit(2)
if __name__ == '__main__':
if len(sys.argv) > 1:
if sys.argv[1] == 'test':
i = test()
sys.exit(i)
main()
# [ -f selenium_test.json ] || yaml2json.bash < selenium_test.json > selenium_test.json
# python2.bash selenium_test.py selenium_test.json
# old -version 3.141 with manifest
# /usr/local/lib64/python2.7/site-packages/selenium/webdriver/firefox/webdriver.xpi

View file

@ -0,0 +1,402 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# (c) 2016, Brad Gibson <napalm255@gmail.com>
#
# This file is a 3rd Party module for Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
"""Ansible Selenium Module."""
DOCUMENTATION = '''
---
module: selenium_test
author: "Brad Gibson"
version_added: "2.3"
short_description: Run selenium tests
requires: [ selenium>=3.0.2 ]
description:
- Run selenium tests against provided URL.
- Use Clicks, Typing, Waiting and Assertions.
options:
url:
required: true
description:
- URL to run selenium tests against.
browser:
required: false
default: "phantomjs"
choices: [ "phantomjs", "firefox", "chrome" ]
description:
- Browser to use for testing.
width:
required: false
default: 1024
description:
- Browser screen width.
height:
required: false
default: 768
description:
- Browser screen height.
title:
required: false
description:
- Title to validate after initial load.
screenshot:
required: false
default: false
description:
- Enable/Disable screenshots.
screenshot_when:
required: false
default: [ "error" ]
choices: [ "all", "start", "end", "error" ]
description:
- Enable/Disable screenshots.
screenshot_type:
required: false
default: "base64"
choices: [ "base64", "file" ]
description:
- Screenshot format.
screenshot_path:
required: false
default: "/tmp"
description:
- Screenshot path.
screenshot_prefix:
required: false
default: "selenium_"
description:
- Screenshot file prefix.
implicit_wait:
required: false
default: 20
description:
- Implicit wait value when loading webpage.
explicit_wait:
required: false
default: 2
description:
- Explicit wait value when loading webpage.
steps:
required: true
description:
- Steps to perform.
validate_cert:
required: false
default: true
description:
- Validate SSL certificate.
'''
EXAMPLES = '''
# run basic check against given url
- selenium_test: url=http://www.python.org
'''
# pylint: disable = wrong-import-position
import sys # noqa
try:
if sys.version_info < (3, 0):
from urlparse import urlparse # noqa
else:
from urllib.parse import urlparse # noqa
URLPARSE_INSTALLED = True
except ImportError:
URLPARSE_INSTALLED = False
from ansible.module_utils.basic import AnsibleModule # noqa
try:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
SELENIUM_INSTALLED = True
except ImportError:
SELENIUM_INSTALLED = False
class AnsibleSelenium(object):
"""Ansible Selenium Class."""
def __init__(self, module):
"""Init."""
self.module = module
self.arg = lambda: None
for arg in self.module.params:
setattr(self.arg, arg, self.module.params[arg])
self.steps_num = len(self.arg.steps) - 1
self.result = {'changed': False,
'failed': False,
'results': {
'steps': [],
'num': self.steps_num
}}
self.browser = self._browser()
def __enter__(self):
"""Enter by loading website and return self."""
# validate url
url_parsed = urlparse(self.arg.url)
if url_parsed.scheme not in ['http', 'https']:
self.failed('invalid url.')
if not url_parsed.netloc:
self.failed('invalid url.')
# load browser
self.browser.get(self.arg.url)
self.result['browser_closed'] = False
# validate title
if self.arg.title in self.browser.title:
self.result['results']['title'] = True
else:
self.result['results']['title'] = False
self.failed('title does not match.')
# process steps
self.steps()
return self
def __exit__(self, type, value, traceback):
"""Exit by closing and quitting the browser."""
# pylint: disable = redefined-builtin
self.browser.close()
self.browser.quit()
self.result['browser_closed'] = True
def _browser(self):
"""Select browser and return object."""
name = self.arg.browser
if 'phantomjs' in name:
return self._phantomjs()
elif 'firefox' in name:
return self._firefox()
elif 'chrome' in name:
return self._chrome()
def _phantomjs(self):
"""Use PhantomJS browser."""
service_args = ['--ssl-protocol=any']
if not self.arg.validate_cert:
service_args.append('--ignore-ssl-errors=true')
driver = webdriver.PhantomJS(service_args=service_args)
driver.set_window_size(self.arg.width, self.arg.height)
driver.set_page_load_timeout(self.arg.implicit_wait)
return driver
def _firefox(self):
"""Use Firefox browser."""
# pylint: disable = no-self-use
driver = webdriver.Firefox()
return driver
def _chrome(self):
"""Use Chrome browser."""
# pylint: disable = no-self-use
driver = webdriver.Chrome()
return driver
def failed(self, msg, step=None):
"""Failed."""
# self.result['failed'] = True
self.result['msg'] = msg
if step:
step['error'] = True
step['msg'] = msg
when = self.arg.screenshot_when
if 'all' in when or 'error' in when:
step['screenshot'] = self.screenshot('failed')
self.result['results']['steps'].append(step)
else:
self.result['results']['screenshot'] = self.screenshot('failed')
self.module.fail_json(**self.result)
def screenshot(self, suffix='default'):
"""Screenshot."""
details = {}
if 'base64' in self.arg.screenshot_type:
base64 = self.browser.get_screenshot_as_base64()
details['base64'] = base64
elif 'file' in self.arg.screenshot_type:
path = '%s/%s%s.png' % (self.arg.screenshot_path,
self.arg.screenshot_prefix,
suffix)
self.browser.get_screenshot_as_file(path)
details['file'] = path
return details
def keys(self, step, step_result):
"""Keys."""
step_result['keys'] = False
try:
keys_method = getattr(self.browser, step['keys']['type'])
if 'text' in step['keys']:
value = step['keys']['text']
keys_method(step['keys']['value']).send_keys(value)
if 'key' in step['keys']:
key_type = getattr(Keys, step['keys']['key'])
keys_method(step['keys']['value']).send_keys(key_type)
except KeyError:
self.failed('configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('type error. check syntax.', step_result)
except NoSuchElementException:
self.failed('no such element.', step_result)
step_result['keys'] = True
return step_result
def click(self, step, step_result):
"""Click."""
step_result['click'] = False
try:
click_method = getattr(self.browser, step['click']['type'])
click_method(step['click']['text']).click()
except KeyError:
self.failed('configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('type error. check syntax.', step_result)
except NoSuchElementException:
self.failed('no such element.', step_result)
step_result['click'] = True
return step_result
def wait_for(self, step, step_result):
"""Wait for."""
step_result['wait_for'] = False
try:
waitfor_method = getattr(EC, step['wait_for']['method'])
waitfor_type = getattr(By, step['wait_for']['type'])
waitfor_text = step['wait_for']['text']
except KeyError:
self.failed('configuration failure. check syntax.', step_result)
except AttributeError:
self.failed('method or type error. check syntax.', step_result)
try:
WebDriverWait(self.browser, self.arg.explicit_wait).until(
waitfor_method((waitfor_type, waitfor_text))
)
except TimeoutException:
self.failed('failure waiting for element.', step_result)
step_result['wait_for'] = True
return step_result
def asserts(self, step, step_result):
"""Assertions."""
step_result['assert'] = False
step_result['assert_results'] = []
for aidx, item in enumerate(step['assert']):
step_result['assert_results'].append(False)
try:
assert_method = getattr(self.browser, item['type'])
assert assert_method(item['text'])
except KeyError:
self.failed('configuration failure. check syntax.',
step_result)
except NoSuchElementException:
self.failed('no such element.', step_result)
step_result['assert_results'][aidx] = True
step_result['assert'] = True
return step_result
def steps(self):
"""Loop through steps."""
for idx, step in enumerate(self.arg.steps):
step_result = {'id': idx,
'screenshot': 'no'}
if 'name' in step:
step_result['name'] = step['name']
if 'keys' in step:
step_result.update(self.keys(step, step_result))
if 'click' in step:
step_result.update(self.click(step, step_result))
if 'wait_for' in step:
step_result.update(self.wait_for(step, step_result))
if 'assert' in step:
step_result.update(self.asserts(step, step_result))
when = self.arg.screenshot_when
if self.arg.screenshot:
capture = False
if 'all' in when:
capture = True
elif 'start' in when and idx is 0:
capture = True
elif 'end' in when and idx is self.steps_num:
capture = True
if capture:
suffix = idx
if 'name' in step:
suffix = '%s_%s' % (idx, step['name'])
step_result['screenshot'] = self.screenshot(suffix)
self.result['results']['steps'].append(step_result)
def main():
"""Main."""
# pylint: disable = too-many-branches
module = AnsibleModule(
argument_spec=dict(
url=dict(type='str', required=True),
browser=dict(type='str', default='phantomjs',
choices=['phantomjs', 'firefox', 'chrome']),
width=dict(type='int', default=1024),
height=dict(type='int', default=768),
title=dict(type='str'),
screenshot=dict(type='bool', default=False),
screenshot_when=dict(type='list', default=['error']),
screenshot_type=dict(type='str', default='base64',
choices=['file', 'base64']),
screenshot_path=dict(type='str', default='/tmp'),
screenshot_prefix=dict(type='str', default='selenium_'),
steps=dict(type='list', required=True),
explicit_wait=dict(type='int', default=2),
implicit_wait=dict(type='int', default=20),
validate_cert=dict(type='bool', default=True),
),
supports_check_mode=False
)
# check urlparse dependency
if not URLPARSE_INSTALLED:
module.fail_json(msg='urlparse not installed.')
# check selenium dependency
if not SELENIUM_INSTALLED:
module.fail_json(msg='selenium not installed.')
# initiate module
results = {'failed': True, 'msg': 'something went wrong'}
with AnsibleSelenium(module) as sel:
results = sel.result
module.exit_json(**results)
if __name__ == '__main__':
main()

View file

@ -0,0 +1 @@
https://github.com/napalm255/ansible-selenium

View file

@ -0,0 +1,222 @@
which firefox || exit 0
/usr/bin/firefox
/var/local/bin/python2.bash selenium_test.py test
Traceback (most recent call last):
File "selenium_test.py", line 743, in <module>
i = test()
File "selenium_test.py", line 638, in test
driver = webdriver.Firefox(firefox_binary=binary)
File "/var/local/lib/python2.7/site-packages/selenium-4.0.0a6.post2-py2.7.egg/selenium/webdriver/firefox/webdriver.py", line 191, in __init__
keep_alive=True)
File "/var/local/lib/python2.7/site-packages/selenium-4.0.0a6.post2-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 183, in __init__
self.start_session(capabilities, browser_profile)
File "/var/local/lib/python2.7/site-packages/selenium-4.0.0a6.post2-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 280, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "/var/local/lib/python2.7/site-packages/selenium-4.0.0a6.post2-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 349, in execute
self.error_handler.check_response(response)
File "/var/local/lib/python2.7/site-packages/selenium-4.0.0a6.post2-py2.7.egg/selenium/webdriver/remote/errorhandler.py", line 204, in check_response
raise exception_class(value)
selenium.common.exceptions.WebDriverException: Message: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>503 - Forwarding failure (Privoxy@localhost)</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex,nofollow">
<link rel="shortcut icon" href="//config.privoxy.org/error-favicon.ico">
<style type="text/css">
/*
* CSS for Privoxy CGI and script output
*/
/*
* General rules: Font, Color, Headings, Margins, Links
*/
body,td,th { font-family: arial, helvetica, helv, sans-serif; }
body { background-color: #ffffff; color: #000000; }
h1 { font-size: 140%; margin: 0px; }
h2 { font-size: 120%; margin: 0px; }
h3 { font-size: 110%; margin: 0px; }
p,pre { margin-left: 15px; }
li { margin: 2px 15px; }
dl { margin: 2px 15px; }
a:link { color: #0000dd; text-decoration: none; }
a:visited { color: #330099; text-decoration: none; }
a:active { color: #3333ff; text-decoration: none; }
/*
* Boxen as Table elements:
*/
td.title { border: solid black 1px; background-color: #dddddd; }
td.box { border: solid black 1px; background-color: #eeeeee; }
td.info { border: solid black 1px; background-color: #ccccff; }
td.warning { border: solid black 1px; background-color: #ffdddd; }
/*
* Special Table Boxen: for nesting, naked container and for
* the Status field in CGI Output:
*/
td.wrapbox { border: solid black 1px; padding: 5px; }
td.container { padding: 0px; }
td.status { border: solid black 1px; background-color: #ff0000; color: #ffffff; font-size: 300%; font-weight: bolder; }
/*
* Same Boxen as <div>s:
*/
div.title { border: solid black 1px; background-color: #dddddd; margin: 20px; padding: 20px; }
div.box { border: solid black 1px; background-color: #eeeeee; margin: 20px; padding: 20px; }
div.info { border: solid black 1px; background-color: #ccccff; margin: 20px; padding: 20px; }
div.warning { border: solid black 1px; background-color: #ffdddd; margin: 20px; padding: 20px; }
div.wrapbox { border: solid black 1px; margin: 20px; padding: 5px; }
/*
* Bold definitions in <dl>s, grey BG for table headings, transparent (no-bordered) table
*/
dt { font-weight: bold; }
th { background-color: #dddddd; }
table.transparent { border-style: none}
/*
* Special purpose paragraphs: Small for page footers,
* Important for quoting wrong or dangerous examples,
* Whiteframed for the toggle?mini=y CGI
*/
p.small { font-size: 10px; margin: 0px; }
p.important { border: solid black 1px; background-color: #ffdddd; font-weight: bold; padding: 2px; }
p.whiteframed { margin: 5px; padding: 5px; border: solid black 1px; text-align: center; background-color: #eeeeee; }
/*
* Links as buttons:
*/
td.buttons {
padding: 2px;
}
a.cmd, td.indentbuttons a, td.buttons a {
white-space: nowrap;
width: auto;
padding: 2px;
background-color: #dddddd;
color: #000000;
text-decoration: none;
border-top: 1px solid #ffffff;
border-left: 1px solid #ffffff;
border-bottom: 1px solid #000000;
border-right: 1px solid #000000;
}
a.cmd:hover, td.indentbuttons a:hover, td.buttons a:hover {
background-color: #eeeeee;
}
a.cmd:active, td.indentbuttons a:active, td.buttons a:active {
border-top: 1px solid #000000;
border-left: 1px solid #000000;
border-bottom: 1px solid #ffffff;
border-right: 1px solid #ffffff;
}
/*
* Special red emphasis:
*/
em.warning, strong.warning { color: #ff0000 }
/*
* In show-status we use tables directly behind headlines
* and for some reason or another the headlines are set to
* "margin:0" and leave the tables no air to breath.
*
* A proper fix would be to replace or remove the "margin:0",
* but as this affects every cgi page we do it another time
* and use this workaround until then.
*/
.box table { margin-top: 1em; }
/*
* Let the URL and pattern input fields scale with the browser
* width and try to prevent vertical scroll bars if the width
* is less than 80 characters.
*/
input.url, input.pattern { width: 95%; }
</style>
</head>
<body>
<table summary="" cellpadding="20" cellspacing="10" border="0" width="100%">
<tr>
<td class="status">
503
</td>
<td class="title" style="width: 100%">
<h1>
This is <a href="https://www.privoxy.org/">Privoxy</a> 3.0.32 on localhost (127.0.0.1), port 3128<!-- @if-can-toggle-start -->,
disabled<!-- if-can-toggle-end@ -->
</h1>
</td>
</tr>
<!-- -->
<tr>
<td class="warning" colspan=2>
<h2>Forwarding failure</h2>
<p>Privoxy was unable to <b>socks5t-forward</b> your request
<a title="Repeat the request"
href="http://localhost:15991/session"><b>http://localhost:15991/session</b></a>
through <b>127.0.0.1</b>:
<strong>SOCKS5 request failed</strong></p>
</p>
<p>Just <a title="Repeat the request" href="http://localhost:15991/session">try again</a> to
see if this is a temporary problem, or check your <a title="Privoxy's show-status page"
href="//config.privoxy.org/show-status">forwarding settings</a>
and make sure that all forwarding servers are working correctly and
listening where they are supposed to be listening.
</p>
</td>
</tr>
<tr>
<td class="box" colspan="2">
<h2>More Privoxy:</h2>
<ul><li><a href="//config.privoxy.org/">Privoxy main page</a></li><li><a href="//config.privoxy.org/show-status">View &amp; change the current configuration</a></li><li><a href="//config.privoxy.org/client-tags">View or toggle the tags that can be set based on the client&#39;s address</a></li><li><a href="//config.privoxy.org/show-request">View the request headers</a></li><li><a href="//config.privoxy.org/show-url-info">Look up which actions apply to a URL and why</a></li><li><a href="//config.privoxy.org/user-manual/">Documentation</a></li></ul>
</td>
</tr>
<!-- -->
<tr>
<td class="info" colspan="2">
<h2>Support and Service:</h2>
<p>
The Privoxy Team values your feedback.
</p>
<p>
Please have a look at the User Manual to learn how to
<a title="Privoxy User Manual: Contacting the developers, Bug Reporting and Feature Requests"
href="//config.privoxy.org/user-manual/contact.html">get support or report problems</a>.
<p>
If you want to support the Privoxy Team, you can
<a href="https://www.privoxy.org/participate">participate</a>
or <a href="https://www.privoxy.org/donate">donate</a>.
</p>
</td>
</tr>
</table>
</body>
</html>
make: *** [Makefile:22: test_test] Error 1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
{
"ANSIBLE_MODULE_ARGS": {
"screenshot_when": [
"end",
"error"
],
"webdriver_log": "/tmp/test_ipleak.net_firefox_geckodriver.log",
"screenshot": true,
"title": "IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites",
"url": "https://ipv4.ipleak.net/",
"webdriver_executable": "/usr/bin/geckodriver",
"validate_cert": true,
"browser_log": "/tmp/test_ipleak.net_firefox_geckodriver.log",
"screenshot_path": "/tmp",
"steps": [
{
"assert": [
{
"text": "IPv4",
"type": "find_element_by_link_text"
}
],
"wait_for": {
"text": "IPv4",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "IPv4",
"click": {
"text": "IPv4",
"type": "find_element_by_link_text"
}
}
],
"screenshot_prefix": "test_ipleak.net_firefox_",
"screenshot_type": "file",
"browser_executable": "/usr/bin/firefox",
"browser": "firefox"
}
}

View file

@ -0,0 +1,32 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: "https://ipv4.ipleak.net/"
title: "IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites"
browser: "firefox"
browser_log: "/tmp/test_ipleak.net_firefox_geckodriver.log"
# must run webdriver.xpi
browser_executable: "/usr/bin/firefox"
webdriver_log: "/tmp/test_ipleak.net_firefox_geckodriver.log"
webdriver_executable: "/usr/bin/geckodriver"
screenshot: true
screenshot_prefix: test_ipleak.net_firefox_
screenshot_when: ['end', 'error']
screenshot_type: file
screenshot_path: /tmp
validate_cert: true
steps:
- name: IPv4
click:
type: 'find_element_by_link_text'
text: 'IPv4'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'IPv4'
assert:
- type: 'find_element_by_link_text'
text: 'IPv4'

View file

@ -0,0 +1,40 @@
{
"ANSIBLE_MODULE_ARGS": {
"screenshot_when": [
"end",
"error"
],
"webdriver_log": "/tmp/test_ipleak.net_phantomjs_ghostdriver.log",
"screenshot": true,
"title": "IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites",
"url": "https://ipv4.ipleak.net/",
"webdriver_executable": "/usr/bin/ghostdriver",
"validate_cert": true,
"browser_log": "/tmp/test_ipleak.net_phantomjs_ghostdriver.log",
"screenshot_path": "/tmp",
"steps": [
{
"assert": [
{
"text": "IPv4",
"type": "find_element_by_link_text"
}
],
"wait_for": {
"text": "IPv4",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "IPv4",
"click": {
"text": "IPv4",
"type": "find_element_by_link_text"
}
}
],
"screenshot_prefix": "test_ipleak.net_phantomjs_",
"screenshot_type": "file",
"browser_executable": "/usr/bin/phantomjs",
"browser": "phantomjs"
}
}

View file

@ -0,0 +1,32 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: "https://ipv4.ipleak.net/"
title: "IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites"
browser: "phantomjs"
browser_log: "/tmp/phantomjs-ipleak.net.log"
# must run webdriver.xpi
browser_executable: "/var/local/bin/phantomjs.bash"
webdriver_log: "/tmp/ghostdriver-ipleak.net.log"
# webdriver_executable: "/var/local/bin/ghostdriver.bash"
screenshot: true
screenshot_prefix: "privacy_ipleak.net_phantomjs_"
screenshot_when: ['end', 'error']
screenshot_type: file
screenshot_path: /tmp
validate_cert: true
steps:
- name: IPv4
click:
type: 'find_element_by_link_text'
text: 'IPv4'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'IPv4'
assert:
- type: 'find_element_by_link_text'
text: 'IPv4'

View file

@ -0,0 +1,32 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: "https://ipv4.ipleak.net/"
title: "IP/DNS Detect - What is your IP, what is your DNS, what informations you send to websites"
browser: "firefox"
browser_log: "/tmp/waterfox-ipleak.net.log"
# must run webdriver.xpi
browser_executable: "/var/local/bin/waterfox-classic.bash"
webdriver_log: "/tmp/geckodriver-ipleak.net.log"
webdriver_executable: "/var/local/bin/geckodriver.bash"
screenshot: true
screenshot_prefix: test_ipleak.net_waterfox_
screenshot_when: ['end', 'error']
screenshot_type: file
screenshot_path: /tmp
validate_cert: true
steps:
- name: IPv4
click:
type: 'find_element_by_link_text'
text: 'IPv4'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'IPv4'
assert:
- type: 'find_element_by_link_text'
text: 'IPv4'

View file

@ -0,0 +1,51 @@
{
"ANSIBLE_MODULE_ARGS": {
"screenshot_when": [
"end",
"error"
],
"webdriver_log": "/tmp/geckodriver-polipo.log",
"screenshot": true,
"url": "http://localhost:3128/",
"webdriver_executable": "geckodriver",
"validate_cert": false,
"browser_log": "/tmp/firefox-polipo.log",
"screenshot_path": "/tmp",
"steps": [
{
"name": "The Polipo Manual!",
"click": {
"text": "The Polipo manual",
"type": "find_element_by_link_text"
}
},
{
"wait_for": {
"text": "Variable index",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
}
},
{
"assert": [
{
"text": "1 Background",
"type": "find_element_by_link_text"
},
{
"text": "2 Running Polipo",
"type": "find_element_by_link_text"
},
{
"text": "3 Polipo and the network",
"type": "find_element_by_link_text"
}
]
}
],
"screenshot_prefix": "privacy_polipo_firefox_",
"screenshot_type": "file",
"browser_executable": "firefox",
"browser": "firefox"
}
}

View file

@ -0,0 +1,39 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: "http://localhost:3128/"
browser: firefox
browser_log: "/tmp/firefox-polipo.log"
browser_executable: "firefox"
webdriver_executable: "geckodriver"
webdriver_log: "/tmp/geckodriver-polipo.log"
# not found
# title: "Welcome to Polipo!"
screenshot: true
screenshot_prefix: privacy_polipo_firefox_
screenshot_when: ['end', 'error']
screenshot_type: file
screenshot_path: /tmp
validate_cert: false
steps:
- name: The Polipo Manual!
click:
type: 'find_element_by_link_text'
text: 'The Polipo manual'
- wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Variable index'
- assert:
- type: 'find_element_by_link_text'
text: '1 Background'
- type: 'find_element_by_link_text'
text: '2 Running Polipo'
- type: 'find_element_by_link_text'
text: '3 Polipo and the network'

View file

@ -0,0 +1,51 @@
{
"ANSIBLE_MODULE_ARGS": {
"screenshot_when": [
"end",
"error"
],
"webdriver_log": "/tmp/ghostdriver-polipo.log",
"screenshot": true,
"url": "http://localhost:3128/",
"webdriver_executable": "ghostdriver",
"validate_cert": false,
"browser_log": "/tmp/phantomjs-polipo.log",
"screenshot_path": "/tmp",
"steps": [
{
"name": "The Polipo Manual!",
"click": {
"text": "The Polipo manual",
"type": "find_element_by_link_text"
}
},
{
"wait_for": {
"text": "Variable index",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
}
},
{
"assert": [
{
"text": "1 Background",
"type": "find_element_by_link_text"
},
{
"text": "2 Running Polipo",
"type": "find_element_by_link_text"
},
{
"text": "3 Polipo and the network",
"type": "find_element_by_link_text"
}
]
}
],
"screenshot_prefix": "privacy_polipo_phantomjs_",
"screenshot_type": "file",
"browser_executable": "phantomjs",
"browser": "phantomjs"
}
}

View file

@ -0,0 +1,38 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: "http://localhost:3128/"
# not found
# title: "Welcome to Polipo!"
browser: phantomjs
browser_log: "/tmp/phantomjs-polipo.log"
browser_executable: "var/local/bin/phantomjs.bash"
webdriver_log: "/tmp/ghostdriver-polipo.log"
screenshot: true
screenshot_prefix: privacy_polipo_phantomjs_
screenshot_when: ['end', 'error']
screenshot_type: file
screenshot_path: /tmp
validate_cert: false
steps:
- name: The Polipo Manual!
click:
type: 'find_element_by_link_text'
text: 'The Polipo manual'
- wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Variable index'
- assert:
- type: 'find_element_by_link_text'
text: '1 Background'
- type: 'find_element_by_link_text'
text: '2 Running Polipo'
- type: 'find_element_by_link_text'
text: '3 Polipo and the network'

View file

@ -0,0 +1,82 @@
{
"ANSIBLE_MODULE_ARGS": {
"screenshot_when": [
"start",
"end",
"error"
],
"webdriver_log": "/tmp/geckodriver-python.org.log",
"screenshot": true,
"title": "Python",
"url": "https://www.python.org",
"validate_cert": true,
"browser_log": "/tmp/firefox-python.org.log",
"screenshot_path": "/tmp",
"steps": [
{
"keys": {
"text": "garbage",
"type": "find_element_by_id",
"value": "id-search-field",
"key": "RETURN"
},
"wait_for": {
"text": "Python 2.0",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "Login"
},
{
"wait_for": {
"text": "Conferences and Workshops",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "About",
"click": {
"text": "About",
"type": "find_element_by_link_text"
}
},
{
"wait_for": {
"text": "Download Python 3.5.2",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "Downloads",
"click": {
"text": "Downloads",
"type": "find_element_by_link_text"
}
},
{
"assert": [
{
"text": "Python 3.x Docs",
"type": "find_element_by_link_text"
},
{
"text": "Python 2.x Docs",
"type": "find_element_by_link_text"
}
],
"wait_for": {
"text": "Python 3.x Docs",
"type": "LINK_TEXT",
"method": "presence_of_element_located"
},
"name": "Documentation",
"click": {
"text": "Documentation",
"type": "find_element_by_link_text"
}
}
],
"screenshot_prefix": "test_python.org_firefox_",
"screenshot_type": "file",
"browser_executable": "/usr/bin/firefox",
"browser": "firefox"
}
}

View file

@ -0,0 +1,67 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
#- hosts: localhost
# connection: local
# gather_facts: false
#
# tasks:
# - name: Debug
# debug: var=inventory_hostname
#
# - name: selenium
# selenium_test:
ANSIBLE_MODULE_ARGS:
url: https://www.python.org
title: Python
browser: firefox
browser_log: "/tmp/firefox-python.org.log"
browser_executable: "/usr/bin/firefox"
webdriver_log: "/tmp/geckodriver-python.org.log"
screenshot: true
screenshot_prefix: test_python.org_firefox_
screenshot_type: file
screenshot_path: /tmp
screenshot_when: ['start', 'end', 'error']
validate_cert: true
steps:
- name: Login
keys:
type: 'find_element_by_id'
value: 'id-search-field'
text: 'garbage'
key: 'RETURN'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Python 2.0'
- name: About
click:
type: 'find_element_by_link_text'
text: 'About'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Conferences and Workshops'
- name: Downloads
click:
type: 'find_element_by_link_text'
text: 'Downloads'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Download Python 3.5.2'
- name: Documentation
click:
type: 'find_element_by_link_text'
text: 'Documentation'
wait_for:
method: 'presence_of_element_located'
type: 'LINK_TEXT'
text: 'Python 3.x Docs'
assert:
- type: 'find_element_by_link_text'
text: 'Python 3.x Docs'
- type: 'find_element_by_link_text'
text: 'Python 2.x Docs'

Some files were not shown because too many files have changed in this diff Show more