⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267579 in webkit


Ignore:
Timestamp:
Sep 25, 2020, 10:55:03 AM (6 years ago)
Author:
Jonathan Bedard
Message:

results.webkit.org: Use s3 for cold storage
https://bugs.webkit.org/show_bug.cgi?id=216662
<rdar://problem/69092010>

Rubber-stamped by Aakash Jain.

  • Scripts/libraries/resultsdbpy/resultsdbpy/init.py:
  • Scripts/libraries/resultsdbpy/resultsdbpy/model/archive_context.py:

(ArchiveContext.init): Differentiate between cache storage and long-term storage of archives.
(ArchiveContext.enter): Connect to the cold storage archive, if one is available.
(ArchiveContext.exit): Disconnect from the cold storage archive, if applicable.
(ArchiveContext.register): Save to cold storage instead of cache storage by default.
(ArchiveContext.find_archive):

  • Scripts/libraries/resultsdbpy/resultsdbpy/model/model.py:

(Model.init): Pass S3 credentials to ArchiveContext.

  • Scripts/libraries/resultsdbpy/resultsdbpy/model/s3_archiver.py: Added.

(S3Archiver):
(S3Archiver.Credentials):
(S3Archiver.init): Connect to S3 and configure our bucket.
(S3Archiver._cipher): Construct new AES cipher, if a key was provided.
(S3Archiver.enter): Create S3 resource, if one is not available.
(S3Archiver.exit): Teardown S3 resource.
(S3Archiver.save): Save an archive to S3 by it's hash.
(S3Archiver.retrieve): Retreive an archive from S3 by its hash.

  • Scripts/libraries/resultsdbpy/setup.py: Add boto3.
