Example #1
0
def CMDcleanup(parser, args):
    """Removes old versions of GAE application modules.

  Removes the specified versions from all app modules. If no versions are
  provided via command line, will ask interactively.

  When asking interactively, uses EDITOR environment variable to edit the list
  of versions. Otherwise uses notepad.exe on Windows, or vi otherwise.
  """
    parser.add_force_option()
    parser.allow_positional_args = True
    app, options, versions_to_remove = parser.parse_args(args)

    if not versions_to_remove:
        # List all deployed versions, dump them to a temp file to be edited.
        versions = app.get_uploaded_versions()
        fd, path = tempfile.mkstemp()
        atexit.register(lambda: os.remove(path))
        with os.fdopen(fd, "w") as f:
            header = "# Remove lines that correspond to versions\n" "# you'd like to delete from '%s'.\n"
            f.write(header % app.app_id + "\n".join(versions) + "\n")

        # Let user remove versions that are no longer needed.
        editor = os.environ.get("EDITOR", "notepad.exe" if sys.platform == "win32" else "vi")
        exit_code = os.system("%s %s" % (editor, path))
        if exit_code:
            print("Aborted.")
            return exit_code

        # Read back the file that now contains only versions to keep.
        keep = []
        with open(path, "r") as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith("#"):
                    continue
                if line not in versions:
                    print >>sys.stderr, "Unknown version: %s" % line
                    return 1
                if line not in keep:
                    keep.append(line)

        # Calculate a list of versions to remove.
        versions_to_remove = [v for v in versions if v not in keep]
        if not versions_to_remove:
            print("Nothing to do.")
            return 0

    # Deleting a version is a destructive operation, confirm.
    if not options.force:
        ok = gae_sdk_utils.confirm("Delete the following versions?", app, versions_to_remove)
        if not ok:
            print("Aborted.")
            return 1

    for version in versions_to_remove:
        print("Deleting %s..." % version)
        app.delete_version(version)

    return 0
Example #2
0
def CMDupload(parser, args):
    """Uploads a new version of specific (or all) modules of an app.

  Version name looks like <number>-<commit sha1>[-tainted-<who>], where:
    number      git commit number, monotonically increases with each commit
    commit sha1 upstream commit hash the branch is based of
    tainted     git repo has local modifications compared to upstream branch
    who         username who uploads the tainted version

  Doesn't make it a default unless --switch is specified. Use 'switch'
  subcommand to change default serving version.
  """
    parser.add_tag_option()
    parser.add_switch_option()
    parser.add_force_option()
    parser.allow_positional_args = True
    app, options, modules = parser.parse_args(args)

    for module in modules:
        if module not in app.modules:
            parser.error('No such module: %s' % module)

    version = calculate_version.calculate_version(app.app_dir, options.tag)

    # Updating indexes, queues, etc is a disruptive operation. Confirm.
    if not options.force:
        approved = gae_sdk_utils.confirm(
            'Upload new version, update indexes, queues and cron jobs?', app,
            version, modules)
        if not approved:
            print('Aborted.')
            return 1

    # 'appcfg.py update <list of modules>' does not update the rest of app engine
    # app like 'appcfg.py update <app dir>' does. It updates only modules. So do
    # index, queues, etc. updates manually afterwards.
    app.update_modules(version, modules)
    app.update_indexes()
    app.update_queues()
    app.update_cron()
    app.update_dispatch()

    print('-' * 80)
    print('New version:')
    print('  %s' % version)
    print('Uploaded as:')
    print('  https://%s-dot-%s.appspot.com' % (version, app.app_id))
    print('Manage at:')
    print('  https://appengine.google.com/deployment?app_id=s~' + app.app_id)
    print('-' * 80)

    if options.switch:
        if 'tainted-' in version:
            print('')
            print >> sys.stderr, 'Can\'t use --switch with a tainted version!'
            return 1
        print('Switching as default version')
        app.set_default_version(version)

    return 0
