contrib/automation/hgautomation/aws.py
author Gregory Szorc <gregory.szorc@gmail.com>
Thu, 05 Dec 2019 17:42:38 -0800
changeset 43823 3d53f9cc73ab
parent 43411 a77338d2bdab
child 44739 828d3277618a
permissions -rw-r--r--
automation: use latest Windows AMI as base It looks like the previous base image no longer exists. I guess Amazon expires them or something. Let's switch to the newest version of the equivalent image. Differential Revision: https://phab.mercurial-scm.org/D7571
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
# aws.py - Automation code for Amazon Web Services
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
# no-check-code because Python 3 native.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
import contextlib
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
import copy
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
import hashlib
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
import json
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
import os
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
import pathlib
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
import subprocess
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
import time
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
import boto3
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
import botocore.exceptions
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    21
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    22
from .linux import BOOTSTRAP_DEBIAN
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    23
from .ssh import (
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    24
    exec_command as ssh_exec_command,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    25
    wait_for_ssh,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    26
)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    27
from .winrm import (
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    28
    run_powershell,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
    wait_for_winrm,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    33
SOURCE_ROOT = pathlib.Path(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    34
    os.path.abspath(__file__)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    35
).parent.parent.parent.parent
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    37
INSTALL_WINDOWS_DEPENDENCIES = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    38
    SOURCE_ROOT / 'contrib' / 'install-windows-dependencies.ps1'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
    39
)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    42
INSTANCE_TYPES_WITH_STORAGE = {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    43
    'c5d',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    44
    'd2',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    45
    'h1',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    46
    'i3',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    47
    'm5ad',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    48
    'm5d',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    49
    'r5d',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    50
    'r5ad',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    51
    'x1',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    52
    'z1d',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    53
}
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    54
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    55
42647
8804aa6c07a0 automation: extract strings to constants
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42646
diff changeset
    56
AMAZON_ACCOUNT_ID = '801119661308'
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    57
DEBIAN_ACCOUNT_ID = '379101102735'
43018
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
    58
DEBIAN_ACCOUNT_ID_2 = '136693071363'
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    59
UBUNTU_ACCOUNT_ID = '099720109477'
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    60
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    61
43823
3d53f9cc73ab automation: use latest Windows AMI as base
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43411
diff changeset
    62
WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2019-English-Full-Base-2019.11.13'
42647
8804aa6c07a0 automation: extract strings to constants
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42646
diff changeset
    63
