def make_username_list(args): '''Make a list of the usernames from the current DM experiment. ''' log.info('Making a list of DM system usernames from current DM experiment') exp_name = directories.make_directory_name(args) try: exp_obj = exp_api.getExperimentByName(exp_name) return exp_obj['experimentUsernameList'] except: log.error('No such experiment in the DM system: {:s}'.format(exp_name)) log.error(' Have you run globus dm_init yet?') return []
def add_user(args): '''Add a user from the DM experiment. ''' exp_name = directories.make_directory_name(args) try: exp_obj = exp_api.getExperimentByName(exp_name) except: log.error(' No appropriate DM experiment found.') return try: add_users(exp_obj, ['d{:d}'.format(args.edit_user_badge)]) except: log.error(' Problem adding the user. Check the badge number')
def create_local_directory(remote_server, remote_dir): '''Create directory and all necessary parent directories, on the analysis and detector computers. These computers are generally located in the same local network at the beamline. ''' cmd = 'mkdir -m 777 ' + remote_dir try: # log.info(' *** sending command %s' % (cmd)) log.info(' *** creating remote directory %s' % (remote_dir)) subprocess.check_call(['ssh', remote_server, cmd]) log.info(' *** creating remote directory %s: Done!' % (remote_dir)) return 0 except subprocess.CalledProcessError as e: log.error(' *** Error while creating remote directory. Error code: %d' % (e.returncode)) return -1
def send_email(args): log.info("email will contain %s download data link", args.globus_server_name) log.info("send email to users?") if not yes_or_no(' *** Yes or No'): log.info(' ') log.warning(' *** Message not not sent') return False users = dm.list_users_this_dm_exp(args) emails = dm.make_user_email_list(users) #users = scheduling.get_current_users(args) #emails = scheduling.get_current_emails(users, exclude_pi=False) emails.append(args.primary_beamline_contact_email) emails.append(args.secondary_beamline_contact_email) if (args.globus_server_name == 'voyager'): s = smtplib.SMTP('mailhost.anl.gov') for em in emails: if args.msg['To'] is None: args.msg['To'] = em else: args.msg.replace_header('To', em) log.info(' Sending informational message to {:s}'.format(em)) s.send_message(args.msg) s.quit() elif (args.globus_server_name == 'petrel'): # # see https://globus-sdk-python.readthedocs.io/en/stable/tutorial/#step-1-get-a-client # # to create your project app_id. Once is set put it in globus.config app-id field ac, tc = globus.create_clients(args) log.info('Creating user directories on server %s:%s' % (args.globus_server_uuid, args.globus_server_top_dir)) # try to create the directories to share on the globus server in case after the globus init the pi last name was manually changed globus.create_globus_dir(args, ac, tc) new_dir = args.year_month + '/' + args.pi_last_name for email in emails: args.pi_email = email log.warning('Sharing %s%s with %s' % (args.globus_server_top_dir, new_dir, args.pi_email)) globus.share_globus_dir(args, ac, tc) else: log.error("%s is not a supported globus server" % args.globus_server_name)
def list_users(args): '''Lists the users on the current experiment in a nice format. ''' log.info('Listing the users on the DM experiment') exp_name = directories.make_directory_name(args) try: exp_obj = exp_api.getExperimentByName(exp_name) except: log.error(' No appropriate DM experiment found.') return username_list = exp_obj['experimentUsernameList'] if len(username_list) == 0: log.info(' No users for this experiment') return for uname in username_list: user_obj = user_api.getUserByUsername(uname) log.info(' User {0:s}, badge {1:s} is on the DM experiment'.format( make_pretty_user_name(user_obj), user_obj['badge']))
def list_users_this_dm_exp(args): '''Provide a list of user names for this DM expt in the form "d(badge#)" ''' log.info('Listing the users on the DM experiment') exp_name = directories.make_directory_name(args) try: exp_obj = exp_api.getExperimentByName(exp_name) except: log.error(' No appropriate DM experiment found.') return None username_list = exp_obj['experimentUsernameList'] if len(username_list) == 0: log.info(' No users for this experiment') return None else: print(username_list) return username_list
def check_local_directory(remote_server, remote_dir): '''Check if a directory exists on the analysis or on the detector computers. These computers are generally located in the same local network at the beamline. ''' try: rcmd = 'ls ' + remote_dir # rcmd is the command used to check if the remote directory exists subprocess.check_call(['ssh', remote_server, rcmd], stderr=open(os.devnull, 'wb'), stdout=open(os.devnull, 'wb')) log.warning(' *** remote directory %s exists' % (remote_dir)) return 0 except subprocess.CalledProcessError as e: # log.info(' *** return code = %d' % (e.returncode)) log.warning(' *** remote directory %s does not exist' % (remote_dir)) if e.returncode == 2: return e.returncode else: log.error(' *** Unknown error code returned: %d' % (e.returncode)) return -1
def start_daq(args): '''Starts the data managememnt (DM) data acquisition (DAQ) system. In this mode of operation, the DM system will monitor specified data directory for incoming files, and will transfer data automatically. Alternative is to upload files after experiment is done. ''' exp_name = directories.make_directory_name(args) analysis_dir_name = directories.create_analysis_dir_name(args) log.info('Check that the directory exists on the analysis machine') dir_check = directories.check_local_directory(args.analysis, analysis_dir_name) if dir_check == 2: log.info(' Need to make the analysis machine directory') mkdir_response = directories.create_local_directory( args.analysis, analysis_dir_name) if mkdir_response: log.error( ' Unknown response when creating analysis machine directory. Exiting' ) return elif dir_check == 0: log.info(' Directory already exists') else: log.warning( ' Unknown response when checking for analysis machine directory. Exiting' ) return dm_dir_name = "@{0:s}:{1:s}".format(args.analysis, analysis_dir_name) log.info('Check to make sure the appropriate DAQ is not already running.') current_daqs = daq_api.listDaqs() for d in current_daqs: if (d['experimentName'] == exp_name and d['status'] == 'running' and d['dataDirectory'] == dm_dir_name): log.warning(' DAQ is already running. Returning.') return log.info('Add a DAQ to experiment {:s}'.format(exp_name)) daq_obj = daq_api.startDaq(exp_name, dm_dir_name)
def remove_user(args): '''Remove a user from the DM experiment. ''' exp_name = directories.make_directory_name(args) dm_username = '******'.format(args.edit_user_badge) try: user_to_remove = user_api.getUserByUsername(dm_username) except: log.error( ' Problem retrieving user information. Check the badge number') return log.info('Removing user {0:s} from experiment {1:s}'.format( make_pretty_user_name(user_to_remove), exp_name)) try: exp_obj = exp_api.getExperimentByName(exp_name) except: log.error(' No appropriate DM experiment found.') return try: user_api.deleteUserExperimentRole(dm_username, 'User', exp_name) except: log.error(' Problem removing the user. Check the badge number')
def refresh_globus_token(args): """ Create and save a globus token. The token is valid for 48h. Parameters ---------- globus_app_id : App UUID """ try: token_response = np.load(args.globus_token_file, allow_pickle='TRUE').item() except FileNotFoundError: log.error('Globus token is missing. Creating one') # Creating new token # -------------------------------------------- globus_app_id = args.globus_app_uuid client = globus_sdk.NativeAppAuthClient(globus_app_id) client.oauth2_start_flow(refresh_tokens=True) log.warning('Please go to this URL and login: {0}'.format( client.oauth2_get_authorize_url())) get_input = getattr(__builtins__, 'raw_input', input) auth_code = get_input( 'Please enter the code you get after login here: ').strip( ) # pythn 3 # auth_code = raw_input('Please enter the code you get after login here: ').strip() # python 2.7 token_response = client.oauth2_exchange_code_for_tokens(auth_code) # -------------------------------------------- np.save(args.globus_token_file, token_response) # let's get stuff for the Globus Transfer service globus_transfer_data = token_response.by_resource_server[ 'transfer.api.globus.org'] # the refresh token and access token, often abbr. as RT and AT transfer_rt = globus_transfer_data['refresh_token'] transfer_at = globus_transfer_data['access_token'] expires_at_s = globus_transfer_data['expires_at_seconds'] globus_token_life = expires_at_s - time.time() if (globus_token_life < 0): # Creating new token # -------------------------------------------- globus_app_id = args.globus_app_uuid client = globus_sdk.NativeAppAuthClient(globus_app_id) client.oauth2_start_flow(refresh_tokens=True) log.warning('Please go to this URL and login: {0}'.format( client.oauth2_get_authorize_url())) get_input = getattr(__builtins__, 'raw_input', input) auth_code = get_input( 'Please enter the code you get after login here: ').strip( ) # pythn 3 # auth_code = raw_input('Please enter the code you get after login here: ').strip() # python 2.7 token_response = client.oauth2_exchange_code_for_tokens(auth_code) # -------------------------------------------- np.save(args.globus_token_file, token_response) return token_response