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."