github.com/MetalBlockchain/metalgo@v1.11.9/.github/workflows/update-ami.py (about)

     1  #!/usr/bin/env python3
     2  import json
     3  import os 
     4  import boto3
     5  import uuid
     6  import re
     7  import subprocess
     8  import sys
     9  
    10  # Globals
    11  amifile = '.github/workflows/amichange.json'
    12  packerfile = ".github/packer/ubuntu-jammy-x86_64-public-ami.pkr.hcl"
    13  
    14  # Environment Globals
    15  product_id = os.getenv('PRODUCT_ID')
    16  role_arn = os.getenv('ROLE_ARN')
    17  vtag = os.getenv('TAG')
    18  tag = vtag.replace('v', '')
    19  skip_create_ami = os.getenv('SKIP_CREATE_AMI', "True")
    20  
    21  def packer_build(packerfile):
    22    print("Running the packer build")
    23    output = subprocess.run('/usr/local/bin/packer build ' + packerfile, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    24    if output.returncode != 0:
    25      raise RuntimeError(f"Command returned with code: {output.returncode}")
    26  
    27  def packer_build_update(packerfile):
    28    print("Creating packer AMI image for Marketplace")
    29    output = subprocess.run('/usr/local/bin/packer build ' + packerfile, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    30    if output.returncode != 0:
    31      raise RuntimeError(f"Command returned with code: {output.returncode}")
    32  
    33    found = re.findall('ami-[a-z0-9]*', str(output.stdout))
    34  
    35    if found:
    36      amiid = found[-1]
    37      return amiid
    38    else:
    39      raise RuntimeError(f"No AMI ID found in packer output: {output.stdout}")
    40  
    41  def parse_amichange(amifile, amiid, role_arn, tag):
    42    # Create json blob to submit with the catalog update
    43    print("Updating the json artifact with recent amiid and tag information")
    44    with open(amifile, 'r') as file:
    45      data = json.load(file)
    46  
    47    data['DeliveryOptions'][0]['Details']['AmiDeliveryOptionDetails']['AmiSource']['AmiId']=amiid
    48    data['DeliveryOptions'][0]['Details']['AmiDeliveryOptionDetails']['AmiSource']['AccessRoleArn']=role_arn
    49    data['Version']['VersionTitle']=tag
    50    return json.dumps(data)
    51  
    52  def update_ami(amifile, amiid):
    53    # Update the catalog with the last amiimage
    54    print('Updating the marketplace image')
    55    client = boto3.client('marketplace-catalog',region_name='us-east-1')
    56    uid = str(uuid.uuid4())
    57    global tag
    58    global product_id
    59    global role_arn
    60  
    61    try:
    62      response = client.start_change_set(
    63        Catalog='AWSMarketplace',
    64        ChangeSet=[
    65          {
    66            'ChangeType': 'AddDeliveryOptions',
    67            'Entity': {
    68              'Type': 'AmiProduct@1.0',
    69              'Identifier': product_id
    70            },
    71              'Details': parse_amichange(amifile,amiid,role_arn,tag),
    72              'ChangeName': 'Update'
    73            },
    74          ],
    75          ChangeSetName='MetalGo Update ' + tag,
    76          ClientRequestToken=uid
    77      )
    78      print(response)
    79    except client.exceptions.ResourceInUseException:
    80      print("The product is currently blocked by Amazon.  Please check the product site for more details")
    81    except Exception as e:
    82      print(f"An error occurred while updating AMI delivery options: {e}")
    83  
    84  def main():
    85    try:
    86      if skip_create_ami == "True":
    87        packer_build(packerfile)
    88      else:
    89        update_ami(amifile, packer_build_update(packerfile))
    90      
    91      print("Ran packer build and update ami successfully")
    92    except Exception as e:
    93      print(f"An error occurred while running packer")
    94      sys.exit(5)
    95  
    96  if __name__ == '__main__':
    97    main()
    98