Exemple #1
0
def _prod_deployment_helper(config_dir,
                            package_zip_paths,
                            deploy_go=True,
                            deploy_appengine=True):
  """Helper for production deployment."""
  config = local_config.Config()
  deployment_bucket = config.get('project.deployment.bucket')

  gae_config = config.sub_config(local_config.GAE_CONFIG_PATH)
  gae_deployment = gae_config.sub_config('deployment')
  project = gae_config.get('application_id')

  print('Deploying %s to prod.' % project)
  yaml_paths = gae_deployment.get_absolute_path('prod')
  yaml_paths = appengine.filter_yaml_paths(yaml_paths, deploy_go)

  if deploy_appengine:
    _update_pubsub_queues(project)
    _update_alerts(project)
    _update_bigquery(project)

  _deploy_app_prod(
      project,
      deployment_bucket,
      yaml_paths,
      package_zip_paths,
      deploy_appengine=deploy_appengine)

  if deploy_appengine:
    common.execute('python butler.py run setup --config-dir {config_dir} '
                   '--non-dry-run'.format(config_dir=config_dir))
  print('Production deployment finished.')
Exemple #2
0
def execute(_):
  """Lint changed code."""
  pythonpath = os.getenv('PYTHONPATH', '')
  os.environ['PYTHONPATH'] = appengine.find_sdk_path() + ':' + pythonpath

  if 'GOOGLE_CLOUDBUILD' in os.environ:
    # Explicitly compare against master if we're running on the CI
    _, output = common.execute('git diff --name-only master FETCH_HEAD')
  elif 'TRAVIS_BRANCH' in os.environ:
    _, output = common.execute(
        'git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD)')
  else:
    _, output = common.execute('git diff --name-only FETCH_HEAD')

  py_changed_file_paths = [
      f for f in output.splitlines() if f.endswith('.py') and
      # Exclude auto-generated files.
      not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
  ]
  go_changed_file_paths = [f for f in output.splitlines() if f.endswith('.go')]

  for file_path in py_changed_file_paths:
    if os.path.exists(file_path):
      common.execute('pylint ' + file_path)
      common.execute('yapf -d ' + file_path)

  golint_path = os.path.join('local', 'bin', 'golint')
  for file_path in go_changed_file_paths:
    if os.path.exists(file_path):
      common.execute(golint_path + ' ' + file_path)

      _, output = common.execute('gofmt -d ' + file_path)
      if output.strip():
        sys.exit(1)
Exemple #3
0
def _delete_old_versions(project, service, delete_window):
  """Delete old versions."""

  def _to_datetime(entry):
    """Parse datetime entry."""
    return datetime.datetime(entry['year'], entry['month'], entry['day'],
                             entry['hour'], entry['minute'], entry['second'])

  _, versions = common.execute('gcloud app versions list --format=json '
                               '--project=%s --service=%s' % (project, service))
  versions = [
      Version(version['id'], _to_datetime(version['last_deployed_time']),
              version['traffic_split']) for version in json.loads(versions)
  ]

  versions.sort(key=lambda v: v.deploy_time)
  assert versions[-1].traffic_split == 1.0

  to_delete = _versions_to_delete(versions, delete_window)
  if not to_delete:
    return

  versions = ' '.join(version.id for version in to_delete)
  common.execute('gcloud app versions delete --quiet '
                 '--project=%s --service=%s %s' % (project, service, versions))
