<reponame>WindQAQ/iree<gh_stars>1-10
#!/usr/bin/env python3

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Builds the specified Docker images and optionally pushes them to GCR.

Example usage:
  python3 build_tools/docker/build_and_update_gcr.py --image cmake
"""

import argparse
import functools
import os
import subprocess
import sys

IREE_GCR_URL = 'gcr.io/iree-oss/'
DOCKER_DIR = 'build_tools/docker/'

# Map from image names to images that they depend on.
IMAGES_TO_DEPENDENCIES = {
    'bazel': [],
    'bazel-bindings': ['bazel'],
    'bazel-tensorflow': ['bazel-bindings'],
    'bazel-nvidia': ['bazel-tensorflow'],
    'bazel-swiftshader': ['bazel-tensorflow'],
    'cmake': [],
    'cmake-android': ['cmake'],
    'cmake-nvidia': ['cmake'],
    'cmake-vulkan': ['cmake'],
    'cmake-swiftshader': ['cmake-vulkan'],
    'rbe-toolchain': [],
}

IMAGES_TO_DEPENDENT_IMAGES = {k: [] for k in IMAGES_TO_DEPENDENCIES.keys()}
for image, dependencies in IMAGES_TO_DEPENDENCIES.items():
  for dependency in dependencies:
    IMAGES_TO_DEPENDENT_IMAGES[dependency].append(image)

IMAGES_HELP = [f'`{name}`' for name in IMAGES_TO_DEPENDENCIES.keys()]
IMAGES_HELP = f'{", ".join(IMAGES_HELP)} or `all`'

RBE_MESSAGE = """
Remember to update the `rbe_default` digest in the `WORKSPACE` file to reflect
the new digest for the container.

Use `docker images --digests` to view the digest."""


def parse_arguments():
  """Parses command-line options."""
  parser = argparse.ArgumentParser(
      description="Build IREE's Docker images and optionally push them to GCR.")
  parser.add_argument(
      '--image',
      dest='images',
      type=str,
      required=True,
      action='append',
      help=f'Name of the image to build: {IMAGES_HELP}.')
  parser.add_argument(
      '--tag',
      type=str,
      default='latest',
      help='Tags for the images to build. Defaults to `latest` (which is good '
      'for testing changes in a PR). Use `prod` to update the images that the '
      'OSS CI uses.')
  parser.add_argument(
      '--push',
      action='store_true',
      help='Push the built images to GCR. Requires gcloud authorization.')

  args = parser.parse_args()
  for image in args.images:
    if image == 'all':
      args.images = IMAGES_TO_DEPENDENCIES.keys()
    elif image not in IMAGES_TO_DEPENDENCIES.keys():
      raise parser.error('Expected --image to be one of:\n'
                         f'  {IMAGES_HELP}\n'
                         f'but got `{image}`.')
  return args


def cmp_images_by_dependency(image1, image2):
  if image2 in IMAGES_TO_DEPENDENT_IMAGES[image1]:
    return -1
  if image1 in IMAGES_TO_DEPENDENT_IMAGES[image2]:
    return 1
  return (image1 > image2) - (image1 < image2)


def run_command(command):
  print(f'Running: {" ".join(command)}')
  process = subprocess.Popen(
      command,
      bufsize=1,
      stderr=subprocess.STDOUT,
      stdout=subprocess.PIPE,
      text=True)
  for line in process.stdout:
    print(line, end='')

  return process.poll()


def check_command(command):
  exit_code = run_command(command)
  if exit_code != 0:
    print(f'Command failed: {" ".join(command)}')
    sys.exit(exit_code)


if __name__ == '__main__':
  args = parse_arguments()

  # Ensure the user has the correct authorization if they try to push to GCR.
  if args.push:
    if run_command(['which', 'gcloud']) != 0:
      print('gcloud not found.'
            ' See https://cloud.google.com/sdk/install for installation.')
      sys.exit(1)
    check_command(['gcloud', 'auth', 'configure-docker'])

  # Check if any images depend on `args.images` and update them if they do.
  images_to_update_set = set()
  to_check = list(args.images)
  while to_check:
    image = to_check.pop()
    if image not in images_to_update_set:
      images_to_update_set.add(image)
      to_check.extend(IMAGES_TO_DEPENDENT_IMAGES[image])

  # Topo sort by image dependency
  images_to_update = sorted(
      images_to_update_set, key=functools.cmp_to_key(cmp_images_by_dependency))

  print(f'Also updating dependent images. Will update: {images_to_update}')
  for image in images_to_update:
    print(f'Updating image {image}')
    image_url = os.path.join(IREE_GCR_URL, f'{image}:{args.tag}')
    image_path = os.path.join(DOCKER_DIR, image.replace('-', '_'))
    check_command(['docker', 'build', '--tag', image_url, image_path])
    if args.push:
      check_command(['docker', 'push', image_url])

  if 'rbe-toolchain' in images_to_update:
    print(RBE_MESSAGE)

#!/usr/bin/env python3

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Builds the specified Docker images and optionally pushes them to GCR.

Example usage:
  python3 build_tools/docker/build_and_update_gcr.py --image cmake
"""

import argparse
import functools
import os
import subprocess
import sys

