contrib/debugshell.py
author Gregory Szorc <gregory.szorc@gmail.com>
Fri, 15 Mar 2019 11:24:08 -0700
changeset 42024 b05a3e28cf24
parent 41819 b10bbbe995eb
child 43076 2372284d9457
permissions -rw-r--r--
automation: perform tasks on remote machines Sometimes you don't have access to a machine in order to do something. For example, you may not have access to a Windows machine required to build Windows binaries or run tests on that platform. This commit introduces a pile of code intended to help "automate" common tasks, like building release artifacts. In its current form, the automation code provides functionality for performing tasks on Windows EC2 instances. The hgautomation.aws module provides functionality for integrating with AWS. It manages EC2 resources such as IAM roles, EC2 security groups, AMIs, and instances. The hgautomation.windows module provides a higher-level interface for performing tasks on remote Windows machines. The hgautomation.cli module provides a command-line interface to these higher-level primitives. I attempted to structure Windows remote machine interaction around Windows Remoting / PowerShell. This is kinda/sorta like SSH + shell, but for Windows. In theory, most of the functionality is cloud provider agnostic, as we should be able to use any established WinRM connection to interact with a remote. In reality, we're tightly coupled to AWS at the moment because I didn't want to prematurely add abstractions for a 2nd cloud provider. (1 was hard enough to implement.) In the aws module is code for creating an image with a fully functional Mercurial development environment. It contains VC9, VC2017, msys, and other dependencies. The image is fully capable of building all the existing Mercurial release artifacts and running tests. There are a few things that don't work. For example, running Windows tests with Python 3. But building the Windows release artifacts does work. And that was an impetus for this work. (Although we don't yet support code signing.) Getting this functionality to work was extremely time consuming. It took hours debugging permissions failures and other wonky behavior due to PowerShell Remoting. (The permissions model for PowerShell is crazy and you brush up against all kinds of issues because of the user/privileges of the user running the PowerShell and the permissions of the PowerShell session itself.) The functionality around AWS resource management could use some improving. In theory we support shared tenancy via resource name prefixing. In reality, we don't offer a way to configure this. Speaking of AWS resource management, I thought about using a tool like Terraform to manage resources. But at our scale, writing a few dozen lines of code to manage resources seemed acceptable. Maybe we should reconsider this if things grow out of control. Time will tell. Currently, emphasis is placed on Windows. But I only started there because it was likely to be the most difficult to implement. It should be relatively trivial to automate tasks on remote Linux machines. In fact, I have a ~1 year old script to run tests on a remote EC2 instance. I will likely be porting that to this new "framework" in the near future. # no-check-commit because foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6142
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11633
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
     1
# debugshell extension
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
     2
"""a python shell with repo, changelog & manifest objects"""
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
     3
28476
e28dc6de38e7 debugshell: use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27721
diff changeset
     4
from __future__ import absolute_import
e28dc6de38e7 debugshell: use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27721
diff changeset
     5
import code
11633
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
     6
import mercurial
28476
e28dc6de38e7 debugshell: use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27721
diff changeset
     7
import sys
27721
e4b512bb6386 debugshell: disable demand importer when importing debugger
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21243
diff changeset
     8
from mercurial import (
e4b512bb6386 debugshell: disable demand importer when importing debugger
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21243
diff changeset
     9
    demandimport,
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    10
    pycompat,
32376
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30385
diff changeset
    11
    registrar,
27721
e4b512bb6386 debugshell: disable demand importer when importing debugger
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21243
diff changeset
    12
)
21243
8b5c039f2b4f debugshell: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19794
diff changeset
    13
8b5c039f2b4f debugshell: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 19794
diff changeset
    14
cmdtable = {}
32376
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30385
diff changeset
    15
command = registrar.command(cmdtable)
11633
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    16
19771
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    17
def pdb(ui, repo, msg, **opts):
11633
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    18
    objects = {
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    19
        'mercurial': mercurial,
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    20
        'repo': repo,
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    21
        'cl': repo.changelog,
30385
11b8b740d54a manifest: remove last uses of repo.manifest
Durham Goode <durham@fb.com>
parents: 29397
diff changeset
    22
        'mf': repo.manifestlog,
11633
6b7b99867ada contrib: add debugshell extension
Vishakh H <vsh426@gmail.com>
parents:
diff changeset
    23
    }
19771
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    24
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    25
    code.interact(msg, local=objects)
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    26
19772
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    27
def ipdb(ui, repo, msg, **opts):
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    28
    import IPython
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    29
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    30
    cl = repo.changelog
30385
11b8b740d54a manifest: remove last uses of repo.manifest
Durham Goode <durham@fb.com>
parents: 29397
diff changeset
    31
    mf = repo.manifestlog
19794
cccc44304b2c debugshell: appease pyflakes
Matt Mackall <mpm@selenic.com>
parents: 19773
diff changeset
    32
    cl, mf # use variables to appease pyflakes
19772
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    33
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    34
    IPython.embed()
6ccec36a1fd9 debugshell: add function to embed ipython
Sean Farley <sean.michael.farley@gmail.com>
parents: 19771
diff changeset
    35
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    36
@command(b'debugshell|dbsh', [])
19771
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    37
def debugshell(ui, repo, **opts):
41768
aaad36b88298 cleanup: use () to wrap long lines instead of \
Augie Fackler <augie@google.com>
parents: 32376
diff changeset
    38
    bannermsg = ("loaded repo : %s\n"
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    39
                 "using source: %s" % (pycompat.sysstr(repo.root),
41768
aaad36b88298 cleanup: use () to wrap long lines instead of \
Augie Fackler <augie@google.com>
parents: 32376
diff changeset
    40
                                       mercurial.__path__[0]))
19771
3bc675361206 debugshell: abstract out pdb code.interact
Sean Farley <sean.michael.farley@gmail.com>
parents: 11633
diff changeset
    41
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    42
    pdbmap = {
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    43
        'pdb'  : 'code',
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    44
        'ipdb' : 'IPython'
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    45
    }
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    46
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    47
    debugger = ui.config(b"ui", b"debugger")
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    48
    if not debugger:
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    49
        debugger = 'pdb'
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    50
    else:
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    51
        debugger = pycompat.sysstr(debugger)
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    52
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    53
    # if IPython doesn't exist, fallback to code.interact
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    54
    try:
27721
e4b512bb6386 debugshell: disable demand importer when importing debugger
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21243
diff changeset
    55
        with demandimport.deactivated():
e4b512bb6386 debugshell: disable demand importer when importing debugger
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21243
diff changeset
    56
            __import__(pdbmap[debugger])
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    57
    except ImportError:
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    58
        ui.warn((b"%s debugger specified but %s module was not found\n")
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    59
                % (debugger, pdbmap[debugger]))
41819
b10bbbe995eb py3: make contrib/debugshell.py work with Python 3
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
    60
        debugger = b'pdb'
19773
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    61
51799a965446 debugshell: check ui.debugger for which debugger to use
Sean Farley <sean.michael.farley@gmail.com>
parents: 19772
diff changeset
    62
    getattr(sys.modules[__name__], debugger)(ui, repo, bannermsg, **opts)