Exemple #4
0
def execute(_):
  """Lint changed code."""
  pythonpath = os.getenv('PYTHONPATH', '')
  os.environ['PYTHONPATH'] = appengine.find_sdk_path() + ':' + pythonpath

  if 'GOOGLE_CLOUDBUILD' in os.environ:
    # Explicitly compare against master if we're running on the CI
    _, output = common.execute('git diff --name-only master FETCH_HEAD')
  elif 'TRAVIS_BRANCH' in os.environ:
    _, output = common.execute(
        'git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD)')
  else:
    _, output = common.execute('git diff --name-only FETCH_HEAD')

  file_paths = [f for f in output.splitlines() if os.path.exists(f)]
  py_changed_file_paths = [
      f for f in file_paths if f.endswith('.py') and
      # Exclude auto-generated files.
      not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
  ]
  go_changed_file_paths = [f for f in file_paths if f.endswith('.go')]
  yaml_changed_file_paths = [f for f in file_paths if f.endswith('.yaml')]

  for file_path in py_changed_file_paths:
    _execute_command_and_track_error('pylint ' + file_path)
    _execute_command_and_track_error('yapf -d ' + file_path)

    futurize_excludes = ' '.join(
        ['-x ' + exception for exception in _FUTURIZE_EXCEPTIONS])
    futurize_command = 'futurize -0 {excludes} {file_path}'.format(
        excludes=futurize_excludes, file_path=file_path)
    futurize_output = _execute_command_and_track_error(futurize_command)
    if ('No changes to ' not in futurize_output and
        'No files need to be modified' not in futurize_output):
      # Futurize doesn't modify its return code depending on the result.
      _error('Python 3 compatibility error introduced.')

    py_import_order(file_path)
    py_test_init_check(file_path)

  golint_path = os.path.join('local', 'bin', 'golint')
  for file_path in go_changed_file_paths:
    if not os.path.basename(file_path) in _GOLINT_EXCEPTIONS:
      _execute_command_and_track_error(golint_path + ' ' + file_path)

    output = _execute_command_and_track_error('gofmt -d ' + file_path)
    if output.strip():
      _error()

  for file_path in yaml_changed_file_paths:
    yaml_validate(file_path)

  for file_path in file_paths:
    license_validate(file_path)

  if _error_occurred:
    print('Linting failed, see errors above.')
    sys.exit(1)
  else:
    print('Linting passed.')
Exemple #5
0
def execute(_):
    """Lint changed code."""
    pythonpath = os.getenv("PYTHONPATH", "")
    os.environ["PYTHONPATH"] = appengine.find_sdk_path() + ":" + pythonpath

    if "GOOGLE_CLOUDBUILD" in os.environ:
        # Explicitly compare against master if we're running on the CI
        _, output = common.execute("git diff --name-only master FETCH_HEAD")
    elif "TRAVIS_BRANCH" in os.environ:
        _, output = common.execute(
            "git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD)")
    else:
        _, output = common.execute("git diff --name-only FETCH_HEAD")

    file_paths = [f for f in output.splitlines() if os.path.exists(f)]
    py_changed_file_paths = [
        f for f in file_paths
        if f.endswith(".py") and not is_auto_generated_file(f)
    ]
    go_changed_file_paths = [f for f in file_paths if f.endswith(".go")]
    yaml_changed_file_paths = [f for f in file_paths if f.endswith(".yaml")]

    for file_path in py_changed_file_paths:
        _execute_command_and_track_error("pylint " + file_path)
        _execute_command_and_track_error("yapf -d " + file_path)

        futurize_excludes = " ".join("-x " + exception
                                     for exception in _FUTURIZE_EXCEPTIONS)
        futurize_command = "futurize -0 {excludes} {file_path}".format(
            excludes=futurize_excludes, file_path=file_path)
        futurize_output = _execute_command_and_track_error(futurize_command)
        if ("No changes to " not in futurize_output
                and "No files need to be modified" not in futurize_output):
            # Futurize doesn't modify its return code depending on the result.
            _error("Python 3 compatibility error introduced.")

        py_import_order(file_path)
        py_test_init_check(file_path)

    golint_path = os.path.join("local", "bin", "golint")
    for file_path in go_changed_file_paths:
        if not os.path.basename(file_path) in _GOLINT_EXCEPTIONS:
            _execute_command_and_track_error(golint_path + " " + file_path)

        output = _execute_command_and_track_error("gofmt -d " + file_path)
        if output.strip():
            _error()

    for file_path in yaml_changed_file_paths:
        yaml_validate(file_path)

    for file_path in file_paths:
        license_validate(file_path)

    if _error_occurred:
        print("Linting failed, see errors above.")
        sys.exit(1)
    else:
        print("Linting passed.")
Exemple #6
0
def is_diff_origin_master():
  """Check if the current state is different from origin/master."""
  common.execute('git fetch')
  remote_sha = get_remote_sha()
  _, local_sha = common.execute('git rev-parse HEAD')
  _, diff_output = common.execute('git diff origin/master --stat')

  return diff_output.strip() or remote_sha.strip() != local_sha.strip()