Example #3
0
def CMDupload(parser, args):
  """Uploads a new version of specific (or all) modules of an app.

  Version name looks like <number>-<commit sha1>[-tainted-<who>], where:
    number      git commit number, monotonically increases with each commit
    commit sha1 upstream commit hash the branch is based of
    tainted     git repo has local modifications compared to upstream branch
    who         username who uploads the tainted version

  Doesn't make it a default unless --switch is specified. Use 'switch'
  subcommand to change default serving version.
  """
  parser.add_tag_option()
  parser.add_switch_option()
  parser.add_force_option()
  parser.allow_positional_args = True
  app, options, modules = parser.parse_args(args)

  for module in modules:
    if module not in app.modules:
      parser.error('No such module: %s' % module)

  version = calculate_version.calculate_version(app.app_dir, options.tag)

  # Updating indexes, queues, etc is a disruptive operation. Confirm.
  if not options.force:
    approved = gae_sdk_utils.confirm(
        'Upload new version, update indexes, queues and cron jobs?',
        app, version, modules)
    if not approved:
      print('Aborted.')
      return 1

  # 'appcfg.py update <list of modules>' does not update the rest of app engine
  # app like 'appcfg.py update <app dir>' does. It updates only modules. So do
  # index, queues, etc. updates manually afterwards.
  app.update_modules(version, modules)
  app.update_indexes()
  app.update_queues()
  app.update_cron()
  app.update_dispatch()

  print('-' * 80)
  print('New version:')
  print('  %s' % version)
  print('Uploaded as:')
  print('  https://%s-dot-%s.appspot.com' % (version, app.app_id))
  print('Manage at:')
  print('  https://appengine.google.com/deployment?app_id=s~' + app.app_id)
  print('-' * 80)

  if options.switch:
    if 'tainted-' in version:
      print('')
      print >> sys.stderr, 'Can\'t use --switch with a tainted version!'
      return 1
    print('Switching as default version')
    app.set_default_version(version)

  return 0
Example #4
0
def CMDswitch(parser, args):
    """Switches default version of all app services.

  The version must be uploaded already. If no version is provided via command
  line, will ask interactively.
  """
    parser.add_switch_option()
    parser.add_force_option()
    parser.allow_positional_args = True
    app, options, version = parser.parse_args(args)
    if len(version) > 1:
        parser.error('Unknown args: %s' % version[1:])
    version = None if not version else version[0]

    # Interactively pick a version if not passed via command line.
    if not version:
        versions = app.get_uploaded_versions()
        if not versions:
            print('Upload a version first.')
            return 1

        print('Specify a version to switch to:')
        for version in versions:
            print('  %s' % version)

        prompt = 'Switch to version [%s]: ' % versions[-1]
        version = _raw_input(prompt) or versions[-1]
        if version not in versions:
            print('No such version.')
            return 1

    _print_version_log(app, version)
    # Switching a default version is disruptive operation. Require confirmation.
    if (not options.force and not gae_sdk_utils.confirm(
            'Switch default version?', app, version)):
        print('Aborted.')
        return 1

    print()
    app.set_default_version(version, roll_duration=options.roll_duration)
    return 0
Example #5
0
def CMDswitch(parser, args):
  """Switches default version of all app modules.

  The version must be uploaded already. If no version is provided via command
  line, will ask interactively.
  """
  parser.add_force_option()
  parser.allow_positional_args = True
  app, options, version = parser.parse_args(args)
  if len(version) > 1:
    parser.error('Unknown args: %s' % version[1:])
  version = None if not version else version[0]

  # Interactively pick a version if not passed via command line.
  if not version:
    versions = app.get_uploaded_versions()
    if not versions:
      print('Upload a version first.')
      return 1

    print('Specify a version to switch to:')
    for version in versions:
      print('  %s' % version)

    version = (
        raw_input('Switch to version [%s]: ' % versions[-1]) or versions[-1])
    if version not in versions:
      print('No such version.')
      return 1

  # Switching a default version is disruptive operation. Require confirmation.
  if not options.force:
    ok = gae_sdk_utils.confirm('Switch default version?', app, version)
    if not ok:
      print('Aborted.')
      return 1

  app.set_default_version(version)
  return 0
Example #6
0
def CMDcleanup(parser, args):
    """Removes old versions of GAE application modules.

  Removes the specified versions from all app modules. If no versions are
  provided via command line, will ask interactively.

  When asking interactively, uses EDITOR environment variable to edit the list
  of versions. Otherwise uses notepad.exe on Windows, or vi otherwise.
  """
    parser.add_force_option()
    parser.allow_positional_args = True
    app, options, versions_to_remove = parser.parse_args(args)

    if not versions_to_remove:
        # List all deployed versions, dump them to a temp file to be edited.
        versions = app.get_uploaded_versions()
        fd, path = tempfile.mkstemp()
        atexit.register(lambda: os.remove(path))
        with os.fdopen(fd, 'w') as f:
            header = ('# Remove lines that correspond to versions\n'
                      '# you\'d like to delete from \'%s\'.\n')
            f.write(header % app.app_id + '\n'.join(versions) + '\n')

        # Let user remove versions that are no longer needed.
        editor = os.environ.get(
            'EDITOR', 'notepad.exe' if sys.platform == 'win32' else 'vi')
        exit_code = os.system('%s %s' % (editor, path))
        if exit_code:
            print('Aborted.')
            return exit_code

        # Read back the file that now contains only versions to keep.
        keep = []
        with open(path, 'r') as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                if line not in versions:
                    print >> sys.stderr, 'Unknown version: %s' % line
                    return 1
                if line not in keep:
                    keep.append(line)

        # Calculate a list of versions to remove.
        versions_to_remove = [v for v in versions if v not in keep]
        if not versions_to_remove:
            print('Nothing to do.')
            return 0

    # Deleting a version is a destructive operation, confirm.
    if not options.force:
        ok = gae_sdk_utils.confirm('Delete the following versions?', app,
                                   versions_to_remove)
        if not ok:
            print('Aborted.')
            return 1

    for version in versions_to_remove:
        print('Deleting %s...' % version)
        app.delete_version(version)

    return 0
