Hi Miguel, Miguel Couceiro <couce...@isec.pt> writes:
> Hi Loris, > > I am interested in the script you mentioned. Could you please post the code? > > Best regards, > Miguel [snip (23 lines)] >> We have licenses, such as Intel compiler licenses, which can be used >> both interactively outside the queuing system and within Slurm jobs. >> >> We use a script which parses the output of the FlexLM manager and >> modifies a reservation in which the licenses are defined. This is run >> as a cron job once a minute. It's a bit of a kludge and obviously won't >> work well if there is a lot of contention for licenses. >> >> I can post the code if anyone is interested. >> >> Cheers, >> >> Loris It is almost the first thing I wrote in Python, so beware. Also the usual caveats apply: use at your own risk, no warranty implied, I'm not responsible if the script causes your license server to implode, etc. The code relies on being able to parse the output of the FlexLM license server. If you are using something else, you'll have to adapt the regular expression used appropriately. The program has an option to generate a 'Licenses' entry for slurm.conf. Users then have to specify both a license and the appropriate reservation, e.g. #SBATCH --licenses=matlab_MATLAB #SBATCH --reservation=licenses_matlab The main things to be configured are the paths to the license manager and to 'scontrol' as well as the paths to the license files. One thing is missing: The script should also update the reservation to move the end time continuously into the future, such that it never expires. Here's the code. Enjoy. Improvements/suggestions welcome. Cheers, Loris ------------------------------------------------------------------------------- #!/shared/apps/python/python3.4/bin/python from subprocess import check_output import re import string import os import sys import argparse parser = argparse.ArgumentParser(description="update licence reservations") parser.add_argument("-i","--initialise", help="generate line for slurm.conf", action="store_true") parser.add_argument("-d","--dryrun", help="print action without performing it", action="store_true") args = parser.parse_args() total_or_available = 'available' separator = ':' if args.initialise: total_or_available = 'total' separator = '*' lmstat = '/local/licenses/matlab/etc/lmstat' scontrol = '/usr/bin/scontrol' matlab_license_file = '/local/licenses/matlab/etc/license.dat' intel_license_file = '/shared/licenses/intel/license_2015-2016.lic' vendors = {} vendors['matlab'] = {'prefix':'matlab_', 'licence_file': matlab_license_file } vendors['intel'] = {'prefix':'intel_', 'licence_file': intel_license_file} # Note that licence names may contain hyphens (particularly for Intel products) re_dict = re.compile(r"""Users\s+of\s+(?P<name>\w+(?:-\w+)*):\s+ \(Total\s+of\s+(?P<total>\d+)\s+licenses?\s+issued;\s+ Total\s+of\s+(?P<in_use>\d+)\s+licenses?\s+in\s+use\)""", re.VERBOSE) re_product = re.compile('User.*', re.MULTILINE) re_name = re.compile('Users of (.*?):') re_error = re.compile('Error') for vendor, params in vendors.items(): cmd = [lmstat, "-a", "-c", params['licence_file']] out = check_output(cmd) string = str(out,'utf-8') licences = [] for line in re_product.findall(string): # Something is wrong with the licence manager or license file if re_error.search(line): product['name'] = re_name.match(line).group(1) product['error'] = True # Extract licence data else: m = re_dict.match(line) product = m.groupdict() product['error'] = False licences.append(product) licence_strings_total = [] licence_strings_available = [] for licence in licences: if not licence['error']: slurm_licence_name = params['prefix'] slurm_licence_name += licence['name'] licence['available'] = int(licence['total']) - \ int(licence['in_use']) licence_strings_total.append(slurm_licence_name + \ separator + \ str(licence['total'])) if licence['available'] > 0: # Slurm doesn't like 0 licenses licence_strings_available.append(slurm_licence_name + \ separator + \ str(licence['available'])) slurm_licence_total_string = ",".join(licence_strings_total) slurm_licence_available_string = ",".join(licence_strings_available) scontrol_string = scontrol + \ ' update reservationname=licenses_' + vendor + \ ' licenses=' + slurm_licence_available_string if args.initialise: print(slurm_licence_total_string) continue if args.dryrun: print(scontrol_string) continue # Actually update the reservation os.system(scontrol_string) # Strings used for testing # #string = 'Users of MATLAB_Distrib_Comp_Engine: (Total of 16 licenses issued; Total of 0 licenses in use)' #string = 'Users of Wavelet_Toolbox: (Error: 2 licenses, unsupported by licensed server)' ------------------------------------------------------------------------------- -- Dr. Loris Bennett (Mr.) ZEDAT, Freie Universität Berlin Email loris.benn...@fu-berlin.de