Exemple #7
0
 def bootstrap():
     # Wait for the server to run.
     time.sleep(10)
     print('Bootstrapping datastore...')
     common.execute(
         ('python butler.py run setup '
          '--non-dry-run --local --config-dir={config_dir}').format(
              config_dir=constants.TEST_CONFIG_DIR),
         exit_on_error=False)
Exemple #8
0
def _deploy_manifest(bucket_name, manifest_path):
    """Deploy source manifest to GCS."""
    if sys.version_info.major == 3:
        manifest_suffix = '.3'
    else:
        manifest_suffix = ''

    common.execute('gsutil cp -a public-read %s '
                   'gs://%s/clusterfuzz-source.manifest%s' %
                   (manifest_path, bucket_name, manifest_suffix))
Exemple #9
0
def execute(_):
    """Lint changed code."""
    if "GOOGLE_CLOUDBUILD" in os.environ:
        # Explicitly compare against master if we're running on the CI
        _, output = common.execute('git diff --name-only master FETCH_HEAD')
    else:
        _, output = common.execute('git diff --name-only FETCH_HEAD')

    py_changed_file_paths = [
        f for f in output.splitlines() if f.endswith('.py') and
        # Exclude auto-generated files.
        not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
    ]
    go_changed_file_paths = [
        f for f in output.splitlines() if f.endswith('.go')
    ]

    for file_path in py_changed_file_paths:
        if os.path.exists(file_path):
            common.execute('pylint ' + file_path)
            common.execute('yapf -d ' + file_path)

    golint_path = os.path.join('local', 'bin', 'golint')
    for file_path in go_changed_file_paths:
        if os.path.exists(file_path):
            common.execute(golint_path + ' ' + file_path)

            _, output = common.execute('gofmt -d ' + file_path)
            if output.strip():
                sys.exit(1)
Exemple #10
0
def execute(_):
    """Lint changed code."""
    pythonpath = os.getenv('PYTHONPATH', '')
    os.environ['PYTHONPATH'] = appengine.find_sdk_path() + ':' + pythonpath

    if 'GOOGLE_CLOUDBUILD' in os.environ:
        # Explicitly compare against master if we're running on the CI
        _, output = common.execute('git diff --name-only master FETCH_HEAD')
    else:
        _, output = common.execute('git diff --name-only FETCH_HEAD')

    file_paths = [
        f.decode('utf-8') for f in output.splitlines() if os.path.exists(f)
    ]
    py_changed_file_paths = [
        f for f in file_paths
        if f.endswith('.py') and not is_auto_generated_file(f)
    ]
    go_changed_file_paths = [f for f in file_paths if f.endswith('.go')]
    yaml_changed_file_paths = [f for f in file_paths if f.endswith('.yaml')]

    for file_path in py_changed_file_paths:
        line_length_override = ''
        if '_test.py' in file_path:
            line_length_override = '--max-line-length=240'

        _execute_command_and_track_error(
            f'pylint {line_length_override} {file_path}')
        _execute_command_and_track_error(f'yapf -d {file_path}')
        _execute_command_and_track_error(
            f'{formatter.ISORT_CMD} -c {file_path}')

        py_test_init_check(file_path)

    golint_path = os.path.join('local', 'bin', 'golint')
    for file_path in go_changed_file_paths:
        if not os.path.basename(file_path) in _GOLINT_EXCEPTIONS:
            _execute_command_and_track_error(golint_path + ' ' + file_path)

        output = _execute_command_and_track_error('gofmt -d ' + file_path)
        if output.strip():
            _error()

    for file_path in yaml_changed_file_paths:
        yaml_validate(file_path)

    for file_path in file_paths:
        license_validate(file_path)

    if _error_occurred:
        print('Linting failed, see errors above.')
        sys.exit(1)
    else:
        print('Linting passed.')
