github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/packaging/ci/lambda/PublishRepoToBucket/lambda_function.py (about)

     1  #!/usr/bin/env python
     2  
     3  import re
     4  import json
     5  import boto3
     6  import traceback
     7  import tempfile
     8  import shutil
     9  import contextlib
    10  import zipfile
    11  import gzip
    12  import xml.etree.ElementTree as ET
    13  from os import path
    14  
    15  from lemur_ci import pipeline
    16  
    17  from botocore.client import Config
    18  from boto3 import Session, client
    19  
    20  @contextlib.contextmanager
    21  def tempdir():
    22      dirpath = tempfile.mkdtemp()
    23      def cleanup():
    24          shutil.rmtree(dirpath)
    25      yield dirpath
    26  
    27  def lambda_handler(event, context):
    28      try:
    29          # for debugging
    30          print json.dumps(event)
    31  
    32          job = pipeline.Job(event['CodePipeline.job'])
    33          artifact = job.data['inputArtifacts'][0]
    34          config = job.data['actionConfiguration']['configuration']
    35          creds = job.data['artifactCredentials']
    36          from_bucket = artifact['location']['s3Location']['bucketName']
    37          from_key = artifact['location']['s3Location']['objectKey']
    38          to_bucket = config['UserParameters']
    39  
    40          session = Session(aws_access_key_id=creds['accessKeyId'],
    41                            aws_secret_access_key=creds['secretAccessKey'],
    42                            aws_session_token=creds['sessionToken'])
    43          s3 = session.client('s3', config=Config(signature_version='s3v4'))
    44  
    45          keyPrefix = 'devel'
    46          version = 'UNKNOWN'
    47          zipMembers = []
    48          with tempdir() as td:
    49              with tempfile.NamedTemporaryFile() as tf:
    50                  s3.download_file(from_bucket, from_key, tf.name)
    51                  with zipfile.ZipFile(tf.name, 'r') as zf:
    52                      zf.extractall(td)
    53                      zipMembers = zf.namelist()
    54                  # TODO: Figure out how to avoid double-wrapping this
    55                  if 'repo.zip' in zipMembers:
    56                      with zipfile.ZipFile(path.join(td, 'repo.zip'), 'r') as zf:
    57                          zf.extractall(td)
    58                          zipMembers = zf.namelist()
    59  
    60              # extract the RPM version
    61              r = ET.parse(path.join(td, 'repodata/repomd.xml')).getroot()
    62              pf = r.find(".//*[@type='primary']/{http://linux.duke.edu/metadata/repo}location").attrib['href']
    63              with gzip.open(path.join(td, pf)) as gz:
    64                  pr = ET.parse(gz).getroot()
    65                  version = pr.find('.//{http://linux.duke.edu/metadata/common}package/{http://linux.duke.edu/metadata/common}version').attrib['ver']
    66  
    67              if re.match(r'^\d+\.\d+\.\d+$', version):
    68                  keyPrefix = 'release'
    69  
    70              # Get a new s3 client to use IAM Role
    71              s3 = client('s3')
    72              for fileName in zipMembers:
    73                  if path.isdir(path.join(td, fileName)):
    74                      continue
    75                  s3.upload_file(path.join(td, fileName), to_bucket, path.join(keyPrefix, version, fileName))
    76  
    77          pipeline.put_job_success(job.id, "Published repo")
    78  
    79      except Exception as e:
    80          # If any other exceptions which we didn't expect are raised
    81          # then fail the job and log the exception message.
    82          print('Function failed due to exception.')
    83          print(e)
    84          traceback.print_exc()
    85          pipeline.put_job_failure(job.id, 'Function exception: ' + str(e))
    86  
    87      print('Function complete.')
    88      return "Complete."