view contrib/dockerlib.sh @ 36528:72e487851a53

debugcommands: add debugwireproto command We currently don't have a low-level mechanism for sending arbitrary wire protocol commands. Having a generic and robust mechanism for sending wire protocol commands, examining wire data, etc would make it vastly easier to test the wire protocol and debug server operation. This is a problem I've wanted a solution for numerous times, especially recently as I've been hacking on a new version of the wire protocol. This commit establishes a `hg debugwireproto` command for sending data to a peer. The command invents a mini language for specifying actions to take. This will enable a lot of flexibility for issuing commands and testing variations for how commands are sent. Right now, we only support low-level raw sends and receives. These are probably the least valuable commands to intended users of this command. But they are the most useful commands to implement to bootstrap the feature (I've chosen to reimplement test-ssh-proto.t using this command to prove its usefulness). My eventual goal of `hg debugwireproto` is to allow calling wire protocol commands with a human-friendly interface. Essentially, people can type in a command name and arguments and `hg debugwireproto` will figure out how to send that on the wire. I'd love to eventually be able to save the server's raw response to a file. This would allow us to e.g. call "getbundle" wire protocol commands easily. test-ssh-proto.t has been updated to use the new command in lieu of piping directly to a server process. As part of the transition, test behavior improved. Before, we piped all request data to the server at once. Now, we have explicit control over the ordering of operations. e.g. we can send one command, receive its response, then send another command. This will allow us to more robustly test race conditions, buffering behavior, etc. There were some subtle changes in test behavior. For example, previous behavior would often send trailing newlines to the server. The new mechanism doesn't treat literal newlines specially and requires newlines be escaped in the payload. Because the new logging code is very low level, it is easy to introduce race conditions in tests. For example, the number of bytes returned by a read() may vary depending on load. This is why tests make heavy use of "readline" for consuming data: the result of that operation should be deterministic and not subject to race conditions. There are still some uses of "readavailable." However, those are only for reading from stderr. I was able to reproduce timing issues with my system under load when using "readavailable" globally. But if I "readline" to grab stdout, "readavailable" appears to work deterministically for stderr. I think this is because the server writes to stderr first. As long as the OS delivers writes to pipes in the same order they were made, this should work. If there are timing issues, we can introduce a mechanism to readline from stderr. Differential Revision: https://phab.mercurial-scm.org/D2392
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 01 Mar 2018 08:24:54 -0800
parents a3ac1ea611ce
children 1335bbfb066f
line wrap: on
line source

#!/bin/sh -eu

# This function exists to set up the DOCKER variable and verify that
# it's the binary we expect. It also verifies that the docker service
# is running on the system and we can talk to it.
function checkdocker() {
  if which docker.io >> /dev/null 2>&1 ; then
    DOCKER=docker.io
  elif which docker >> /dev/null 2>&1 ; then
    DOCKER=docker
  else
    echo "Error: docker must be installed"
    exit 1
  fi

  $DOCKER -h 2> /dev/null | grep -q Jansens && { echo "Error: $DOCKER is the Docking System Tray - install docker.io instead"; exit 1; }
  $DOCKER version | grep -Eq "^Client( version)?:" || { echo "Error: unexpected output from \"$DOCKER version\""; exit 1; }
  $DOCKER version | grep -Eq "^Server( version)?:" || { echo "Error: could not get docker server version - check it is running and your permissions"; exit 1; }
}

# Construct a container and leave its name in $CONTAINER for future use.
function initcontainer() {
  [ "$1" ] || { echo "Error: platform name must be specified"; exit 1; }

  DFILE="$ROOTDIR/contrib/docker/$1"
  [ -f "$DFILE" ] || { echo "Error: docker file $DFILE not found"; exit 1; }

  CONTAINER="hg-dockerrpm-$1"
  DBUILDUSER=build
  (
    cat $DFILE
    if [ $(uname) = "Darwin" ] ; then
        # The builder is using boot2docker on OS X, so we're going to
        # *guess* the uid of the user inside the VM that is actually
        # running docker. This is *very likely* to fail at some point.
        echo RUN useradd $DBUILDUSER -u 1000
    else
        echo RUN groupadd $DBUILDUSER -g `id -g` -o
        echo RUN useradd $DBUILDUSER -u `id -u` -g $DBUILDUSER -o
    fi
  ) | $DOCKER build --build-arg http_proxy --build-arg https_proxy --tag $CONTAINER -
}