Exemple #11
0
def execute(_):
    """Lint changed code."""
    _, output = common.execute('git diff --name-only FETCH_HEAD')

    py_changed_file_paths = [
        f for f in output.splitlines() if f.endswith('.py') and
        # Exclude auto-generated files.
        not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
    ]
    go_changed_file_paths = [
        f for f in output.splitlines() if f.endswith('.go')
    ]

    for file_path in py_changed_file_paths:
        if os.path.exists(file_path):
            common.execute('pylint ' + file_path)
            common.execute('yapf -d ' + file_path)

    golint_path = os.path.join('local', 'bin', 'golint')
    for file_path in go_changed_file_paths:
        if os.path.exists(file_path):
            common.execute(golint_path + ' ' + file_path)

            _, output = common.execute('gofmt -d ' + file_path)
            if output.strip():
                sys.exit(1)
Exemple #12
0
def execute(_):
  """Lint changed code."""
  pythonpath = os.getenv('PYTHONPATH', '')
  os.environ['PYTHONPATH'] = appengine.find_sdk_path() + ':' + pythonpath

  if 'GOOGLE_CLOUDBUILD' in os.environ:
    # Explicitly compare against master if we're running on the CI
    _, output = common.execute('git diff --name-only master FETCH_HEAD')
  elif 'TRAVIS_BRANCH' in os.environ:
    _, output = common.execute(
        'git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD)')
  else:
    _, output = common.execute('git diff --name-only FETCH_HEAD')

  file_paths = [f for f in output.splitlines() if os.path.exists(f)]
  py_changed_file_paths = [
      f for f in file_paths if f.endswith('.py') and
      # Exclude auto-generated files.
      not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
  ]
  go_changed_file_paths = [f for f in file_paths if f.endswith('.go')]
  yaml_changed_file_paths = [f for f in file_paths if f.endswith('.yaml')]

  for file_path in py_changed_file_paths:
    _execute_command_and_track_error('pylint ' + file_path)
    _execute_command_and_track_error('yapf -d ' + file_path)
    py_import_order(file_path)
    py_test_init_check(file_path)

  golint_path = os.path.join('local', 'bin', 'golint')
  for file_path in go_changed_file_paths:
    if not os.path.basename(file_path) in _GOLINT_EXCEPTIONS:
      _execute_command_and_track_error(golint_path + ' ' + file_path)

    output = _execute_command_and_track_error('gofmt -d ' + file_path)
    if output.strip():
      _error()

  for file_path in yaml_changed_file_paths:
    yaml_validate(file_path)

  for file_path in file_paths:
    license_validate(file_path)

  if _error_occurred:
    print('Linting failed, see errors above.')
    sys.exit(1)
  else:
    print('Linting passed.')
Exemple #13
0
def execute(_):
    """Format changed code."""
    _, output = common.execute('git diff --name-only FETCH_HEAD')

    file_paths = [f for f in output.splitlines() if os.path.exists(f)]
    py_changed_file_paths = [
        f for f in file_paths if f.endswith('.py') and
        # Exclude auto-generated files.
        not f.endswith('_pb2.py') and not f.endswith('_pb2_grpc.py')
    ]
    go_changed_file_paths = [f for f in file_paths if f.endswith('.go')]
    for file_path in py_changed_file_paths:
        common.execute('yapf -i ' + file_path)

    for file_path in go_changed_file_paths:
        common.execute('gofmt -w ' + file_path)
Exemple #14
0
def symlink_dirs():
  """Symlink folders for use on appengine."""
  symlink_config_dir()

  common.symlink(
      src=os.path.join('src', 'protos'),
      target=os.path.join(SRC_DIR_PY, 'protos'))
  common.symlink(
      src=os.path.join('src', 'python'),
      target=os.path.join(SRC_DIR_PY, 'python'))
  # While importing third party modules, we may call pkg_resources.
  # pkg_resources normalizes paths by calling os.path.realpath on them, which is
  # incompatible with the App Engine sandbox since the resulting path will no
  # longer be under appengine/.
  common.copy_dir(
      src=os.path.join('src', 'third_party'),
      target=os.path.join(SRC_DIR_PY, 'third_party'))

  # Remove existing local_gcs symlink (if any). This is important, as otherwise
  # we will try deploying the directory in production. This is only needed for
  # local development in run_server.
  local_gcs_symlink_path = os.path.join(SRC_DIR_PY, 'local_gcs')
  if os.path.exists(local_gcs_symlink_path):
    os.remove(local_gcs_symlink_path)

  _, output = common.execute('bazel run //local:create_gopath', cwd='src')
  os.environ['GOPATH'] = output.splitlines()[-1]
