update_run_token.py 4.53 KB
Newer Older
1
#!/usr/bin/env python3
Lachlan's avatar
Lachlan committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

#
#  Copyright (C) 2018 Codethink Limited
#  Copyright (C) 2018 Bloomberg Finance LP
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Lachlan Mackenzie <lachlan.mackenzie@codethink.co.uk>

import argparse
import os
import logging
import ntpath
import tempfile
import shutil
29 30
import operator
import datetime
Lachlan's avatar
Lachlan committed
31 32 33

from distutils.file_util import copy_file

34 35 36 37
import yaml

import token_file_processing

Lachlan's avatar
Lachlan committed
38 39 40 41 42 43 44 45 46 47 48
# This command line executable allows the updating of a given run token file
# given a path to a set of results. The token file is processed but not
# not validated (on the basis that this has already had to be done to get to
# this point). The path for the generated results files are checked and the
# most recent file established. The new version of the token file is updated
# and copied over the original
#
# token_file - the path to the token file to be updated
# input_path - the path to the cached results files
#

49

Lachlan's avatar
Lachlan committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
def main():
   token_file = 'run_token.yml'
   results_files = 'results_cache/'

   parser = argparse.ArgumentParser()
   parser.add_argument("-t", "--token_file",
                       help="The token file that is to be updated.",
                       type=str)
   parser.add_argument("-i", "--input_path",
                       help="Path for generated results",
                       type=str)
   args = parser.parse_args()

   if bool(args.token_file):
      token_file = args.token_file

   if bool(args.input_path):
      results_files = args.input_path

   print(token_file)
   print(results_files)

   if not update_run_token(token_file=token_file, results_files=results_files):
73
      logging.error('Unable to update token file: %s', token_file)
Lachlan's avatar
Lachlan committed
74 75
      os.sys.exit(1)

76

Lachlan's avatar
Lachlan committed
77 78 79 80 81
def update_run_token(token_file, results_files):

   # Check if token file exists and try to load
   if os.path.isfile(token_file):
      try:
82
         token_values = token_file_processing.process_token_file(token_file)
Lachlan's avatar
Lachlan committed
83
      except OSError as err:
84
         logging.error("Unable to access token file: %s", token_file)
Lachlan's avatar
Lachlan committed
85
         return False
86 87
      except yaml.YAMLError:
         logging.error("Unable to parse token file: %s", token_file)
Lachlan's avatar
Lachlan committed
88 89
         return False
   else:
90
      logging.error("Token file does not exist: %s", token_file)
Lachlan's avatar
Lachlan committed
91 92 93 94
      return False

   # Check if results exist and get the last generated one
   if os.path.isdir(results_files):
95
      file_times = {}
Lachlan's avatar
Lachlan committed
96 97 98
      print(results_files)
      for file in os.listdir(results_files):
         if file.endswith('.json'):
99 100
            file_times[os.path.join(results_files, file)] = datetime.datetime.strptime(
               os.path.basename(file), 'results-%Y-%m-%d-%H:%M:%S.json')
101 102
      if file_times:
         latest_file = max(file_times.items(), key=operator.itemgetter(1))[0]
Lachlan's avatar
Lachlan committed
103 104
         archive_result = ntpath.basename(latest_file)
      else:
105
         logging.info('No results files found from: %s', results_files)
Lachlan's avatar
Lachlan committed
106 107
         return False
   else:
108
      logging.error('Results path does not exist, nothing to update: %s', results_files)
Lachlan's avatar
Lachlan committed
109 110 111
      return False

   token_values['build']['result'] = archive_result
112

Lachlan's avatar
Lachlan committed
113 114 115 116 117 118 119 120 121
   buildstream_sha = os.environ.get('BUILDSTREAM_HEAD')
   if not buildstream_sha:
      logging.error('No Buildstream SHA was set')
      return False

   temp_staging_area = tempfile.mkdtemp(prefix='temp_staging_location')
   temp_file = os.path.join(temp_staging_area, 'token_temp.yaml')
   try:
      # Generate the token file.;
122 123 124 125 126
      token_file_processing.generate_token_file(
         temp_file,
         buildstream_sha,
         token_values['build']['bs_branch'],
         archive_result)
Lachlan's avatar
Lachlan committed
127 128
      # Copy the temporary token file to replace requested
      copy_file(temp_file, token_file)
129 130 131

   # TODO: Sort out what this error here actually means
   # pylint: disable=broad-except
Lachlan's avatar
Lachlan committed
132
   except Exception as err:
133
      logging.error('Unable to write token file: %s', err)
Lachlan's avatar
Lachlan committed
134 135 136 137 138 139 140 141 142
      return False
   finally:
      shutil.rmtree(temp_staging_area)

   return True


if __name__ == "__main__":
   main()