Location:
trunk/Tools
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r267568 r267579  
     12020-09-25  Jonathan Bedard  <jbedard@apple.com>
     2
     3        results.webkit.org: Use s3 for cold storage
     4        https://bugs.webkit.org/show_bug.cgi?id=216662
     5        <rdar://problem/69092010>
     6
     7        Rubber-stamped by Aakash Jain.
     8
     9        * Scripts/libraries/resultsdbpy/resultsdbpy/__init__.py:
     10        * Scripts/libraries/resultsdbpy/resultsdbpy/model/archive_context.py:
     11        (ArchiveContext.__init__): Differentiate between cache storage and long-term storage of archives.
     12        (ArchiveContext.__enter__): Connect to the cold storage archive, if one is available.
     13        (ArchiveContext.__exit__): Disconnect from the cold storage archive, if applicable.
     14        (ArchiveContext.register): Save to cold storage instead of cache storage by default.
     15        (ArchiveContext.find_archive):
     16        * Scripts/libraries/resultsdbpy/resultsdbpy/model/model.py:
     17        (Model.__init__): Pass S3 credentials to ArchiveContext.
     18        * Scripts/libraries/resultsdbpy/resultsdbpy/model/s3_archiver.py: Added.
     19        (S3Archiver):
     20        (S3Archiver.Credentials):
     21        (S3Archiver.__init__): Connect to S3 and configure our bucket.
     22        (S3Archiver._cipher): Construct new AES cipher, if a key was provided.
     23        (S3Archiver.__enter__): Create S3 resource, if one is not available.
     24        (S3Archiver.__exit__): Teardown S3 resource.
     25        (S3Archiver.save): Save an archive to S3 by it's hash.
     26        (S3Archiver.retrieve): Retreive an archive from S3 by its hash.
     27        * Scripts/libraries/resultsdbpy/setup.py: Add boto3.
     28
    1292020-09-25  Youenn Fablet  <youenn@apple.com>
    230
  • trunk/Tools/Scripts/libraries/resultsdbpy/resultsdbpy/__init__.py

    r267542 r267579  
    4444    )
    4545
    46 version = Version(1, 0, 2)
     46version = Version(1, 1, 0)
    4747
    4848name = 'resultsdbpy'
  • trunk/Tools/Scripts/libraries/resultsdbpy/resultsdbpy/model/archive_context.py

    r256172 r267579  
    2323import calendar
    2424import io
    25 import json
    2625import time
    2726import zipfile
    2827
    2928from cassandra.cqlengine import columns
    30 from cassandra.cqlengine.models import Model
    31 from collections import OrderedDict
    3229from datetime import datetime
    3330from resultsdbpy.controller.commit import Commit
    34 from resultsdbpy.controller.configuration import Configuration
    3531from resultsdbpy.model.archiver import Archiver
    3632from resultsdbpy.model.cassandra_archiver import CassandraArchiver
    3733from resultsdbpy.model.commit_context import CommitContext
    3834from resultsdbpy.model.configuration_context import ClusteredByConfiguration
     35from resultsdbpy.model.s3_archiver import S3Archiver
    3936from resultsdbpy.model.upload_context import UploadContext
    4037
     
    8279        return zipfile.ZipFile(archive, mode='r')
    8380
    84     def __init__(self, configuration_context, commit_context, ttl_seconds=None):
     81    def __init__(self, configuration_context, commit_context, ttl_seconds=None, s3_credentials=None):
    8582        self.configuration_context = configuration_context
    8683        self.commit_context = commit_context
    8784        self.cassandra = self.configuration_context.cassandra
    88         self.archiver = CassandraArchiver(self.cassandra)
     85        self.cached_archiver = CassandraArchiver(self.cassandra)
     86        self.cold_archiver = S3Archiver(
     87            bucket='{}-results-archive'.format(self.cassandra.keyspace.replace('_', '-')),
     88            credentials=s3_credentials,
     89            ttl_seconds=ttl_seconds,
     90        ) if s3_credentials else None
    8991        self.ttl_seconds = ttl_seconds
    9092
     
    9698        self.configuration_context.__enter__()
    9799        self.commit_context.__enter__()
    98         self.archiver.__enter__()
     100        self.cached_archiver.__enter__()
     101        if self.cold_archiver:
     102            self.cold_archiver.__enter__()
    99103
    100104    def __exit__(self, *args, **kwargs):
    101105        self.commit_context.__exit__(*args, **kwargs)
    102106        self.configuration_context.__exit__(*args, **kwargs)
    103         self.archiver.__exit__(*args, **kwargs)
     107        self.cached_archiver.__exit__(*args, **kwargs)
     108        if self.cold_archiver:
     109            self.cold_archiver.__exit__()
    104110
    105111    def register(self, archive, configuration, commits, suite, timestamp=None):
     
    117123                    UploadContext.SuitesByConfiguration.__table_name__, configuration, suite=suite, branch=branch, ttl=ttl,
    118124                )
    119                 digest = self.archiver.save(archive, retain_for=ttl)
     125
     126                archiver_to_use = self.cold_archiver or self.cached_archiver
     127                size = Archiver.archive_size(archive)
     128                digest = archiver_to_use.save(archive, retain_for=ttl)
    120129
    121130                self.configuration_context.insert_row_with_configuration(
     
    124133                    sdk=configuration.sdk or '?', start_time=timestamp,
    125134                    digest=digest,
    126                     size=Archiver.archive_size(archive),
     135                    size=size,
    127136                )
    128137
     
    168177
    169178                    if not archive_by_digest.get(value.get('digest')):
    170                         archive = self.archiver.retrieve(value.get('digest'), value.get('size', None))
     179                        archive = self.cached_archiver.retrieve(value.get('digest'), value.get('size', None))
    171180                        if not archive:
    172                             continue
     181                            if not self.cold_archiver:
     182                                continue
     183
     184                            archive = self.cold_archiver.retrieve(value.get('digest'), value.get('size', None))
     185                            if not archive:
     186                                continue
     187
     188                            # If we retrieved an archive from the cold_archiver, it's pretty likely that
     189                            # the same archive will be retrieved in the near future. Cache the archive for 6 hours
     190                            self.cached_archiver.save(archive, retain_for=60 * 60 * 6)
     191
    173192                        archive_by_digest[value.get('digest')] = archive
    174193
  • trunk/Tools/Scripts/libraries/resultsdbpy/resultsdbpy/model/model.py

    r265305 r267579  
    4646        value = columns.Text(required=True)
    4747
    48     def __init__(self, redis, cassandra, repositories=[], default_ttl_seconds=TTL_YEAR * 5, archive_ttl_seconds=TTL_WEEK * 8, async_processing=False):
     48    def __init__(self, redis, cassandra, repositories=[], default_ttl_seconds=TTL_YEAR * 5, archive_ttl_seconds=TTL_WEEK * 8, async_processing=False, s3_credentials=None):
    4949        if default_ttl_seconds is not None and default_ttl_seconds < 4 * self.TTL_WEEK:
    5050            raise ValueError('TTL must be at least 4 weeks')
     
    100100            commit_context=self.commit_context,
    101101            ttl_seconds=self.archive_ttl_seconds,
     102            s3_credentials=s3_credentials,
    102103        )
    103104
  • trunk/Tools/Scripts/libraries/resultsdbpy/setup.py

    r266080 r267579  
    6060    ],
    6161    install_requires=[
     62        'boto3',
    6263        'cassandra-driver',
    6364        'fakeredis',
     
    6667        'gunicorn',
    6768        'lupa',
     69        'pycryptodome',
    6870        'redis',
    6971        'xmltodict',
Note: See TracChangeset for help on using the changeset viewer.