Exemple #15
0
def _deploy_appengine(project, yamls, stop_previous_version, version=None):
    """Deploy to appengine using `yamls`."""
    stop_previous_version_arg = ("--stop-previous-version"
                                 if stop_previous_version else
                                 "--no-stop-previous-version")

    version_arg = "--version=" + version if version else ""

    for retry_num in range(DEPLOY_RETRIES + 1):
        return_code, _ = common.execute(
            "gcloud app deploy %s --quiet "
            "--project=%s %s %s" %
            (stop_previous_version_arg, project, version_arg, " ".join(yamls)),
            exit_on_error=False,
        )

        if return_code == 0:
            break

        if retry_num == DEPLOY_RETRIES:
            print("Failed to deploy after %d retries." % DEPLOY_RETRIES)
            sys.exit(return_code)

        print("gcloud deployment failed, retrying...")
        time.sleep(RETRY_WAIT_SECONDS)
Exemple #16
0
def _execute_command_and_track_error(command):
    """Executes command, tracks error state."""
    returncode, output = common.execute(command, exit_on_error=False)
    if returncode != 0:
        _error()

    return output.decode('utf-8')
Exemple #17
0
def _update_redis(project):
  """Update redis instance."""
  _update_deployment_manager(project, 'redis',
                             os.path.join('redis', 'instance.yaml'))

  region = appengine.region(project)
  return_code, _ = common.execute(
      'gcloud compute networks vpc-access connectors describe '
      'connector --region={region} '
      '--project={project}'.format(project=project, region=region),
      exit_on_error=False)

  if return_code:
    # Does not exist.
    common.execute('gcloud compute networks vpc-access connectors create '
                   'connector --network=default --region={region} '
                   '--range=10.8.0.0/28 '
                   '--project={project}'.format(project=project, region=region))
Exemple #18
0
def region(project):
    """Get the App Engine region."""
    return_code, location = common.execute(
        'gcloud app describe --project={project} '
        '--format="value(locationId)"'.format(project=project))
    if return_code:
        raise RuntimeError('Could not get App Engine region')

    return region_from_location(location.strip().decode('utf-8'))
Exemple #19
0
def execute(_):
  """Run integration tests."""
  if sys.version_info.major == 2:
    print('Skipping integration_tests on Python 2.')
    return

  command = 'run_server'
  indicator = b'Booting worker'

  try:
    lines = []
    server = common.execute_async(
        'python -u butler.py {} --skip-install-deps'.format(command))
    test_utils.wait_for_emulator_ready(
        server,
        command,
        indicator,
        timeout=RUN_SERVER_TIMEOUT,
        output_lines=lines)

    # Sleep a small amount of time to ensure the server is definitely ready.
    time.sleep(1)

    # Call setup ourselves instead of passing --bootstrap since we have no idea
    # when that finishes.
    # TODO(ochang): Make bootstrap a separate butler command and just call that.
    common.execute(
        ('python butler.py run setup '
         '--non-dry-run --local --config-dir={config_dir}'
        ).format(config_dir=constants.TEST_CONFIG_DIR),
        exit_on_error=False)

    request = urllib.request.urlopen('http://' + constants.DEV_APPSERVER_HOST)
    request.read()  # Raises exception on error
  except Exception:
    print('Error occurred:')
    print(b''.join(lines))
    raise
  finally:
    server.terminate()

  # TODO(ochang): Test that bot runs, and do a basic fuzzing session to ensure
  # things work end to end.
  print('All end-to-end integration tests passed.')
Exemple #20
0
def _get_redis_ip(project):
    """Get the redis IP address."""
    region = appengine.region(project)
    return_code, ip = common.execute(
        'gcloud redis instances describe redis-instance '
        '--project={project} --region={region} '
        '--format="value(host)"'.format(project=project, region=region))

    if return_code:
        raise RuntimeError('Failed to get redis IP.')

    return ip.decode('utf-8').strip()