IREE_GCR_URL = 'gcr.io/iree-oss/'
DOCKER_DIR = 'build_tools/docker/'

# Map from image names to images that they depend on.
IMAGES_TO_DEPENDENCIES = {
    'bazel': [],
    'bazel-bindings': ['bazel'],
    'bazel-tensorflow': ['bazel-bindings'],
    'bazel-nvidia': ['bazel-tensorflow'],
    'bazel-swiftshader': ['bazel-tensorflow'],
    'cmake': [],
    'cmake-android': ['cmake'],
    'cmake-nvidia': ['cmake'],
    'cmake-vulkan': ['cmake'],
    'cmake-swiftshader': ['cmake-vulkan'],
    'rbe-toolchain': [],
}

IMAGES_TO_DEPENDENT_IMAGES = {k: [] for k in IMAGES_TO_DEPENDENCIES.keys()}
for image, dependencies in IMAGES_TO_DEPENDENCIES.items():
  for dependency in dependencies:
    IMAGES_TO_DEPENDENT_IMAGES[dependency].append(image)

IMAGES_HELP = [f'`{name}`' for name in IMAGES_TO_DEPENDENCIES.keys()]
IMAGES_HELP = f'{", ".join(IMAGES_HELP)} or `all`'

RBE_MESSAGE = """
Remember to update the `rbe_default` digest in the `WORKSPACE` file to reflect
the new digest for the container.

Use `docker images --digests` to view the digest."""


def parse_arguments():
  """Parses command-line options."""
  parser = argparse.ArgumentParser(
      description="Build IREE's Docker images and optionally push them to GCR.")
  parser.add_argument(
      '--image',
      dest='images',
      type=str,
      required=True,
      action='append',
      help=f'Name of the image to build: {IMAGES_HELP}.')
  parser.add_argument(
      '--tag',
      type=str,
      default='latest',
      help='Tags for the images to build. Defaults to `latest` (which is good '
      'for testing changes in a PR). Use `prod` to update the images that the '
      'OSS CI uses.')
  parser.add_argument(
      '--push',
      action='store_true',
      help='Push the built images to GCR. Requires gcloud authorization.')

  args = parser.parse_args()
  for image in args.images:
    if image == 'all':
      args.images = IMAGES_TO_DEPENDENCIES.keys()
    elif image not in IMAGES_TO_DEPENDENCIES.keys():
      raise parser.error('Expected --image to be one of:\n'
                         f'  {IMAGES_HELP}\n'
                         f'but got `{image}`.')
  return args


def cmp_images_by_dependency(image1, image2):
  if image2 in IMAGES_TO_DEPENDENT_IMAGES[image1]:
    return -1
  if image1 in IMAGES_TO_DEPENDENT_IMAGES[image2]:
    return 1
  return (image1 > image2) - (image1 < image2)


def run_command(command):
  print(f'Running: {" ".join(command)}')
  process = subprocess.Popen(
      command,
      bufsize=1,
      stderr=subprocess.STDOUT,
      stdout=subprocess.PIPE,
      text=True)
  for line in process.stdout:
    print(line, end='')

  return process.poll()


def check_command(command):
  exit_code = run_command(command)
  if exit_code != 0:
    print(f'Command failed: {" ".join(command)}')
    sys.exit(exit_code)


if __name__ == '__main__':
  args = parse_arguments()

  # Ensure the user has the correct authorization if they try to push to GCR.
  if args.push:
    if run_command(['which', 'gcloud']) != 0:
      print('gcloud not found.'
            ' See https://cloud.google.com/sdk/install for installation.')
      sys.exit(1)
    check_command(['gcloud', 'auth', 'configure-docker'])

  # Check if any images depend on `args.images` and update them if they do.
  images_to_update_set = set()
  to_check = list(args.images)
  while to_check:
    image = to_check.pop()
    if image not in images_to_update_set:
      images_to_update_set.add(image)
      to_check.extend(IMAGES_TO_DEPENDENT_IMAGES[image])

  # Topo sort by image dependency
  images_to_update = sorted(
      images_to_update_set, key=functools.cmp_to_key(cmp_images_by_dependency))

  print(f'Also updating dependent images. Will update: {images_to_update}')
  for image in images_to_update:
    print(f'Updating image {image}')
    image_url = os.path.join(IREE_GCR_URL, f'{image}:{args.tag}')
    image_path = os.path.join(DOCKER_DIR, image.replace('-', '_'))
    check_command(['docker', 'build', '--tag', image_url, image_path])
    if args.push:
      check_command(['docker', 'push', image_url])

  if 'rbe-toolchain' in images_to_update:
    print(RBE_MESSAGE)
#!/usr/bin/env python3 # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # #      https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Builds the specified Docker images and optionally pushes them to GCR.  Example usage:   python3 build_tools/docker/build_and_update_gcr.py --image cmake # Map from image names to images that they depend on. Remember to update the `rbe_default` digest in the `WORKSPACE` file to reflect the new digest for the container.  Use `docker images --digests` to view the digest. Parses command-line options. # Ensure the user has the correct authorization if they try to push to GCR. # Check if any images depend on `args.images` and update them if they do. # Topo sort by image dependency