Skip to content

Instantly share code, notes, and snippets.

@dosaboy
Last active March 28, 2019 15:44
Show Gist options
  • Save dosaboy/c04fce37b99990bd1994da90e8e72e7e to your computer and use it in GitHub Desktop.
Save dosaboy/c04fce37b99990bd1994da90e8e72e7e to your computer and use it in GitHub Desktop.
#!/bin/bash -eu
#
# Origin: https://gist.github.com/dosaboy/c04fce37b99990bd1994da90e8e72e7e
#
# Authors:
# - edward.hope-morley@canonical.com
# - opentastic@gmail.com
#
# This must be executed on Juju client node.
#
# The tool generates a script that is then copied (scp) to all Compute
# hosts. You can then log into those compute hosts and do:
#
# * source the script (does not execute anything just loads into local shell)
#
# * save the read/write iops caps applied to a domain/vm
#
# * apply new read/write iops caps to a domain/vm
#
# * restore read/write iops to a domain/vm from file (save(d))
#
nova_compute_juju_app_name=${1:-'nova-compute'}
msg="The name of your Juju compute application is '$nova_compute_juju_app_name' - hit [ENTER] to continue or ctrl+c to quit"
read -p "$msg"
local_script_name=/tmp/virsh_domain_iops_throttling.sh
cat << 'EOF' > $local_script_name
#!/bin/bash -eu
statspath=/tmp/virsh-blkdev-settings
mkdir -p $statspath
# Required deps
dpkg -s jq| grep -q "Status: install ok installed" || sudo apt install -y jq
save ()
{
domain=$1
device=$2
(($#>1)) || { echo "ERROR: not enough args"; return 1; }
results=$statspath/$domain
mkdir -p $results
for key in read_iops_sec write_iops_sec; do
results_key=$results/${device}_$key
if [ -r "$results_key" ]; then
echo "Domain $results_key already saved."
else
val=`virsh blkdeviotune $domain $device| sed -r "s/^$key\s*:\s*(.+)/\1/g;t;d"`
[ -n "$val" ] || { echo "ERROR: no value found for $domain $device $key"; continue; }
echo "$val" > $results_key
echo "Domain $results_key saved."
fi
done
}
apply ()
{
domain=$1
device=$2
iops_rd=$3
iops_wr=$4
force=${5:-false}
(($#>3)) || { echo "ERROR: not enough args"; return 1; }
echo "Setting domain '$domain' --read-iops-sec $iops_rd --write-iops-sec $iops_wr"
$force || read -p "OK? Hit [ENTER] to continue"
virsh blkdeviotune $domain $device --read-iops-sec $iops_rd --write-iops-sec $iops_wr
echo "Done."
}
restore ()
{
domain=$1
device=$2
(($#>1)) || { echo "ERROR: not enough args"; return 1; }
declare -A lookup=(
["read_iops_sec"]="--read-iops-sec"
["write_iops_sec"]="--write-iops-sec"
)
results=$statspath/$domain
args=()
for key in read_iops_sec write_iops_sec; do
results_key=$results/${device}_$key
if [ -r "$results_key" ]; then
val=`cat $results_key`
[ -n "$val" ] || echo "ERROR: $results_key has no value"
args+=( "${lookup[$key]} $val" )
else
echo "No saved settings for domain '$domain' dev $device"
break
fi
done
((${#args[@]}>0)) || continue
echo "Restoring domain '$domain' ${args[@]} "
virsh blkdeviotune $domain $device ${args[@]}
echo "Done."
}
EOF
chmod +x $local_script_name
readarray -t compute_hosts<<<"`juju status --format=json ${nova_compute_juju_app_name}| jq -r '.machines[]| .\"dns-name\"'`"
echo "Copying script '`basename $local_script_name`' (from `dirname $local_script_name`) to ${#compute_hosts[@]} compute hosts: ${compute_hosts[@]}"
for m in "${compute_hosts[@]}"; do
echo -n "copying script to host '$m'..."
juju scp $local_script_name $m: &
echo "done"
done
wait
cat << EOF
You can now log into any of your ${#compute_hosts[@]} compute hosts and do:
. .`basename $local_script_name`
Then save a copy of existing settings (this only works once):
save <domain> <device>
Then you can go ahead and apply the new settings to all vms on this host:
apply <domain> <device> <rd_iops_max> <wr_iops_max>
If you need to restore settings you can do:
restore <domain> <device>
NOTE: <domain> is the virsh name given to a vm which can be found by looking for "instance_name" in the output of openstack server show <vm>
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment