Ejemplo n.º 1
0
def get_expected_redirects(flocker_version):
    """
    Get the expected redirects for a given version of Flocker, if that version
    has been published successfully. Documentation versions (e.g. 0.3.0.post2)
    are published to their release version counterparts (e.g. 0.3.0).

    :param bytes flocker_version: The version of Flocker for which to get
        expected redirects.

    :return: Dictionary mapping paths to the path to which they are expected to
        redirect.
    """
    published_version = get_doc_version(flocker_version)

    if is_release(published_version):
        expected_redirects = {
            '/':
            '/en/' + published_version + '/',
            '/en/':
            '/en/' + published_version + '/',
            '/en/latest':
            '/en/' + published_version + '/',
            '/en/latest/faq/index.html':
            '/en/' + published_version + '/faq/index.html',
        }
    else:
        expected_redirects = {
            '/en/devel':
            '/en/' + published_version + '/',
            '/en/devel/faq/index.html':
            '/en/' + published_version + '/faq/index.html',
        }

    return expected_redirects
Ejemplo n.º 2
0
def get_expected_redirects(flocker_version):
    """
    Get the expected redirects for a given version of Flocker, if that version
    has been published successfully. Documentation versions (e.g. 0.3.0.post2)
    are published to their release version counterparts (e.g. 0.3.0).

    :param bytes flocker_version: The version of Flocker for which to get
        expected redirects.

    :return: Dictionary mapping paths to the path to which they are expected to
        redirect.
    """
    published_version = get_doc_version(flocker_version)

    if is_release(published_version):
        expected_redirects = {
            '/': '/en/' + published_version + '/',
            '/en/': '/en/' + published_version + '/',
            '/en/latest': '/en/' + published_version + '/',
            '/en/latest/faq/index.html':
                '/en/' + published_version + '/faq/index.html',
        }
    else:
        expected_redirects = {
            '/en/devel': '/en/' + published_version + '/',
            '/en/devel/faq/index.html':
                '/en/' + published_version + '/faq/index.html',
        }

    return expected_redirects
Ejemplo n.º 3
0
    def parseArgs(self):
        version = self['flocker-version']

        if not (is_release(version) or is_weekly_release(version)
                or is_pre_release(version)):
            raise NotARelease()

        if get_doc_version(version) != version:
            raise DocumentationRelease()
Ejemplo n.º 4
0
    def parseArgs(self):
        version = self['flocker-version']

        if not (is_release(version)
                or is_weekly_release(version)
                or is_pre_release(version)):
            raise NotARelease()

        if get_doc_version(version) != version:
            raise DocumentationRelease()
Ejemplo n.º 5
0
def upload_rpms(scratch_directory, target_bucket, version, build_server):
    """
    Upload RPMS from build server to yum repository.

    :param FilePath scratch_directory: Temporary directory to download
        repository to.
    :param bytes target_bucket: S3 bucket to upload repository to.
    :param bytes version: Version to download RPMs for.
    :param bytes build_server: Server to download new RPMs from.
    """
    if not (is_release(version)
            or is_weekly_release(version)
            or is_pre_release(version)):
        raise NotARelease()

    if get_doc_version(version) != version:
        raise DocumentationRelease()

    is_dev = not is_release(version)
    if is_dev:
        target_distro_suffix = "-testing"
    else:
        target_distro_suffix = ""


    operating_systems = [
        {'distro': 'fedora', 'version': '20', 'arch': 'x86_64'},
        {'distro': 'centos', 'version': '7', 'arch': 'x86_64'},
    ]

    for operating_system in operating_systems:
        yield update_repo(
            rpm_directory=scratch_directory.child(
                b'{}-{}-{}'.format(
                    operating_system['distro'],
                    operating_system['version'],
                    operating_system['arch'])),
            target_bucket=target_bucket,
            target_key=os.path.join(
                operating_system['distro'] + target_distro_suffix,
                operating_system['version'],
                operating_system['arch']),
            source_repo=os.path.join(
                build_server, b'results/omnibus',
                version,
                b'{}-{}'.format(
                    operating_system['distro'],
                    operating_system['version'])),
            packages=FLOCKER_PACKAGES,
            flocker_version=version,
            distro_name=operating_system['distro'],
            distro_version=operating_system['version'],
        )
Ejemplo n.º 6
0
# General information about the project.
project = u'Flocker'
copyright = u'2014, ClusterHQ'

extlinks = {
    'issue': ('https://clusterhq.atlassian.net/browse/FLOC-%s', 'issue '),
}

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from flocker import __version__
from flocker.common.version import get_doc_version, is_release
# The short X.Y version.
version = get_doc_version(__version__)

html_context = {
    # This is used to show the development version warning.
    'is_release': is_release(__version__),
}

# The full version, including alpha/beta/rc tags.
release = version

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# We override with our own variant to improve search results slightly.
from sphinx.search.en import SearchEnglish
from sphinx.search import languages as sphinx_languages
Ejemplo n.º 7
0
    def parseArgs(self):
        if self['doc-version'] is None:
            self['doc-version'] = get_doc_version(self['flocker-version'])

        if self['production']:
            self.environment = Environments.PRODUCTION
Ejemplo n.º 8
0
def publish_docs(flocker_version, doc_version, environment):
    """
    Publish the Flocker documentation. The documentation for each version of
    Flocker is uploaded to a development bucket on S3 by the build server and
    this copies the documentation for a particular ``flocker_version`` and
    publishes it as ``doc_version``. Attempting to publish documentation to a
    staging environment as a documentation version publishes it as the version
    being updated.

    :param bytes flocker_version: The version of Flocker to publish the
        documentation for.
    :param bytes doc_version: The version to publish the documentation as.
    :param Environments environment: The environment to publish the
        documentation to.
    :raises NotARelease: Raised if trying to publish to a version that isn't a
        release.
    :raises NotTagged: Raised if publishing to production and the version being
        published version isn't tagged.
    """
    if not (is_release(doc_version)
            or is_weekly_release(doc_version)
            or is_pre_release(doc_version)):
        raise NotARelease()

    if environment == Environments.PRODUCTION:
        if get_doc_version(flocker_version) != doc_version:
            raise NotTagged()
    configuration = DOCUMENTATION_CONFIGURATIONS[environment]

    dev_prefix = '%s/' % (flocker_version,)
    version_prefix = 'en/%s/' % (get_doc_version(doc_version),)

    is_dev = not is_release(doc_version)
    if is_dev:
        stable_prefix = "en/devel/"
    else:
        stable_prefix = "en/latest/"

    # Get the list of keys in the new documentation.
    new_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.dev_bucket,
                   prefix=dev_prefix))
    # Get the list of keys already existing for the given version.
    # This should only be non-empty for documentation releases.
    existing_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.documentation_bucket,
                   prefix=version_prefix))

    # Copy the new documentation to the documentation bucket.
    yield Effect(
        CopyS3Keys(source_bucket=configuration.dev_bucket,
                   source_prefix=dev_prefix,
                   destination_bucket=configuration.documentation_bucket,
                   destination_prefix=version_prefix,
                   keys=new_version_keys))

    # Delete any keys that aren't in the new documentation.
    yield Effect(
        DeleteS3Keys(bucket=configuration.documentation_bucket,
                     prefix=version_prefix,
                     keys=existing_version_keys - new_version_keys))

    # Update the key used for error pages if we're publishing to staging or if
    # we're publishing a marketing release to production.
    if ((environment is Environments.STAGING) or
        (environment is Environments.PRODUCTION and not is_dev)):
        yield Effect(
            UpdateS3ErrorPage(bucket=configuration.documentation_bucket,
                              target_prefix=version_prefix))

    # Update the redirect for the stable URL (en/latest/ or en/devel/)
    # to point to the new version. Returns the old target.
    old_prefix = yield Effect(
        UpdateS3RoutingRule(bucket=configuration.documentation_bucket,
                            prefix=stable_prefix,
                            target_prefix=version_prefix))

    # If we have changed versions, get all the keys from the old version
    if old_prefix:
        previous_version_keys = yield Effect(
            ListS3Keys(bucket=configuration.documentation_bucket,
                       prefix=old_prefix))
    else:
        previous_version_keys = set()

    # The changed keys are the new keys, the keys that were deleted from this
    # version, and the keys for the previous version.
    changed_keys = (new_version_keys |
                    existing_version_keys |
                    previous_version_keys)

    # S3 serves /index.html when given /, so any changed /index.html means
    # that / changed as well.
    # Note that we check for '/index.html' but remove 'index.html'
    changed_keys |= {key_name[:-len('index.html')]
                     for key_name in changed_keys
                     if key_name.endswith('/index.html')}

    # Always update the root.
    changed_keys |= {''}

    # The full paths are all the changed keys under the stable prefix, and
    # the new version prefix. This set is slightly bigger than necessary.
    changed_paths = {prefix + key_name
                     for key_name in changed_keys
                     for prefix in [stable_prefix, version_prefix]}

    # Invalidate all the changed paths in cloudfront.
    yield Effect(
        CreateCloudFrontInvalidation(cname=configuration.cloudfront_cname,
                                     paths=changed_paths))