Example #7
0
def CMDupload(parser, args):
    """Uploads a new version of specific (or all) modules of an app.

  Note that module yamls are expected to be named module-<module name>.yaml

  Version name looks like <number>-<commit sha1>[-tainted-<who>], where:
    number      git commit number, monotonically increases with each commit
    commit sha1 upstream commit hash the branch is based of
    tainted     git repo has local modifications compared to upstream branch
    who         username who uploads the tainted version

  Doesn't make it a default unless --switch is specified. Use 'switch'
  subcommand to change default serving version.
  """
    parser.add_tag_option()
    parser.add_option('-x',
                      '--switch',
                      action='store_true',
                      help='Switch version after uploading new code')
    parser.add_switch_option()
    parser.add_force_option()
    parser.allow_positional_args = True
    app, options, modules = parser.parse_args(args)

    for module in modules:
        if module not in app.modules:
            parser.error('No such module: %s' % module)

    # Additional chars is for the app_id as well as 5 chars for '-dot-'.
    version = calculate_version.calculate_version(app.app_dir, options.tag,
                                                  len(app.app_id) + 5)

    # Updating indexes, queues, etc is a disruptive operation. Confirm.
    if not options.force:
        approved = gae_sdk_utils.confirm(
            'Upload new version, update indexes, queues and cron jobs?',
            app,
            version,
            modules,
            default_yes=True)
        if not approved:
            print('Aborted.')
            return 1

    app.update(version, modules)

    print('-' * 80)
    print('New version:')
    print('  %s' % version)
    print('Uploaded as:')
    print('  https://%s-dot-%s.appspot.com' % (version, app.app_id))
    print('Manage at:')
    print('  https://console.cloud.google.com/appengine/versions?project=' +
          app.app_id)
    print('-' * 80)

    if not options.switch:
        return 0
    if 'tainted-' in version:
        print('')
        print >> sys.stderr, 'Can\'t use --switch with a tainted version!'
        return 1
    _print_version_log(app, version)
    print('Switching as default version')
    app.set_default_version(version)
    return 0
Example #8
0
def CMDcleanup(parser, args):
  """Removes old versions of GAE application modules.

  Removes the specified versions from all app modules. If no versions are
  provided via command line, will ask interactively.

  When asking interactively, uses EDITOR environment variable to edit the list
  of versions. Otherwise uses notepad.exe on Windows, or vi otherwise.
  """
  parser.add_force_option()
  parser.allow_positional_args = True
  app, options, versions_to_remove = parser.parse_args(args)

  if not versions_to_remove:
    # List all deployed versions, dump them to a temp file to be edited.
    versions = app.get_uploaded_versions()
    fd, path = tempfile.mkstemp()
    atexit.register(lambda: os.remove(path))
    with os.fdopen(fd, 'w') as f:
      header = (
        '# Remove lines that correspond to versions\n'
        '# you\'d like to delete from \'%s\'.\n')
      f.write(header % app.app_id + '\n'.join(versions) + '\n')

    # Let user remove versions that are no longer needed.
    editor = os.environ.get(
        'EDITOR', 'notepad.exe' if sys.platform == 'win32' else 'vi')
    exit_code = os.system('%s %s' % (editor, path))
    if exit_code:
      print('Aborted.')
      return exit_code

    # Read back the file that now contains only versions to keep.
    keep = []
    with open(path, 'r') as f:
      for line in f:
        line = line.strip()
        if not line or line.startswith('#'):
          continue
        if line not in versions:
          print >> sys.stderr, 'Unknown version: %s' % line
          return 1
        if line not in keep:
          keep.append(line)

    # Calculate a list of versions to remove.
    versions_to_remove = [v for v in versions if v not in keep]
    if not versions_to_remove:
      print('Nothing to do.')
      return 0

  # Deleting a version is a destructive operation, confirm.
  if not options.force:
    ok = gae_sdk_utils.confirm(
        'Delete the following versions?', app, versions_to_remove)
    if not ok:
      print('Aborted.')
      return 1

  # 'delete_version' is buggy, it may require cookie based authentication for
  # some (old) applications.
  for version in versions_to_remove:
    print('Deleting %s...' % version)
    app.delete_version(version)

  return 0