From 0a88f50964c080e54c0ee78c4639cc53441431a9 Mon Sep 17 00:00:00 2001 From: Jean Rouge Date: Thu, 18 Oct 2018 10:08:22 -0700 Subject: [PATCH] Adding a `hack/debug` script That's basically just a light wrapper around delve, to make it nicer to use (stops it after the session is done, and doesn't ignore interrupts like the vanilla version does). Also amending the containerized Makefile to add the right run options when using delve. That's controlled by the `DOCKER_SWARMKIT_USE_DELVE` env variable; it's also possible to override the port delve uses via the `DOCKER_SWARMKIT_DELVE_PORT` env variable. Signed-off-by: Jean Rouge --- Makefile | 21 -------------- containerized.mk | 16 ++++++++--- direct.mk | 22 +++++++++++++++ hack/debug | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 25 deletions(-) create mode 100755 hack/debug diff --git a/Makefile b/Makefile index 8696f2dd64..c940d00919 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,8 @@ # Root directory of the project (absolute path). ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -# Base path used to install. -DESTDIR=/usr/local - -# Used to populate version variable in main package. -VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always) - PROJECT_ROOT=github.com/docker/swarmkit -# Race detector is only supported on amd64. -RACE := $(shell test $$(go env GOARCH) != "amd64" || (echo "-race")) - -# Project packages. -PACKAGES=$(shell go list ./... | grep -v /vendor/) -INTEGRATION_PACKAGE=${PROJECT_ROOT}/integration - -# Project binaries. -COMMANDS=swarmd swarmctl swarm-bench swarm-rafttool protoc-gen-gogoswarm -BINARIES=$(addprefix bin/,$(COMMANDS)) - -VNDR=$(shell which vndr || echo '') - -GO_LDFLAGS=-ldflags "-X `go list ./version`.Version=$(VERSION)" - SHELL := /bin/bash # stop here. do we want to run everything inside of a container, or do we want diff --git a/containerized.mk b/containerized.mk index 4910352242..063112afa7 100644 --- a/containerized.mk +++ b/containerized.mk @@ -2,6 +2,8 @@ IMAGE_NAME=docker/swarmkit GOPATH=/go DOCKER_IMAGE_DIR=${GOPATH}/src/${PROJECT_ROOT} +DOCKER_SWARMKIT_DELVE_PORT ?= 2345 + # don't bother writing every single make target. just pass the call through to # docker and make # we prefer `%:` to `.DEFAULT` as the latter doesn't run phony deps @@ -40,10 +42,16 @@ run: ensure_image_exists @ [ "$$DOCKER_SWARMKIT_DOCKER_RUN_CMD" ] || exit 1 @ DOCKER_RUN_COMMAND="docker run -t -v swarmkit-cache:${GOPATH}" \ && if [ "$$DOCKER_SWARMKIT_USE_DOCKER_SYNC" ]; then \ - $(MAKE) ensure_sync_started && DOCKER_RUN_COMMAND="$$DOCKER_RUN_COMMAND -v swarmkit-sync:${DOCKER_IMAGE_DIR}"; \ + $(MAKE) ensure_sync_started && DOCKER_RUN_COMMAND+=" -v swarmkit-sync:${DOCKER_IMAGE_DIR}"; \ else \ - DOCKER_RUN_COMMAND="$$DOCKER_RUN_COMMAND -v ${ROOTDIR}:${DOCKER_IMAGE_DIR}"; \ + DOCKER_RUN_COMMAND+=" -v ${ROOTDIR}:${DOCKER_IMAGE_DIR}"; \ + fi \ + && if [ "$$DOCKER_SWARMKIT_USE_DELVE" ]; then \ + DOCKER_RUN_COMMAND="DOCKER_SWARMKIT_DELVE_PORT=${DOCKER_SWARMKIT_DELVE_PORT} $$DOCKER_RUN_COMMAND" ; \ + DOCKER_RUN_COMMAND+=" -p ${DOCKER_SWARMKIT_DELVE_PORT}:${DOCKER_SWARMKIT_DELVE_PORT} -e DOCKER_SWARMKIT_DELVE_PORT"; \ + `# see https://github.com/derekparker/delve/issues/515#issuecomment-214911481'` ; \ + DOCKER_RUN_COMMAND+=" --security-opt=seccomp:unconfined"; \ fi \ - && DOCKER_RUN_COMMAND="$$DOCKER_RUN_COMMAND $$DOCKER_SWARMKIT_DOCKER_RUN_FLAGS ${IMAGE_NAME} $$DOCKER_SWARMKIT_DOCKER_RUN_CMD" \ + && DOCKER_RUN_COMMAND+=" $$DOCKER_SWARMKIT_DOCKER_RUN_FLAGS ${IMAGE_NAME} $$DOCKER_SWARMKIT_DOCKER_RUN_CMD" \ && echo $$DOCKER_RUN_COMMAND \ - && $$DOCKER_RUN_COMMAND + && eval $$DOCKER_RUN_COMMAND diff --git a/direct.mk b/direct.mk index 68c5edfa49..0cdeff946a 100644 --- a/direct.mk +++ b/direct.mk @@ -1,3 +1,25 @@ +# Base path used to install. +DESTDIR=/usr/local + +# Used to populate version variable in main package. +VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always) + +# Race detector is only supported on amd64. +RACE := $(shell test $$(go env GOARCH) != "amd64" || (echo "-race")) + +# Project packages. +PACKAGES=$(shell go list ./... | grep -v /vendor/) +INTEGRATION_PACKAGE=${PROJECT_ROOT}/integration + +# Project binaries. +COMMANDS=swarmd swarmctl swarm-bench swarm-rafttool protoc-gen-gogoswarm +BINARIES=$(addprefix bin/,$(COMMANDS)) + +VNDR=$(shell which vndr || echo '') + +GO_LDFLAGS=-ldflags "-X `go list ./version`.Version=$(VERSION)" + + .DEFAULT_GOAL = all .PHONY: all all: check binaries test integration-tests ## run check, build the binaries and run the tests diff --git a/hack/debug b/hack/debug new file mode 100755 index 0000000000..34a23fcf4c --- /dev/null +++ b/hack/debug @@ -0,0 +1,71 @@ +#!/bin/bash + +## Installs delve, then runs it as a headless server +## Keeps running until killed +## Also adds some goodies: delve servers ignore interrupts, which is annoying... +## and also once a debugging session is done, the server just hangs there, which +## is equally annoying. +## This script takes care of both these things + +SUBSHELL_PID= +DLV_PID_FILE= +RUNNING=true + +main() { + [ "$1" ] || usage + + ensure_delve_installed || exit $? + + local PORT="$DOCKER_SWARMKIT_DELVE_PORT" + [ "$PORT" ] || PORT=2345 + + local DLV_CMD="dlv test --accept-multiclient --headless --listen=:$PORT --api-version=2 --log $@" + echo $DLV_CMD + + trap handle_interrupt INT + + DLV_PID_FILE=$(mktemp /tmp/dlv.XXXXXX.pid) + local DLV_OUTPUT_FILE=$(mktemp /tmp/dlv.XXXXXX.out) + + # the weird regex is because we keep the output colored + local HALTING_REGEX='^\e\[37mDEBU\e\[0m\[[0-9]+\] halting\s+\e\[37mlayer\e\[0m=debugger' + while $RUNNING; do + # using `script` to keep colored output, and `exec` to get the PID from the + # subshell + script --flush --quiet "$DLV_OUTPUT_FILE" --command 'printf $$ > '"$DLV_PID_FILE && exec $DLV_CMD" & + SUBSHELL_PID=$! + + # wait for either the subshell to die, or for the "halting" line to appear + # in the output + tail --follow --pid="$SUBSHELL_PID" --sleep-interval=0.1 "$DLV_OUTPUT_FILE" 2> /dev/null | grep --perl-regex --line-buffered "$HALTING_REGEX" | ( read && kill_delve ) + + wait "$SUBSHELL_PID" + done + + rm -f "$DLV_PID_FILE" "$DLV_OUTPUT_FILE" +} + +handle_interrupt() { + RUNNING=false + kill_delve +} + +kill_delve() { + if [ -r "$DLV_PID_FILE" ]; then + local DLV_PID=$(cat "$DLV_PID_FILE") + [ "$DLV_PID" ] && kill "$DLV_PID" &> /dev/null + fi + + [ "$SUBSHELL_PID" ] && kill $SUBSHELL_PID &> /dev/null +} + +ensure_delve_installed() { + which dlv &> /dev/null || go get -u github.com/derekparker/delve/cmd/dlv +} + +usage() { + echo "Usage: $0 name/of/go/package [additional dlv test options]" + exit 1 +} + +main "$@"