Ejemplo n.º 9
0
# General information about the project.
project = u'Flocker'
copyright = u'2014, ClusterHQ'

extlinks = {
    'issue': ('https://clusterhq.atlassian.net/browse/FLOC-%s', 'issue '),
}

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from flocker import __version__
from flocker.common.version import get_doc_version, is_release
# The short X.Y version.
version = get_doc_version(__version__)

html_context = {
    # This is used to show the development version warning.
    'is_release': is_release(__version__),
}

# The full version, including alpha/beta/rc tags.
release = version

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# We override with our own variant to improve search results slightly.
from sphinx.search.en import SearchEnglish
from sphinx.search import languages as sphinx_languages
Ejemplo n.º 10
0
    def parseArgs(self):
        if self['doc-version'] is None:
            self['doc-version'] = get_doc_version(self['flocker-version'])

        if self['production']:
            self.environment = Environments.PRODUCTION
Ejemplo n.º 11
0
def publish_docs(flocker_version, doc_version, environment):
    """
    Publish the Flocker documentation. The documentation for each version of
    Flocker is uploaded to a development bucket on S3 by the build server and
    this copies the documentation for a particular ``flocker_version`` and
    publishes it as ``doc_version``. Attempting to publish documentation to a
    staging environment as a documentation version publishes it as the version
    being updated.

    :param bytes flocker_version: The version of Flocker to publish the
        documentation for.
    :param bytes doc_version: The version to publish the documentation as.
    :param Environments environment: The environment to publish the
        documentation to.
    :raises NotARelease: Raised if trying to publish to a version that isn't a
        release.
    :raises NotTagged: Raised if publishing to production and the version being
        published version isn't tagged.
    """
    if not (is_release(doc_version) or is_weekly_release(doc_version)
            or is_pre_release(doc_version)):
        raise NotARelease()

    if environment == Environments.PRODUCTION:
        if get_doc_version(flocker_version) != doc_version:
            raise NotTagged()
    configuration = DOCUMENTATION_CONFIGURATIONS[environment]

    dev_prefix = '%s/' % (flocker_version, )
    version_prefix = 'en/%s/' % (get_doc_version(doc_version), )

    is_dev = not is_release(doc_version)
    if is_dev:
        stable_prefix = "en/devel/"
    else:
        stable_prefix = "en/latest/"

    # Get the list of keys in the new documentation.
    new_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.dev_bucket, prefix=dev_prefix))
    # Get the list of keys already existing for the given version.
    # This should only be non-empty for documentation releases.
    existing_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.documentation_bucket,
                   prefix=version_prefix))

    # Copy the new documentation to the documentation bucket.
    yield Effect(
        CopyS3Keys(source_bucket=configuration.dev_bucket,
                   source_prefix=dev_prefix,
                   destination_bucket=configuration.documentation_bucket,
                   destination_prefix=version_prefix,
                   keys=new_version_keys))

    # Delete any keys that aren't in the new documentation.
    yield Effect(
        DeleteS3Keys(bucket=configuration.documentation_bucket,
                     prefix=version_prefix,
                     keys=existing_version_keys - new_version_keys))

    # Update the key used for error pages if we're publishing to staging or if
    # we're publishing a marketing release to production.
    if ((environment is Environments.STAGING)
            or (environment is Environments.PRODUCTION and not is_dev)):
        yield Effect(
            UpdateS3ErrorPage(bucket=configuration.documentation_bucket,
                              target_prefix=version_prefix))

    # Update the redirect for the stable URL (en/latest/ or en/devel/)
    # to point to the new version. Returns the old target.
    old_prefix = yield Effect(
        UpdateS3RoutingRule(bucket=configuration.documentation_bucket,
                            prefix=stable_prefix,
                            target_prefix=version_prefix))

    # If we have changed versions, get all the keys from the old version
    if old_prefix:
        previous_version_keys = yield Effect(
            ListS3Keys(bucket=configuration.documentation_bucket,
                       prefix=old_prefix))
    else:
        previous_version_keys = set()

    # The changed keys are the new keys, the keys that were deleted from this
    # version, and the keys for the previous version.
    changed_keys = (new_version_keys | existing_version_keys
                    | previous_version_keys)

    # S3 serves /index.html when given /, so any changed /index.html means
    # that / changed as well.
    # Note that we check for '/index.html' but remove 'index.html'
    changed_keys |= {
        key_name[:-len('index.html')]
        for key_name in changed_keys if key_name.endswith('/index.html')
    }

    # Always update the root.
    changed_keys |= {''}

    # The full paths are all the changed keys under the stable prefix, and
    # the new version prefix. This set is slightly bigger than necessary.
    changed_paths = {
        prefix + key_name
        for key_name in changed_keys
        for prefix in [stable_prefix, version_prefix]
    }

    # Invalidate all the changed paths in cloudfront.
    yield Effect(
        CreateCloudFrontInvalidation(cname=configuration.cloudfront_cname,
                                     paths=changed_paths))