Exemple #21
0
def _is_nodejs_up_to_date():
    """Check if node is of version MINIMUM_NODEJS_VERSION."""
    return_code, output = common.execute('node -v')

    if return_code != 0:
        return False

    m = re.match(r'v([0-9]+)\..+', output.strip())

    if not m:
        return False

    major_version = int(m.group(1))
    return major_version >= MIN_SUPPORTED_NODEJS_VERSION
Exemple #22
0
def execute(args):
  """Build and run all tests under src/go."""
  go_directory = os.path.join('src', 'go')

  common.execute('bazel build //...', cwd=go_directory)
  if args.verbose or args.unsuppress_output:
    test_output_arg = '--test_output=all'
  else:
    test_output_arg = '--test_output=errors'

  common.execute(
      'bazel test --sandbox_writable_path={home} '  # Necessary for gcloud.
      '{test_output_arg} '
      '--test_env=CONFIG_DIR_OVERRIDE={config_dir_override} '
      '--test_env=ROOT_DIR={root_dir} '
      '--test_env=INTEGRATION={integration} '
      '--test_env=CLUSTERFUZZ_MUTABLE_TEST_BUCKET={test_bucket} //...'.format(
          home=os.getenv('HOME'),
          test_output_arg=test_output_arg,
          config_dir_override=os.path.abspath(os.path.join('configs', 'test')),
          root_dir=os.getenv('ROOT_DIR'),
          integration=os.getenv('INTEGRATION', '0'),
          test_bucket=common.test_bucket_for_user()),
      cwd=go_directory)
Exemple #23
0
def _delete_old_versions(project, service, delete_window):
    """Delete old versions."""
    def _to_datetime(entry):
        """Parse datetime entry."""
        return datetime.datetime(
            entry["year"],
            entry["month"],
            entry["day"],
            entry["hour"],
            entry["minute"],
            entry["second"],
        )

    _, versions = common.execute("gcloud app versions list --format=json "
                                 "--project=%s --service=%s" %
                                 (project, service))
    versions = [
        Version(
            version["id"],
            _to_datetime(version["last_deployed_time"]),
            version["traffic_split"],
        ) for version in json.loads(versions)
    ]

    versions.sort(key=lambda v: v.deploy_time)
    if versions[-1].traffic_split != 1.0:
        raise AssertionError

    to_delete = _versions_to_delete(versions, delete_window)
    if not to_delete:
        return

    versions = " ".join(version.id for version in to_delete)
    common.execute("gcloud app versions delete --quiet "
                   "--project=%s --service=%s %s" %
                   (project, service, versions))
Exemple #24
0
def find_sdk_path():
  """Find the App Engine SDK path."""
  if common.get_platform() == 'windows':
    _, gcloud_path = common.execute('where gcloud.cmd', print_output=False)
  else:
    gcloud_path = spawn.find_executable('gcloud')

  if not gcloud_path:
    print('Please install the Google Cloud SDK and set up PATH to point to it.')
    sys.exit(1)

  cloud_sdk_path = os.path.dirname(
      os.path.dirname(os.path.realpath(gcloud_path)))
  appengine_sdk_path = os.path.join(cloud_sdk_path, 'platform',
                                    'google_appengine')
  if not os.path.exists(appengine_sdk_path):
    print('App Engine SDK not found. Please run local/install_deps.bash')
    sys.exit(1)

  return appengine_sdk_path
Exemple #25
0
def symlink_dirs():
    """Symlink folders for use on appengine."""
    symlink_config_dir()

    common.symlink(src=os.path.join('src', 'protos'),
                   target=os.path.join(SRC_DIR_PY, 'protos'))
    common.symlink(src=os.path.join('src', 'python'),
                   target=os.path.join(SRC_DIR_PY, 'python'))
    common.symlink(src=os.path.join('src', 'third_party'),
                   target=os.path.join(SRC_DIR_PY, 'third_party'))

    # Remove existing local_gcs symlink (if any). This is important, as otherwise
    # we will try deploying the directory in production. This is only needed for
    # local development in run_server.
    local_gcs_symlink_path = os.path.join(SRC_DIR_PY, 'local_gcs')
    if os.path.exists(local_gcs_symlink_path):
        os.remove(local_gcs_symlink_path)

    _, output = common.execute('bazel run //local:create_gopath', cwd='src')
    os.environ['GOPATH'] = output.splitlines()[-1]