8804aa6c07a0 automation: extract strings to constants
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42646
diff changeset
    64
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
KEY_PAIRS = {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
    'automation',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    69
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
SECURITY_GROUPS = {
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    71
    'linux-dev-1': {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    72
        'description': 'Mercurial Linux instances that perform build/test automation',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    73
        'ingress': [
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    74
            {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    75
                'FromPort': 22,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    76
                'ToPort': 22,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    77
                'IpProtocol': 'tcp',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    78
                'IpRanges': [
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    79
                    {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    80
                        'CidrIp': '0.0.0.0/0',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    81
                        'Description': 'SSH from entire Internet',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    82
                    },
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    83
                ],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    84
            },
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    85
        ],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
    86
    },
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    87
    'windows-dev-1': {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    88
        'description': 'Mercurial Windows instances that perform build automation',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    89
        'ingress': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    90
            {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    91
                'FromPort': 22,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    92
                'ToPort': 22,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    93
                'IpProtocol': 'tcp',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    94
                'IpRanges': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
                    {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
                        'CidrIp': '0.0.0.0/0',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
                        'Description': 'SSH from entire Internet',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    98
                    },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    99
                ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
            },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   101
            {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
                'FromPort': 3389,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   103
                'ToPort': 3389,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   104
                'IpProtocol': 'tcp',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
                'IpRanges': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   106
                    {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
                        'CidrIp': '0.0.0.0/0',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
                        'Description': 'RDP from entire Internet',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   109
                    },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   110
                ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   111
            },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   112
            {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   113
                'FromPort': 5985,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   114
                'ToPort': 5986,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   115
                'IpProtocol': 'tcp',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   116
                'IpRanges': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   117
                    {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
                        'CidrIp': '0.0.0.0/0',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   119
                        'Description': 'PowerShell Remoting (Windows Remote Management)',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   120
                    },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   121
                ],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   122
            },
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   123
        ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   124
    },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   126
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   127
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   128
IAM_ROLES = {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   129
    'ephemeral-ec2-role-1': {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   130
        'description': 'Mercurial temporary EC2 instances',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   131
        'policy_arns': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   132
            'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   133
        ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   134
    },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   135
}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   136
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   137
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   138
ASSUME_ROLE_POLICY_DOCUMENT = '''
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   139
{
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   140
  "Version": "2012-10-17",
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   141
  "Statement": [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   142
    {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   143
      "Effect": "Allow",
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   144
      "Principal": {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   145
        "Service": "ec2.amazonaws.com"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   146
      },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   147
      "Action": "sts:AssumeRole"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   148
    }
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   149
  ]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   150
}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   151
'''.strip()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   152
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   153
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   154
IAM_INSTANCE_PROFILES = {
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   155
    'ephemeral-ec2-1': {'roles': ['ephemeral-ec2-role-1',],}
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   156
}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   157
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   158
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   159
# User Data for Windows EC2 instance. Mainly used to set the password
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   160
# and configure WinRM.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   161
# Inspired by the User Data script used by Packer
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   162
# (from https://www.packer.io/intro/getting-started/build-image.html).
42064
0e9066db5e44 automation: use raw strings when there are backslashes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42024
diff changeset
   163
WINDOWS_USER_DATA = r'''
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   164
<powershell>
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   165
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   166
# TODO enable this once we figure out what is failing.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   167
#$ErrorActionPreference = "stop"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   168
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   169
# Set administrator password
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   170
net user Administrator "%s"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   171
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   172
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   173
# First, make sure WinRM can't be connected to
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   174
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   175
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   176
# Delete any existing WinRM listeners
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   177
winrm delete winrm/config/listener?Address=*+Transport=HTTP  2>$Null
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   178
winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   179
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   180
# Create a new WinRM listener and configure
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   181
winrm create winrm/config/listener?Address=*+Transport=HTTP
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   182
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   183
winrm set winrm/config '@{MaxTimeoutms="7200000"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   184
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   185
winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   186
winrm set winrm/config/service/auth '@{Basic="true"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   187
winrm set winrm/config/client/auth '@{Basic="true"}'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   188
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   189
# Configure UAC to allow privilege elevation in remote shells
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   190
$Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   191
$Setting = 'LocalAccountTokenFilterPolicy'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   192
Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   193
43411
a77338d2bdab automation: avoid '~' in the temp directory on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 43234
diff changeset
   194
# Avoid long usernames in the temp directory path because the '~' causes extra quoting in ssh output
a77338d2bdab automation: avoid '~' in the temp directory on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 43234
diff changeset
   195
[System.Environment]::SetEnvironmentVariable('TMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
a77338d2bdab automation: avoid '~' in the temp directory on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 43234
diff changeset
   196
[System.Environment]::SetEnvironmentVariable('TEMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
a77338d2bdab automation: avoid '~' in the temp directory on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 43234
diff changeset
   197
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   198
# Configure and restart the WinRM Service; Enable the required firewall exception
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   199
Stop-Service -Name WinRM
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   200
Set-Service -Name WinRM -StartupType Automatic
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   201
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   202
Start-Service -Name WinRM
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   203
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   204
# Disable firewall on private network interfaces so prompts don't appear.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   205
Set-NetFirewallProfile -Name private -Enabled false
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   206
</powershell>
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   207
'''.lstrip()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   208
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   209
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   210
WINDOWS_BOOTSTRAP_POWERSHELL = '''
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   211
Write-Output "installing PowerShell dependencies"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   212
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   213
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   214
Install-Module -Name OpenSSHUtils -RequiredVersion 0.0.2.0
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   215
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   216
Write-Output "installing OpenSSL server"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   217
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   218
# Various tools will attempt to use older versions of .NET. So we enable
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   219
# the feature that provides them so it doesn't have to be auto-enabled
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   220
# later.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   221
Write-Output "enabling .NET Framework feature"
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   222
Install-WindowsFeature -Name Net-Framework-Core
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   223
'''
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   224
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   225
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   226
class AWSConnection:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   227
    """Manages the state of a connection with AWS."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   228
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   229
    def __init__(self, automation, region: str, ensure_ec2_state: bool = True):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   230
        self.automation = automation
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   231
        self.local_state_path = automation.state_path
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   232
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   233
        self.prefix = 'hg-'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   234
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   235
        self.session = boto3.session.Session(region_name=region)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   236
        self.ec2client = self.session.client('ec2')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   237
        self.ec2resource = self.session.resource('ec2')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   238
        self.iamclient = self.session.client('iam')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   239
        self.iamresource = self.session.resource('iam')
42277
dd6a9723ae2b automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42276
diff changeset
   240
        self.security_groups = {}
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   241
42277
dd6a9723ae2b automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42276
diff changeset
   242
        if ensure_ec2_state:
dd6a9723ae2b automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42276
diff changeset
   243
            ensure_key_pairs(automation.state_path, self.ec2resource)
dd6a9723ae2b automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42276
diff changeset
   244
            self.security_groups = ensure_security_groups(self.ec2resource)
42278
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   245
            ensure_iam_state(self.iamclient, self.iamresource)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   246
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   247
    def key_pair_path_private(self, name):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   248
        """Path to a key pair private key file."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   249
        return self.local_state_path / 'keys' / ('keypair-%s' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   250
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   251
    def key_pair_path_public(self, name):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   252
        return self.local_state_path / 'keys' / ('keypair-%s.pub' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   253
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   254
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   255
def rsa_key_fingerprint(p: pathlib.Path):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   256
    """Compute the fingerprint of an RSA private key."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   257
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   258
    # TODO use rsa package.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   259
    res = subprocess.run(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   260
        [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   261
            'openssl',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   262
            'pkcs8',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   263
            '-in',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   264
            str(p),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   265
            '-nocrypt',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   266
            '-topk8',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   267
            '-outform',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   268
            'DER',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   269
        ],
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   270
        capture_output=True,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   271
        check=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   272
    )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   273
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   274
    sha1 = hashlib.sha1(res.stdout).hexdigest()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   275
    return ':'.join(a + b for a, b in zip(sha1[::2], sha1[1::2]))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   276
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   277
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   278
def ensure_key_pairs(state_path: pathlib.Path, ec2resource, prefix='hg-'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   279
    remote_existing = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   280
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   281
    for kpi in ec2resource.key_pairs.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   282
        if kpi.name.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   283
            remote_existing[kpi.name[len(prefix) :]] = kpi.key_fingerprint
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   284
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   285
    # Validate that we have these keys locally.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   286
    key_path = state_path / 'keys'
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   287
    key_path.mkdir(exist_ok=True, mode=0o700)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   288
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   289
    def remove_remote(name):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   290
        print('deleting key pair %s' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   291
        key = ec2resource.KeyPair(name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   292
        key.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   293
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   294
    def remove_local(name):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   295
        pub_full = key_path / ('keypair-%s.pub' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   296
        priv_full = key_path / ('keypair-%s' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   297
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   298
        print('removing %s' % pub_full)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   299
        pub_full.unlink()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   300
        print('removing %s' % priv_full)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   301
        priv_full.unlink()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   302
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   303
    local_existing = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   304
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   305
    for f in sorted(os.listdir(key_path)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   306
        if not f.startswith('keypair-') or not f.endswith('.pub'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   307
            continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   308
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   309
        name = f[len('keypair-') : -len('.pub')]
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   310
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   311
        pub_full = key_path / f
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   312
        priv_full = key_path / ('keypair-%s' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   313
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   314
        with open(pub_full, 'r', encoding='ascii') as fh:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   315
            data = fh.read()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   316
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   317
        if not data.startswith('ssh-rsa '):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   318
            print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   319
                'unexpected format for key pair file: %s; removing' % pub_full
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   320
            )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   321
            pub_full.unlink()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   322
            priv_full.unlink()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   323
            continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   324
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   325
        local_existing[name] = rsa_key_fingerprint(priv_full)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   326
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   327
    for name in sorted(set(remote_existing) | set(local_existing)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   328
        if name not in local_existing:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   329
            actual = '%s%s' % (prefix, name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   330
            print('remote key %s does not exist locally' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   331
            remove_remote(actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   332
            del remote_existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   333
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   334
        elif name not in remote_existing:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   335
            print('local key %s does not exist remotely' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   336
            remove_local(name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   337
            del local_existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   338
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   339
        elif remote_existing[name] != local_existing[name]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   340
            print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   341
                'key fingerprint mismatch for %s; '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   342
                'removing from local and remote' % name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   343
            )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   344
            remove_local(name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   345
            remove_remote('%s%s' % (prefix, name))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   346
            del local_existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   347
            del remote_existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   348
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   349
    missing = KEY_PAIRS - set(remote_existing)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   350
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   351
    for name in sorted(missing):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   352
        actual = '%s%s' % (prefix, name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   353
        print('creating key pair %s' % actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   354
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   355
        priv_full = key_path / ('keypair-%s' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   356
        pub_full = key_path / ('keypair-%s.pub' % name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   357
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   358
        kp = ec2resource.create_key_pair(KeyName=actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   359
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   360
        with priv_full.open('w', encoding='ascii') as fh:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   361
            fh.write(kp.key_material)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   362
            fh.write('\n')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   363
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   364
        priv_full.chmod(0o0600)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   365
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   366
        # SSH public key can be extracted via `ssh-keygen`.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   367
        with pub_full.open('w', encoding='ascii') as fh:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   368
            subprocess.run(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   369
                ['ssh-keygen', '-y', '-f', str(priv_full)],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   370
                stdout=fh,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   371
                check=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   372
            )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   373
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   374
        pub_full.chmod(0o0600)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   375
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   376
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   377
def delete_instance_profile(profile):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   378
    for role in profile.roles:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   379
        print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   380
            'removing role %s from instance profile %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   381
            % (role.name, profile.name)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   382
        )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   383
        profile.remove_role(RoleName=role.name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   384
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   385
    print('deleting instance profile %s' % profile.name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   386
    profile.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   387
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   388
42278
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   389
def ensure_iam_state(iamclient, iamresource, prefix='hg-'):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   390
    """Ensure IAM state is in sync with our canonical definition."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   391
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   392
    remote_profiles = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   393
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   394
    for profile in iamresource.instance_profiles.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   395
        if profile.name.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   396
            remote_profiles[profile.name[len(prefix) :]] = profile
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   397
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   398
    for name in sorted(set(remote_profiles) - set(IAM_INSTANCE_PROFILES)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   399
        delete_instance_profile(remote_profiles[name])
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   400
        del remote_profiles[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   401
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   402
    remote_roles = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   403
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   404
    for role in iamresource.roles.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   405
        if role.name.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   406
            remote_roles[role.name[len(prefix) :]] = role
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   407
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   408
    for name in sorted(set(remote_roles) - set(IAM_ROLES)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   409
        role = remote_roles[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   410
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   411
        print('removing role %s' % role.name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   412
        role.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   413
        del remote_roles[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   414
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   415
    # We've purged remote state that doesn't belong. Create missing
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   416
    # instance profiles and roles.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   417
    for name in sorted(set(IAM_INSTANCE_PROFILES) - set(remote_profiles)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   418
        actual = '%s%s' % (prefix, name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   419
        print('creating IAM instance profile %s' % actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   420
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   421
        profile = iamresource.create_instance_profile(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   422
            InstanceProfileName=actual
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   423
        )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   424
        remote_profiles[name] = profile
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   425
42278
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   426
        waiter = iamclient.get_waiter('instance_profile_exists')
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   427
        waiter.wait(InstanceProfileName=actual)
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   428
        print('IAM instance profile %s is available' % actual)
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   429
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   430
    for name in sorted(set(IAM_ROLES) - set(remote_roles)):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   431
        entry = IAM_ROLES[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   432
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   433
        actual = '%s%s' % (prefix, name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   434
        print('creating IAM role %s' % actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   435
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   436
        role = iamresource.create_role(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   437
            RoleName=actual,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   438
            Description=entry['description'],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   439
            AssumeRolePolicyDocument=ASSUME_ROLE_POLICY_DOCUMENT,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   440
        )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   441
42278
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   442
        waiter = iamclient.get_waiter('role_exists')
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   443
        waiter.wait(RoleName=actual)
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   444
        print('IAM role %s is available' % actual)
8dc22a209420 automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42277
diff changeset
   445
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   446
        remote_roles[name] = role
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   447
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   448
        for arn in entry['policy_arns']:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   449
            print('attaching policy %s to %s' % (arn, role.name))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   450
            role.attach_policy(PolicyArn=arn)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   451
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   452
    # Now reconcile state of profiles.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   453
    for name, meta in sorted(IAM_INSTANCE_PROFILES.items()):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   454
        profile = remote_profiles[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   455
        wanted = {'%s%s' % (prefix, role) for role in meta['roles']}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   456
        have = {role.name for role in profile.roles}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   457
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   458
        for role in sorted(have - wanted):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   459
            print('removing role %s from %s' % (role, profile.name))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   460
            profile.remove_role(RoleName=role)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   461
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   462
        for role in sorted(wanted - have):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   463
            print('adding role %s to %s' % (role, profile.name))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   464
            profile.add_role(RoleName=role)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   465
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   466
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   467
def find_image(ec2resource, owner_id, name):
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   468
    """Find an AMI by its owner ID and name."""
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   469
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   470
    images = ec2resource.images.filter(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   471
        Filters=[
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   472
            {'Name': 'owner-id', 'Values': [owner_id],},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   473
            {'Name': 'state', 'Values': ['available'],},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   474
            {'Name': 'image-type', 'Values': ['machine'],},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   475
            {'Name': 'name', 'Values': [name],},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   476
        ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   477
    )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   478
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   479
    for image in images:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   480
        return image
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   481
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   482
    raise Exception('unable to find image for %s' % name)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   483
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   484
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   485
def ensure_security_groups(ec2resource, prefix='hg-'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   486
    """Ensure all necessary Mercurial security groups are present.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   487
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   488
    All security groups are prefixed with ``hg-`` by default. Any security
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   489
    groups having this prefix but aren't in our list are deleted.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   490
    """
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   491
    existing = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   492
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   493
    for group in ec2resource.security_groups.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   494
        if group.group_name.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   495
            existing[group.group_name[len(prefix) :]] = group
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   496
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   497
    purge = set(existing) - set(SECURITY_GROUPS)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   498
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   499
    for name in sorted(purge):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   500
        group = existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   501
        print('removing legacy security group: %s' % group.group_name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   502
        group.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   503
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   504
    security_groups = {}
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   505
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   506
    for name, group in sorted(SECURITY_GROUPS.items()):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   507
        if name in existing:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   508
            security_groups[name] = existing[name]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   509
            continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   510
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   511
        actual = '%s%s' % (prefix, name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   512
        print('adding security group %s' % actual)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   513
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   514
        group_res = ec2resource.create_security_group(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   515
            Description=group['description'], GroupName=actual,
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   516
        )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   517
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   518
        group_res.authorize_ingress(IpPermissions=group['ingress'],)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   519
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   520
        security_groups[name] = group_res
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   521
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   522
    return security_groups
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   523
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   524
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   525
def terminate_ec2_instances(ec2resource, prefix='hg-'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   526
    """Terminate all EC2 instances managed by us."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   527
    waiting = []
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   528
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   529
    for instance in ec2resource.instances.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   530
        if instance.state['Name'] == 'terminated':
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   531
            continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   532
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   533
        for tag in instance.tags or []:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   534
            if tag['Key'] == 'Name' and tag['Value'].startswith(prefix):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   535
                print('terminating %s' % instance.id)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   536
                instance.terminate()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   537
                waiting.append(instance)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   538
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   539
    for instance in waiting:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   540
        instance.wait_until_terminated()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   541
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   542
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   543
def remove_resources(c, prefix='hg-'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   544
    """Purge all of our resources in this EC2 region."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   545
    ec2resource = c.ec2resource
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   546
    iamresource = c.iamresource
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   547
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   548
    terminate_ec2_instances(ec2resource, prefix=prefix)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   549
42275
730edbd836d8 automation: only iterate over our AMIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42064
diff changeset
   550
    for image in ec2resource.images.filter(Owners=['self']):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   551
        if image.name.startswith(prefix):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   552
            remove_ami(ec2resource, image)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   553
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   554
    for group in ec2resource.security_groups.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   555
        if group.group_name.startswith(prefix):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   556
            print('removing security group %s' % group.group_name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   557
            group.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   558
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   559
    for profile in iamresource.instance_profiles.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   560
        if profile.name.startswith(prefix):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   561
            delete_instance_profile(profile)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   562
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   563
    for role in iamresource.roles.all():
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   564
        if role.name.startswith(prefix):
42276
fcb97cb91ff8 automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42275
diff changeset
   565
            for p in role.attached_policies.all():
fcb97cb91ff8 automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42275
diff changeset
   566
                print('detaching policy %s from %s' % (p.arn, role.name))
fcb97cb91ff8 automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42275
diff changeset
   567
                role.detach_policy(PolicyArn=p.arn)
fcb97cb91ff8 automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42275
diff changeset
   568
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   569
            print('removing role %s' % role.name)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   570
            role.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   571
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   572
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   573
def wait_for_ip_addresses(instances):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   574
    """Wait for the public IP addresses of an iterable of instances."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   575
    for instance in instances:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   576
        while True:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   577
            if not instance.public_ip_address:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   578
                time.sleep(2)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   579
                instance.reload()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   580
                continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   581
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   582
            print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   583
                'public IP address for %s: %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   584
                % (instance.id, instance.public_ip_address)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   585
            )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   586
            break
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   587
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   588
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   589
def remove_ami(ec2resource, image):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   590
    """Remove an AMI and its underlying snapshots."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   591
    snapshots = []
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   592
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   593
    for device in image.block_device_mappings:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   594
        if 'Ebs' in device:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   595
            snapshots.append(ec2resource.Snapshot(device['Ebs']['SnapshotId']))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   596
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   597
    print('deregistering %s' % image.id)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   598
    image.deregister()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   599
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   600
    for snapshot in snapshots:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   601
        print('deleting snapshot %s' % snapshot.id)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   602
        snapshot.delete()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   603
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   604
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   605
def wait_for_ssm(ssmclient, instances):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   606
    """Wait for SSM to come online for an iterable of instance IDs."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   607
    while True:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   608
        res = ssmclient.describe_instance_information(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   609
            Filters=[
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   610
                {'Key': 'InstanceIds', 'Values': [i.id for i in instances],},
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   611
            ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   612
        )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   613
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   614
        available = len(res['InstanceInformationList'])
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   615
        wanted = len(instances)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   616
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   617
        print('%d/%d instances available in SSM' % (available, wanted))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   618
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   619
        if available == wanted:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   620
            return
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   621
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   622
        time.sleep(2)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   623
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   624
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   625
def run_ssm_command(ssmclient, instances, document_name, parameters):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   626
    """Run a PowerShell script on an EC2 instance."""
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   627
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   628
    res = ssmclient.send_command(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   629
        InstanceIds=[i.id for i in instances],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   630
        DocumentName=document_name,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   631
        Parameters=parameters,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   632
        CloudWatchOutputConfig={'CloudWatchOutputEnabled': True,},
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   633
    )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   634
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   635
    command_id = res['Command']['CommandId']
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   636
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   637
    for instance in instances:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   638
        while True:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   639
            try:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   640
                res = ssmclient.get_command_invocation(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   641
                    CommandId=command_id, InstanceId=instance.id,
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   642
                )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   643
            except botocore.exceptions.ClientError as e:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   644
                if e.response['Error']['Code'] == 'InvocationDoesNotExist':
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   645
                    print('could not find SSM command invocation; waiting')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   646
                    time.sleep(1)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   647
                    continue
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   648
                else:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   649
                    raise
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   650
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   651
            if res['Status'] == 'Success':
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   652
                break
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   653
            elif res['Status'] in ('Pending', 'InProgress', 'Delayed'):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   654
                time.sleep(2)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   655
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   656
                raise Exception(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   657
                    'command failed on %s: %s' % (instance.id, res['Status'])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   658
                )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   659
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   660
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   661
@contextlib.contextmanager
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   662
def temporary_ec2_instances(ec2resource, config):
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   663
    """Create temporary EC2 instances.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   664
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   665
    This is a proxy to ``ec2client.run_instances(**config)`` that takes care of
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   666
    managing the lifecycle of the instances.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   667
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   668
    When the context manager exits, the instances are terminated.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   669
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   670
    The context manager evaluates to the list of data structures
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   671
    describing each created instance. The instances may not be available
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   672
    for work immediately: it is up to the caller to wait for the instance
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   673
    to start responding.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   674
    """
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   675
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   676
    ids = None
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   677
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   678
    try:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   679
        res = ec2resource.create_instances(**config)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   680
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   681
        ids = [i.id for i in res]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   682
        print('started instances: %s' % ' '.join(ids))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   683
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   684
        yield res
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   685
    finally:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   686
        if ids:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   687
            print('terminating instances: %s' % ' '.join(ids))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   688
            for instance in res:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   689
                instance.terminate()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   690
            print('terminated %d instances' % len(ids))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   691
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   692
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   693
@contextlib.contextmanager
43234
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   694
def create_temp_windows_ec2_instances(
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   695
    c: AWSConnection, config, bootstrap: bool = False
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   696
):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   697
    """Create temporary Windows EC2 instances.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   698
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   699
    This is a higher-level wrapper around ``create_temp_ec2_instances()`` that
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   700
    configures the Windows instance for Windows Remote Management. The emitted
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   701
    instances will have a ``winrm_client`` attribute containing a
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   702
    ``pypsrp.client.Client`` instance bound to the instance.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   703
    """
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   704
    if 'IamInstanceProfile' in config:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   705
        raise ValueError('IamInstanceProfile cannot be provided in config')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   706
    if 'UserData' in config:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   707
        raise ValueError('UserData cannot be provided in config')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   708
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   709
    password = c.automation.default_password()
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   710
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   711
    config = copy.deepcopy(config)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   712
    config['IamInstanceProfile'] = {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   713
        'Name': 'hg-ephemeral-ec2-1',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   714
    }
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   715
    config.setdefault('TagSpecifications', []).append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   716
        {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   717
            'ResourceType': 'instance',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   718
            'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   719
        }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   720
    )
43234
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   721
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   722
    if bootstrap:
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   723
        config['UserData'] = WINDOWS_USER_DATA % password
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   724
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   725
    with temporary_ec2_instances(c.ec2resource, config) as instances:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   726
        wait_for_ip_addresses(instances)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   727
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   728
        print('waiting for Windows Remote Management service...')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   729
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   730
        for instance in instances:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   731
            client = wait_for_winrm(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   732
                instance.public_ip_address, 'Administrator', password
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   733
            )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   734
            print('established WinRM connection to %s' % instance.id)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   735
            instance.winrm_client = client
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   736
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   737
        yield instances
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   738
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   739
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   740
def resolve_fingerprint(fingerprint):
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   741
    fingerprint = json.dumps(fingerprint, sort_keys=True)
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   742
    return hashlib.sha256(fingerprint.encode('utf-8')).hexdigest()
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   743
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   744
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   745
def find_and_reconcile_image(ec2resource, name, fingerprint):
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   746
    """Attempt to find an existing EC2 AMI with a name and fingerprint.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   747
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   748
    If an image with the specified fingerprint is found, it is returned.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   749
    Otherwise None is returned.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   750
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   751
    Existing images for the specified name that don't have the specified
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   752
    fingerprint or are missing required metadata or deleted.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   753
    """
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   754
    # Find existing AMIs with this name and delete the ones that are invalid.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   755
    # Store a reference to a good image so it can be returned one the
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   756
    # image state is reconciled.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   757
    images = ec2resource.images.filter(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   758
        Filters=[{'Name': 'name', 'Values': [name]}]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   759
    )
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   760
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   761
    existing_image = None
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   762
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   763
    for image in images:
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   764
        if image.tags is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   765
            print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   766
                'image %s for %s lacks required tags; removing'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   767
                % (image.id, image.name)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   768
            )
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   769
            remove_ami(ec2resource, image)
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   770
        else:
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   771
            tags = {t['Key']: t['Value'] for t in image.tags}
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   772
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   773
            if tags.get('HGIMAGEFINGERPRINT') == fingerprint:
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   774
                existing_image = image
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   775
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   776
                print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   777
                    'image %s for %s has wrong fingerprint; removing'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   778
                    % (image.id, image.name)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   779
                )
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   780
                remove_ami(ec2resource, image)
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   781
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   782
    return existing_image
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   783
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   784
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   785
def create_ami_from_instance(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   786
    ec2client, instance, name, description, fingerprint
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   787
):
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   788
    """Create an AMI from a running instance.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   789
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   790
    Returns the ``ec2resource.Image`` representing the created AMI.
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   791
    """
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   792
    instance.stop()
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   793
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   794
    ec2client.get_waiter('instance_stopped').wait(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   795
        InstanceIds=[instance.id], WaiterConfig={'Delay': 5,}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   796
    )
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   797
    print('%s is stopped' % instance.id)
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   798
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   799
    image = instance.create_image(Name=name, Description=description,)
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   800
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   801
    image.create_tags(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   802
        Tags=[{'Key': 'HGIMAGEFINGERPRINT', 'Value': fingerprint,},]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   803
    )
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   804
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   805
    print('waiting for image %s' % image.id)
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   806
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   807
    ec2client.get_waiter('image_available').wait(ImageIds=[image.id],)
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   808
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   809
    print('image %s available as %s' % (image.id, image.name))
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   810
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   811
    return image
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   812
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
   813
43018
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
   814
def ensure_linux_dev_ami(c: AWSConnection, distro='debian10', prefix='hg-'):
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   815
    """Ensures a Linux development AMI is available and up-to-date.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   816
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   817
    Returns an ``ec2.Image`` of either an existing AMI or a newly-built one.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   818
    """
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   819
    ec2client = c.ec2client
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   820
    ec2resource = c.ec2resource
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   821
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   822
    name = '%s%s-%s' % (prefix, 'linux-dev', distro)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   823
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   824
    if distro == 'debian9':
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   825
        image = find_image(
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   826
            ec2resource,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   827
            DEBIAN_ACCOUNT_ID,
43017
6952d42f9158 automation: use latest AMIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43016
diff changeset
   828
            'debian-stretch-hvm-x86_64-gp2-2019-09-08-17994',
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   829
        )
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   830
        ssh_username = 'admin'
43018
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
   831
    elif distro == 'debian10':
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
   832
        image = find_image(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   833
            ec2resource, DEBIAN_ACCOUNT_ID_2, 'debian-10-amd64-20190909-10',
43018
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
   834
        )
d1d919f679f7 automation: support and use Debian Buster by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43017
diff changeset
   835
        ssh_username = 'admin'
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   836
    elif distro == 'ubuntu18.04':
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   837
        image = find_image(
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   838
            ec2resource,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   839
            UBUNTU_ACCOUNT_ID,
43017
6952d42f9158 automation: use latest AMIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43016
diff changeset
   840
            'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20190918',
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   841
        )
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   842
        ssh_username = 'ubuntu'
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   843
    elif distro == 'ubuntu19.04':
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   844
        image = find_image(
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   845
            ec2resource,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   846
            UBUNTU_ACCOUNT_ID,
43017
6952d42f9158 automation: use latest AMIs
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43016
diff changeset
   847
            'ubuntu/images/hvm-ssd/ubuntu-disco-19.04-amd64-server-20190918',
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   848
        )
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   849
        ssh_username = 'ubuntu'
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   850
    else:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   851
        raise ValueError('unsupported Linux distro: %s' % distro)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   852
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   853
    config = {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   854
        'BlockDeviceMappings': [
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   855
            {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   856
                'DeviceName': image.block_device_mappings[0]['DeviceName'],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   857
                'Ebs': {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   858
                    'DeleteOnTermination': True,
43016
92c8bae84e7a automation: increase size of Linux AMI build volume
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43013
diff changeset
   859
                    'VolumeSize': 10,
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   860
                    'VolumeType': 'gp2',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   861
                },
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   862
            },
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   863
        ],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   864
        'EbsOptimized': True,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   865
        'ImageId': image.id,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   866
        'InstanceInitiatedShutdownBehavior': 'stop',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   867
        # 8 VCPUs for compiling Python.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   868
        'InstanceType': 't3.2xlarge',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   869
        'KeyName': '%sautomation' % prefix,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   870
        'MaxCount': 1,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   871
        'MinCount': 1,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   872
        'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   873
    }
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   874
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   875
    requirements2_path = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   876
        pathlib.Path(__file__).parent.parent / 'linux-requirements-py2.txt'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   877
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   878
    requirements3_path = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   879
        pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.txt'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   880
    )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   881
    with requirements2_path.open('r', encoding='utf-8') as fh:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   882
        requirements2 = fh.read()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   883
    with requirements3_path.open('r', encoding='utf-8') as fh:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   884
        requirements3 = fh.read()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   885
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   886
    # Compute a deterministic fingerprint to determine whether image needs to
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   887
    # be regenerated.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   888
    fingerprint = resolve_fingerprint(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   889
        {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   890
            'instance_config': config,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   891
            'bootstrap_script': BOOTSTRAP_DEBIAN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   892
            'requirements_py2': requirements2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   893
            'requirements_py3': requirements3,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   894
        }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   895
    )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   896
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   897
    existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   898
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   899
    if existing_image:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   900
        return existing_image
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   901
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   902
    print('no suitable %s image found; creating one...' % name)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   903
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   904
    with temporary_ec2_instances(ec2resource, config) as instances:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   905
        wait_for_ip_addresses(instances)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   906
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   907
        instance = instances[0]
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   908
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   909
        client = wait_for_ssh(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   910
            instance.public_ip_address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   911
            22,
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   912
            username=ssh_username,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   913
            key_filename=str(c.key_pair_path_private('automation')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   914
        )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   915
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   916
        home = '/home/%s' % ssh_username
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   917
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   918
        with client:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   919
            print('connecting to SSH server')
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   920
            sftp = client.open_sftp()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   921
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   922
            print('uploading bootstrap files')
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   923
            with sftp.open('%s/bootstrap' % home, 'wb') as fh:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   924
                fh.write(BOOTSTRAP_DEBIAN)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   925
                fh.chmod(0o0700)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   926
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   927
            with sftp.open('%s/requirements-py2.txt' % home, 'wb') as fh:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   928
                fh.write(requirements2)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   929
                fh.chmod(0o0700)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   930
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   931
            with sftp.open('%s/requirements-py3.txt' % home, 'wb') as fh:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   932
                fh.write(requirements3)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   933
                fh.chmod(0o0700)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   934
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   935
            print('executing bootstrap')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   936
            chan, stdin, stdout = ssh_exec_command(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   937
                client, '%s/bootstrap' % home
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   938
            )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   939
            stdin.close()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   940
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   941
            for line in stdout:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   942
                print(line, end='')
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   943
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   944
            res = chan.recv_exit_status()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   945
            if res:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   946
                raise Exception('non-0 exit from bootstrap: %d' % res)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   947
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   948
            print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   949
                'bootstrap completed; stopping %s to create %s'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   950
                % (instance.id, name)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   951
            )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   952
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   953
        return create_ami_from_instance(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   954
            ec2client,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   955
            instance,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   956
            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   957
            'Mercurial Linux development environment',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   958
            fingerprint,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   959
        )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   960
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   961
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   962
@contextlib.contextmanager
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   963
def temporary_linux_dev_instances(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   964
    c: AWSConnection,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   965
    image,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   966
    instance_type,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   967
    prefix='hg-',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   968
    ensure_extra_volume=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
   969
):
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   970
    """Create temporary Linux development EC2 instances.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   971
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   972
    Context manager resolves to a list of ``ec2.Instance`` that were created
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   973
    and are running.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   974
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   975
    ``ensure_extra_volume`` can be set to ``True`` to require that instances
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   976
    have a 2nd storage volume available other than the primary AMI volume.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   977
    For instance types with instance storage, this does nothing special.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   978
    But for instance types without instance storage, an additional EBS volume
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   979
    will be added to the instance.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   980
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   981
    Instances have an ``ssh_client`` attribute containing a paramiko SSHClient
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   982
    instance bound to the instance.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   983
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   984
    Instances have an ``ssh_private_key_path`` attributing containing the
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   985
    str path to the SSH private key to connect to the instance.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   986
    """
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   987
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   988
    block_device_mappings = [
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   989
        {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   990
            'DeviceName': image.block_device_mappings[0]['DeviceName'],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   991
            'Ebs': {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   992
                'DeleteOnTermination': True,
42697
3e3fb15bfeea automation: increase root volume size on Linux
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42648
diff changeset
   993
                'VolumeSize': 12,
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   994
                'VolumeType': 'gp2',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   995
            },
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   996
        }
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   997
    ]
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   998
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
   999
    # This is not an exhaustive list of instance types having instance storage.
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1000
    # But
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1001
    if ensure_extra_volume and not instance_type.startswith(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1002
        tuple(INSTANCE_TYPES_WITH_STORAGE)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1003
    ):
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1004
        main_device = block_device_mappings[0]['DeviceName']
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1005
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1006
        if main_device == 'xvda':
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1007
            second_device = 'xvdb'
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1008
        elif main_device == '/dev/sda1':
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1009
            second_device = '/dev/sdb'
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1010
        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1011
            raise ValueError(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1012
                'unhandled primary EBS device name: %s' % main_device
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1013
            )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1014
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1015
        block_device_mappings.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1016
            {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1017
                'DeviceName': second_device,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1018
                'Ebs': {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1019
                    'DeleteOnTermination': True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1020
                    'VolumeSize': 8,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1021
                    'VolumeType': 'gp2',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1022
                },
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1023
            }
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1024
        )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1025
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1026
    config = {
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1027
        'BlockDeviceMappings': block_device_mappings,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1028
        'EbsOptimized': True,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1029
        'ImageId': image.id,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1030
        'InstanceInitiatedShutdownBehavior': 'terminate',
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1031
        'InstanceType': instance_type,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1032
        'KeyName': '%sautomation' % prefix,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1033
        'MaxCount': 1,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1034
        'MinCount': 1,
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1035
        'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1036
    }
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1037
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1038
    with temporary_ec2_instances(c.ec2resource, config) as instances:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1039
        wait_for_ip_addresses(instances)
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1040
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1041
        ssh_private_key_path = str(c.key_pair_path_private('automation'))
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1042
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1043
        for instance in instances:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1044
            client = wait_for_ssh(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1045
                instance.public_ip_address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1046
                22,
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1047
                username='hg',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1048
                key_filename=ssh_private_key_path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1049
            )
42285
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1050
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1051
            instance.ssh_client = client
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1052
            instance.ssh_private_key_path = ssh_private_key_path
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1053
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1054
        try:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1055
            yield instances
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1056
        finally:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1057
            for instance in instances:
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1058
                instance.ssh_client.close()
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1059
65b3ef162b39 automation: initial support for running Linux tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42284
diff changeset
  1060
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1061
def ensure_windows_dev_ami(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1062
    c: AWSConnection, prefix='hg-', base_image_name=WINDOWS_BASE_IMAGE_NAME
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1063
):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1064
    """Ensure Windows Development AMI is available and up-to-date.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1065
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1066
    If necessary, a modern AMI will be built by starting a temporary EC2
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1067
    instance and bootstrapping it.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1068
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1069
    Obsolete AMIs will be deleted so there is only a single AMI having the
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1070
    desired name.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1071
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1072
    Returns an ``ec2.Image`` of either an existing AMI or a newly-built
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1073
    one.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1074
    """
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1075
    ec2client = c.ec2client
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1076
    ec2resource = c.ec2resource
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1077
    ssmclient = c.session.client('ssm')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1078
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1079
    name = '%s%s' % (prefix, 'windows-dev')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1080
42648
d80edcb0b30c automation: make Windows base image name configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42647
diff changeset
  1081
    image = find_image(ec2resource, AMAZON_ACCOUNT_ID, base_image_name)
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
  1082
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1083
    config = {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1084
        'BlockDeviceMappings': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1085
            {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1086
                'DeviceName': '/dev/sda1',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1087
                'Ebs': {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1088
                    'DeleteOnTermination': True,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1089
                    'VolumeSize': 32,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1090
                    'VolumeType': 'gp2',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1091
                },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1092
            }
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1093
        ],
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
  1094
        'ImageId': image.id,
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1095
        'InstanceInitiatedShutdownBehavior': 'stop',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1096
        'InstanceType': 't3.medium',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1097
        'KeyName': '%sautomation' % prefix,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1098
        'MaxCount': 1,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1099
        'MinCount': 1,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1100
        'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1101
    }
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1102
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1103
    commands = [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1104
        # Need to start the service so sshd_config is generated.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1105
        'Start-Service sshd',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1106
        'Write-Output "modifying sshd_config"',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1107
        r'$content = Get-Content C:\ProgramData\ssh\sshd_config',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1108
        '$content = $content -replace "Match Group administrators","" -replace "AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys",""',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1109
        r'$content | Set-Content C:\ProgramData\ssh\sshd_config',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1110
        'Import-Module OpenSSHUtils',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1111
        r'Repair-SshdConfigPermission C:\ProgramData\ssh\sshd_config -Confirm:$false',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1112
        'Restart-Service sshd',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1113
        'Write-Output "installing OpenSSL client"',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1114
        'Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1115
        'Set-Service -Name sshd -StartupType "Automatic"',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1116
        'Write-Output "OpenSSH server running"',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1117
    ]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1118
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1119
    with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1120
        commands.extend(l.rstrip() for l in fh)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1121
43234
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1122
    # Schedule run of EC2Launch on next boot. This ensures that UserData
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1123
    # is executed.
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1124
    # We disable setComputerName because it forces a reboot.
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1125
    # We set an explicit admin password because this causes UserData to run
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1126
    # as Administrator instead of System.
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1127
    commands.extend(
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1128
        [
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1129
            r'''Set-Content -Path C:\ProgramData\Amazon\EC2-Windows\Launch\Config\LaunchConfig.json '''
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1130
            r'''-Value '{"setComputerName": false, "setWallpaper": true, "addDnsSuffixList": true, '''
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1131
            r'''"extendBootVolumeSize": true, "handleUserData": true, '''
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1132
            r'''"adminPasswordType": "Specify", "adminPassword": "%s"}' '''
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1133
            % c.automation.default_password(),
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1134
            r'C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 '
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1135
            r'–Schedule',
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1136
        ]
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1137
    )
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1138
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1139
    # Disable Windows Defender when bootstrapping because it just slows
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1140
    # things down.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1141
    commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1142
    commands.append('Set-MpPreference -DisableRealtimeMonitoring $false')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1143
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1144
    # Compute a deterministic fingerprint to determine whether image needs
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1145
    # to be regenerated.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1146
    fingerprint = resolve_fingerprint(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1147
        {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1148
            'instance_config': config,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1149
            'user_data': WINDOWS_USER_DATA,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1150
            'initial_bootstrap': WINDOWS_BOOTSTRAP_POWERSHELL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1151
            'bootstrap_commands': commands,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1152
            'base_image_name': base_image_name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1153
        }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1154
    )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1155
42284
195dcc10b3d7 automation: move image operations to own functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42280
diff changeset
  1156
    existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1157
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1158
    if existing_image:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1159
        return existing_image
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1160
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1161
    print('no suitable Windows development image found; creating one...')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1162
43234
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1163
    with create_temp_windows_ec2_instances(
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1164
        c, config, bootstrap=True
c09e8ac3f61f automation: schedule an EC2Launch run on next boot
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
  1165
    ) as instances:
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1166
        assert len(instances) == 1
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1167
        instance = instances[0]
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1168
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1169
        wait_for_ssm(ssmclient, [instance])
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1170
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1171
        # On first boot, install various Windows updates.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1172
        # We would ideally use PowerShell Remoting for this. However, there are
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1173
        # trust issues that make it difficult to invoke Windows Update
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1174
        # remotely. So we use SSM, which has a mechanism for running Windows
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1175
        # Update.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1176
        print('installing Windows features...')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1177
        run_ssm_command(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1178
            ssmclient,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1179
            [instance],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1180
            'AWS-RunPowerShellScript',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1181
            {'commands': WINDOWS_BOOTSTRAP_POWERSHELL.split('\n'),},
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1182
        )
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1183
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1184
        # Reboot so all updates are fully applied.
42280
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1185
        #
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1186
        # We don't use instance.reboot() here because it is asynchronous and
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1187
        # we don't know when exactly the instance has rebooted. It could take
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1188
        # a while to stop and we may start trying to interact with the instance
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1189
        # before it has rebooted.
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1190
        print('rebooting instance %s' % instance.id)
42280
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1191
        instance.stop()
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1192
        ec2client.get_waiter('instance_stopped').wait(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1193
            InstanceIds=[instance.id], WaiterConfig={'Delay': 5,}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1194
        )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1195
42280
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1196
        instance.start()
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1197
        wait_for_ip_addresses([instance])
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1198
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1199
        # There is a race condition here between the User Data PS script running
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1200
        # and us connecting to WinRM. This can manifest as
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1201
        # "AuthorizationManager check failed" failures during run_powershell().
e570106beda1 automation: shore up rebooting behavior
Gregory Szorc <gregory.szorc@gmail.com>
parents: 42278
diff changeset
  1202
        # TODO figure out a workaround.
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1203
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1204
        print('waiting for Windows Remote Management to come back...')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1205
        client = wait_for_winrm(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1206
            instance.public_ip_address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1207
            'Administrator',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1208
            c.automation.default_password(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1209
        )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1210
        print('established WinRM connection to %s' % instance.id)
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1211
        instance.winrm_client = client
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1212
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1213
        print('bootstrapping instance...')
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1214
        run_powershell(instance.winrm_client, '\n'.join(commands))
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1215
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1216
        print('bootstrap completed; stopping %s to create image' % instance.id)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1217
        return create_ami_from_instance(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1218
            ec2client,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1219
            instance,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1220
            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1221
            'Mercurial Windows development environment',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1222
            fingerprint,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1223
        )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1224
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1225
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1226
@contextlib.contextmanager
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1227
def temporary_windows_dev_instances(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1228
    c: AWSConnection,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1229
    image,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1230
    instance_type,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1231
    prefix='hg-',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1232
    disable_antivirus=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1233
):
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1234
    """Create a temporary Windows development EC2 instance.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1235
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1236
    Context manager resolves to the list of ``EC2.Instance`` that were created.
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1237
    """
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1238
    config = {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1239
        'BlockDeviceMappings': [
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1240
            {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1241
                'DeviceName': '/dev/sda1',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1242
                'Ebs': {
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1243
                    'DeleteOnTermination': True,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1244
                    'VolumeSize': 32,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1245
                    'VolumeType': 'gp2',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1246
                },
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1247
            }
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1248
        ],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1249
        'ImageId': image.id,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1250
        'InstanceInitiatedShutdownBehavior': 'stop',
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1251
        'InstanceType': instance_type,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1252
        'KeyName': '%sautomation' % prefix,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1253
        'MaxCount': 1,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1254
        'MinCount': 1,
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1255
        'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1256
    }
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1257
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1258
    with create_temp_windows_ec2_instances(c, config) as instances:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1259
        if disable_antivirus:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1260
            for instance in instances:
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1261
                run_powershell(
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1262
                    instance.winrm_client,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1263
                    'Set-MpPreference -DisableRealtimeMonitoring $true',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43018
diff changeset
  1264
                )
42024
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1265
b05a3e28cf24 automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
  1266
        yield instances