Ejemplo n.º 12
0
def calculate_base_branch(version, path):
    """
    The branch a release branch is created from depends on the release
    type and sometimes which pre-releases have preceeded this.

    :param bytes version: The version of Flocker to get a base branch for.
    :param bytes path: See :func:`git.Repo.init`.
    :returns: The base branch from which the new release branch was created.
    """
    if not (is_release(version)
            or is_weekly_release(version)
            or is_pre_release(version)):
        raise NotARelease()

    repo = Repo(path=path, search_parent_directories=True)
    existing_tags = [tag for tag in repo.tags if tag.name == version]

    if existing_tags:
        raise TagExists()

    release_branch_prefix = 'release/flocker-'

    if is_weekly_release(version):
        base_branch_name = 'master'
    elif is_pre_release(version) and get_pre_release(version) == 1:
        base_branch_name = 'master'
    elif get_doc_version(version) != version:
        base_branch_name = release_branch_prefix + get_doc_version(version)
    else:
        if is_pre_release(version):
            target_version = target_release(version)
        else:
            target_version = version

        pre_releases = []
        for tag in repo.tags:
            try:
                if (is_pre_release(tag.name) and
                    target_version == target_release(tag.name)):
                    pre_releases.append(tag.name)
            except UnparseableVersion:
                # The Flocker repository contains versions which are not
                # currently considered valid versions.
                pass

        if not pre_releases:
            raise NoPreRelease()

        latest_pre_release = sorted(
            pre_releases,
            key=lambda pre_release: get_pre_release(pre_release))[-1]

        if (is_pre_release(version) and get_pre_release(version) >
                get_pre_release(latest_pre_release) + 1):
            raise MissingPreRelease()

        base_branch_name = release_branch_prefix + latest_pre_release

    # We create a new branch from a branch, not a tag, because a maintenance
    # or documentation change may have been applied to the branch and not the
    # tag.
    # The branch must be available locally for the next step.
    repo.git.checkout(base_branch_name)

    return (
        branch for branch in repo.branches if
        branch.name == base_branch_name).next()
Ejemplo n.º 13
0
def calculate_base_branch(version, path):
    """
    The branch a release branch is created from depends on the release
    type and sometimes which pre-releases have preceeded this.

    :param bytes version: The version of Flocker to get a base branch for.
    :param bytes path: See :func:`git.Repo.init`.
    :returns: The base branch from which the new release branch was created.
    """
    if not (is_release(version) or is_weekly_release(version)
            or is_pre_release(version)):
        raise NotARelease()

    repo = Repo(path=path, search_parent_directories=True)
    existing_tags = [tag for tag in repo.tags if tag.name == version]

    if existing_tags:
        raise TagExists()

    release_branch_prefix = 'release/flocker-'

    if is_weekly_release(version):
        base_branch_name = 'master'
    elif is_pre_release(version) and get_pre_release(version) == 1:
        base_branch_name = 'master'
    elif get_doc_version(version) != version:
        base_branch_name = release_branch_prefix + get_doc_version(version)
    else:
        if is_pre_release(version):
            target_version = target_release(version)
        else:
            target_version = version

        pre_releases = []
        for tag in repo.tags:
            try:
                if (is_pre_release(tag.name)
                        and target_version == target_release(tag.name)):
                    pre_releases.append(tag.name)
            except UnparseableVersion:
                # The Flocker repository contains versions which are not
                # currently considered valid versions.
                pass

        if not pre_releases:
            raise NoPreRelease()

        latest_pre_release = sorted(
            pre_releases,
            key=lambda pre_release: get_pre_release(pre_release))[-1]

        if (is_pre_release(version) and get_pre_release(version) >
                get_pre_release(latest_pre_release) + 1):
            raise MissingPreRelease()

        base_branch_name = release_branch_prefix + latest_pre_release

    # We create a new branch from a branch, not a tag, because a maintenance
    # or documentation change may have been applied to the branch and not the
    # tag.
    # The branch must be available locally for the next step.
    repo.git.checkout(base_branch_name)

    return (branch for branch in repo.branches
            if branch.name == base_branch_name).next()