Exemple #26
0
def _deploy_appengine(project, yamls, stop_previous_version, version=None):
  """Deploy to appengine using `yamls`."""
  stop_previous_version_arg = ('--stop-previous-version'
                               if stop_previous_version else
                               '--no-stop-previous-version')

  version_arg = '--version=' + version if version else ''

  for retry_num in range(DEPLOY_RETRIES + 1):
    return_code, _ = common.execute(
        'gcloud app deploy %s --quiet '
        '--project=%s %s %s' % (stop_previous_version_arg, project, version_arg,
                                ' '.join(yamls)),
        exit_on_error=False)

    if return_code == 0:
      break

    if retry_num == DEPLOY_RETRIES:
      print('Failed to deploy after %d retries.' % DEPLOY_RETRIES)
      sys.exit(return_code)

    print('gcloud deployment failed, retrying...')
    time.sleep(RETRY_WAIT_SECONDS)
Exemple #27
0
def get_remote_sha():
  """Get remote sha of origin/master."""
  _, remote_sha_line = common.execute('git ls-remote origin refs/heads/master')

  return re.split(r'\s+', remote_sha_line)[0]
Exemple #28
0
def _deploy_manifest(bucket_name, manifest_path):
  """Deploy source manifest to GCS."""
  common.execute(
      'gsutil cp -a public-read %s '
      'gs://%s/clusterfuzz-source.manifest' % (manifest_path, bucket_name))
Exemple #29
0
def _deploy_zip(bucket_name, zip_path):
  """Deploy zip to GCS."""
  common.execute('gsutil cp %s gs://%s/%s' % (zip_path, bucket_name,
                                              os.path.basename(zip_path)))
Exemple #30
0
def package(revision,
            target_zip_dir=constants.PACKAGE_TARGET_ZIP_DIRECTORY,
            target_manifest_path=constants.PACKAGE_TARGET_MANIFEST_PATH,
            platform_name=None):
    """Prepare clusterfuzz-source.zip."""
    is_ci = os.getenv('TEST_BOT_ENVIRONMENT')
    if not is_ci and common.is_git_dirty():
        print('Your branch is dirty. Please fix before packaging.')
        sys.exit(1)

    if not _is_nodejs_up_to_date():
        print(
            'You do not have nodejs, or your nodejs is not at least version 4.'
        )
        sys.exit(1)

    common.install_dependencies(platform_name=platform_name)

    # This needs to be done before packaging step to let src/appengine/config be
    # archived for bot.
    appengine.symlink_dirs()

    _, ls_files_output = common.execute('git -C . ls-files',
                                        print_output=False)
    file_paths = ls_files_output.splitlines()

    if not os.path.exists(target_zip_dir):
        os.makedirs(target_zip_dir)

    target_zip_name = constants.LEGACY_ZIP_NAME
    if platform_name:
        target_zip_name = platform_name + '.zip'

    target_zip_path = os.path.join(target_zip_dir, target_zip_name)
    _clear_zip(target_zip_path)

    output_file = zipfile.ZipFile(target_zip_path, 'w', zipfile.ZIP_DEFLATED)

    # Add files from git.
    for file_path in file_paths:
        if (file_path.startswith('config') or file_path.startswith('local')
                or file_path.startswith(os.path.join('src', 'appengine'))
                or file_path.startswith(os.path.join('src', 'local')) or
                file_path.startswith(os.path.join('src', 'python', 'tests'))):
            continue
        _add_to_zip(output_file, file_path)

    # These are project configuration yamls.
    for path in _get_files(os.path.join('src', 'appengine', 'config')):
        _add_to_zip(output_file, path)

    # These are third party dependencies.
    for path in _get_files(os.path.join('src', 'third_party')):
        _add_to_zip(output_file, path)

    output_file.close()

    with open(target_manifest_path, 'w') as f:
        f.write('%s\n' % revision)

    with zipfile.ZipFile(target_zip_path, 'a', zipfile.ZIP_DEFLATED) as f:
        _add_to_zip(f, target_manifest_path,
                    constants.PACKAGE_TARGET_MANIFEST_PATH)

    print('Revision: %s' % revision)

    print()
    print('%s is ready.' % target_zip_path)
    return target_zip_path