Files
weave-scope/scope
Peter Bourgon b585a362ac Naïve process walker for Darwin
This fixes the regression where process names weren't appearing for
Darwin probes. Makes testing easier.

Also, changes the process walker to operate on value types. There's no
performance advantage to using reference types for something of this
size, and there appeared to be a data race in the Darwin port that
caused nodes to gain and lose process names over time.

Also, restructures how to enable docker scraping. Default false when run
manually, and enabled via --probe.docker true in the scope script.
2015-07-16 12:33:59 +02:00

196 lines
5.4 KiB
Bash
Executable File

#!/bin/bash
set -eu
usage() {
echo "Usage:"
echo "scope launch [<peer> ...]"
echo "scope stop"
echo
echo "scope <peer> is of the form <ip_address_or_fqdn>[:<port>]"
exit 1
}
SCRIPT_VERSION="(unreleased version)"
if [ "$SCRIPT_VERSION" = "(unreleased version)" ] ; then
IMAGE_VERSION=latest
else
IMAGE_VERSION=$SCRIPT_VERSION
fi
IMAGE_VERSION=${VERSION:-$IMAGE_VERSION}
SCOPE_IMAGE=weaveworks/scope:$IMAGE_VERSION
SCOPE_CONTAINER_NAME=weavescope
WEAVE_CONTAINER_NAME=weave
DNS_CONTAINER_NAME=weavedns
DNS_HTTP_PORT=6785
HOSTNAME=scope
DOMAINNAME=weave.local
FQDN=$HOSTNAME.$DOMAINNAME
DOCKER_BRIDGE=${DOCKER_BRIDGE:-docker0}
IP_REGEXP="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
IP_ADDR_CMD="find /sys/class/net -type l | xargs -n1 basename | grep -vE 'docker|veth|lo' | \
xargs -n1 ip addr show | grep inet | awk '{ print \$2 }' | grep -oE '$IP_REGEXP'"
WEAVESCOPE_DOCKER_ARGS=${WEAVESCOPE_DOCKER_ARGS:-}
WEAVESCOPE_DNS_ARGS=${WEAVESCOPE_DNS_ARGS:-}
[ $# -gt 0 ] || usage
COMMAND=$1
shift 1
# http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script
command_exists() {
command -v $1 >/dev/null 2>&1
}
is_running() {
status=$(docker inspect --format='{{.State.Running}}' $1 2>/dev/null) && [ "$status" = "true" ]
return $?
}
# Check that a container named $1 with image $2 is not running
check_not_running() {
case $(docker inspect --format='{{.State.Running}} {{.Config.Image}}' $1 2>/dev/null) in
"true $2")
echo "$1 is already running." >&2
exit 1
;;
"true $2:"*)
echo "$1 is already running." >&2
exit 1
;;
"false $2")
docker rm $1 >/dev/null
;;
"false $2:"*)
docker rm $1 >/dev/null
;;
true*)
echo "Found another running container named '$1'. Aborting." >&2
exit 1
;;
false*)
echo "Found another container named '$1'. Aborting." >&2
exit 1
;;
esac
}
# Run `weave expose` if it's not already exposed.
weave_expose() {
status=$(weave ps weave:expose | awk '{print $3}' 2>/dev/null)
if [ "$status" == "" ]; then
weave expose
fi
}
# Add all Scope IPs to its DNS record.
weave_dns_add() {
CONTAINER_ID="$1"
CONTAINER_FQDN="$2"
shift 2
for ip in $*; do
weave dns-add $ip $CONTAINER_ID -h $CONTAINER_FQDN
done
}
set_docker_bridge_ip() {
DOCKER_BRIDGE_IP=$(ip -4 addr show dev $DOCKER_BRIDGE | grep -m1 -o 'inet [.0-9]*')
DOCKER_BRIDGE_IP=${DOCKER_BRIDGE_IP#inet }
}
# Call url $4 with http verb $3 on container $1 at port $2
http_call() {
container_ip $1 \
"$1 container is not present. Have you launched it?" \
"$1 container is not running." \
|| return 1
shift 1
http_call_ip $CONTAINER_IP "$@"
}
http_call_ip() {
ip="$1"
port="$2"
http_verb="$3"
url="$4"
shift 4
curl --connect-timeout 3 -s -X $http_verb "$@" http://$ip:$port$url
}
container_ip() {
if ! status=$(docker inspect --format='{{.State.Running}} {{.NetworkSettings.IPAddress}}' $1 2>/dev/null); then
echo "$2" >&2
return 1
fi
case "$status" in
"true ")
echo "$1 container has no IP address; is Docker networking enabled?" >&2
return 1
;;
true*)
CONTAINER_IP="${status#true }"
;;
*)
echo "$3" >&2
return 1
;;
esac
}
case "$COMMAND" in
launch)
check_not_running $SCOPE_CONTAINER_NAME $SCOPE_IMAGE
# If Weave is running, we want to expose a Weave IP to the host
# network namespace, so Scope can use it.
if is_running $WEAVE_CONTAINER_NAME && command_exists weave; then
weave_expose
fi
# If WeaveDNS is running, we want to automatically tell the scope
# image to use weave dns. We can't use --dns with --net=host, so we
# have to hack it.
if is_running $DNS_CONTAINER_NAME; then
set_docker_bridge_ip
WEAVESCOPE_DNS_ARGS="$WEAVESCOPE_DNS_ARGS --dns $DOCKER_BRIDGE_IP --searchpath $DOMAINNAME"
fi
CONTAINER=$(docker run --privileged -d --name=$SCOPE_CONTAINER_NAME --net=host --pid=host \
-v /var/run/docker.sock:/var/run/docker.sock \
$WEAVESCOPE_DOCKER_ARGS $SCOPE_IMAGE $WEAVESCOPE_DNS_ARGS --probe.docker true "$@")
IP_ADDRS=$(docker run --net=host gliderlabs/alpine /bin/sh -c "$IP_ADDR_CMD")
if is_running $DNS_CONTAINER_NAME && is_running $WEAVE_CONTAINER_NAME && command_exists weave; then
if [ -z "$IP_ADDRS" ]; then
echo "Could not determine local IP address; Weave DNS integration will not work correctly."
exit 1
fi
weave_dns_add $CONTAINER $FQDN $IP_ADDRS
fi
echo $CONTAINER
echo "Weave Scope is reachable at the following URL(s):" >&2
for ip in $IP_ADDRS; do
echo " * http://$ip:4040/" >&2
done
;;
stop)
[ $# -eq 0 ] || usage
if ! docker stop $SCOPE_CONTAINER_NAME >/dev/null 2>&1 ; then
echo "Weave Scope is not running." >&2
fi
docker rm -f $SCOPE_CONTAINER_NAME >/dev/null 2>&1 || true
;;
*)
echo "Unknown scope command '$COMMAND'" >&2
usage
;;
esac