def node_detail(request, nodename=None): # TODO: # co dalsiho by u uzlu mohlo byt? # formular na vyber je tradicne vlevo a mohl by obsahovat zatrhavaci # cudliky, kde se voli, jake detaily o uzlu clovek chce videt # bylo by fajn, mit moznost definovat obecne linky do jinych systemu # hezky by byl i histogram startovani a ukoncovani uloh # pripadne graf toho jakymi ulohami se uzel zaobiral poslednich X hodin node_form = NodeDetailForm() if not request.POST and not nodename: return render_to_response_with_config('trqacc/node_detail.html', {'node':None, 'node_form':node_form}) if nodename: n = Node.objects.get(name=nodename) if request.POST.has_key('node'): n = Node.objects.get(pk=request.POST['node']) node_form.data['node'] = n.pk node_form.is_bound = True running_jobs = Job.objects.filter(jobslots__node=n, job_state__shortname="R") updated_running_jobs = [] for rj in running_jobs: if UpdateRunningJob(rj): rj = Job.objects.get(pk=rj.pk) updated_running_jobs.append(rj) return render_to_response_with_config('trqacc/node_detail.html', {'node':n, 'running_jobs': updated_running_jobs, 'node_form':node_form } )
def job_detail(request, servername=None, jobid=None): select_form = JobSelectForm() if not request.POST and jobid==None: return render_to_response_with_config( 'trqacc/job_detail.html', {'select_form':select_form, 'unknownjob': False, 'job':None, 'accevents':[]} ) try: if request.POST: server = BatchServer.objects.get(pk=request.POST['server']) job = Job.objects.get(jobid=request.POST['jobid'], server=server) select_form.data['server'] = request.POST['server'] select_form.data['jobid'] = request.POST['jobid'] else: server = BatchServer.objects.get(name=servername) job = Job.objects.get(jobid=jobid, server=server) select_form.data['server'] = server.pk select_form.data['jobid'] = jobid select_form.is_bound = True except Job.DoesNotExist: return render_to_response_with_config( 'trqacc/job_detail.html', {'select_form':select_form, 'unknownjob': True, 'job':None, 'accevents':[]} ) if job.job_state.shortname=='R': UpdateRunningJob(job) accevents = AccountingEvent.objects.filter(job=job) return render_to_response_with_config( 'trqacc/job_detail.html', {'select_form':select_form, 'unknownjob': False, 'job':job, 'accevents':accevents} )
def suspicious(request): """ Get lists of suspicious jobs (various reasons) and render page with them. """ sf = SuspicionForm() if not request.POST: return render_to_response_with_config( 'trqacc/jobs_suspicious.html', {'suspicion_form':sf, 'jobs_page':None, 'paginator':None} ) current_date = datetime.date.today() jobs = [] for j in Job.objects.filter(job_state=getJobState('R')): if wl.isProblem(j): jobs.append(j) sf.data['page'] = request.POST['page'] if request.POST['submit']=='>>': sf.data['page'] = int(sf.data['page']) + 1 elif request.POST['submit']=='<<': sf.data['page'] = int(sf.data['page']) - 1 page = int(sf.data['page']) paginator = Paginator(jobs, 50) if page>paginator.num_pages: page=1 jobs_page = paginator.page(page) return render_to_response_with_config( 'trqacc/jobs_suspicious.html', {'suspicion_form':sf, 'jobs_page':jobs_page, 'paginator':paginator} )
def jobs_running(request): run_form = RunningForm() if not request.POST: return render_to_response_with_config( 'trqacc/jobs_running.html', {'jobs_page':[], 'paginator':None, 'run_form':run_form} ) run_form.data['momentdate'] = request.POST['momentdate'] run_form.data['momenttime'] = request.POST['momenttime'] run_form.data['queue'] = request.POST['queue'] run_form.data['user'] = request.POST['user'] run_form.data['group'] = request.POST['group'] run_form.data['griduser'] = request.POST['griduser'] run_form.data['node'] = request.POST['node'] run_form.data['page'] = request.POST['page'] if request.POST['submit']=='>>': run_form.data['page'] = int(run_form.data['page']) + 1 elif request.POST['submit']=='<<': run_form.data['page'] = int(run_form.data['page']) - 1 run_form.is_bound = True args = { 'start_time__lte':run_form.data['momentdate'], 'comp_time__gte':run_form.data['momentdate'] } if run_form.data['queue'] != '0': args['queue__pk'] = run_form.data['queue'] if run_form.data['user'] != '0': args['job_owner__pk'] = run_form.data['user'] if run_form.data['group'] != '0': args['job_owner__group__pk'] = run_form.data['group'] if run_form.data['griduser'] != '0': args['job_gridowner__pk'] = run_form.data['griduser'] if run_form.data['node'] != '0': args['jobslots__node__pk'] = run_form.data['node'] object_list1 = Job.objects.filter(**args) args.pop('comp_time__gte') args['job_state__pk'] = getJobState('R').pk object_list2 = Job.objects.filter(**args) object_list = object_list1|object_list2 page = int(run_form.data['page']) paginator = Paginator(object_list, 50) if page>paginator.num_pages: page=1 jobs_page = paginator.page(page) return render_to_response_with_config( 'trqacc/jobs_running.html', {'jobs_page':jobs_page, 'paginator':paginator, 'run_form':run_form} )
def group_detail(request, groupname=None): group_form = GroupSelectForm() summary = [] if not request.POST and not groupname: detailgroup = None elif groupname: detailgroup = Group.objects.get(name=groupname) elif request.POST.has_key('user'): detailgroup = Group.objects.get(pk=request.POST['user']) if detailgroup: group_form.data['user'] = detailgroup.pk group_form.is_bound = True if request.POST and request.POST.has_key('summary'): group_form.data['summary'] = request.POST['summary'] group_form.is_bound = True if request.POST['summary']: summary = create_summary({'job_owner__group': detailgroup}) return render_to_response_with_config( 'trqacc/user_detail.html', {'user':detailgroup, 'user_form':group_form, 'summary':summary} )
def users_overview(request): users = User.objects.all() job_states = JobState.objects.all() return render_to_response_with_config( 'trqacc/users_overview.html', {'users_list':users, 'job_states':job_states} )
def user_detail(request, servername=None, username=None): user_form = UserSelectForm() summary = [] if not request.POST and not username: detailuser = None elif request.POST.has_key('user'): detailuser = User.objects.get(pk=request.POST['user']) elif username: detailuser = User.objects.get(name=username, server__name=servername) if detailuser: user_form.data['user'] = detailuser.pk user_form.is_bound = True if request.POST and request.POST.has_key('summary'): user_form.data['summary'] = request.POST['summary'] user_form.is_bound = True if request.POST['summary']: summary = create_summary({'job_owner': detailuser}) return render_to_response_with_config( 'trqacc/user_detail.html', {'user':detailuser, 'user_form':user_form, 'summary':summary} )
def overview(request): info = [] for c in (BatchServer, Node, SubCluster, NodeProperty, User, Queue, Job, SubmitHost): item = {} item['name'] = c.get_overview_name() item['count'] = c.objects.all().count() item['url'] = c.get_overview_url() info.append(item) tsdata = {} # for ts in BatchServer.objects.all(): # tsdata[ts] = {'queues':[],'starttime':0,'endtime':0} # qdb=Queue.objects.filter(server=ts) # for q in qdb: # numsq = Job.objects.filter(queue=q,job_state__shortname='Q').count() # numsr = Job.objects.filter(queue=q,job_state__shortname='R').count() # tsdata[ts]['queues'].append( # {'queue':q,'Q':numsq,'R':numsr} # ) # try: # tsdata[ts]['starttime'] = Job.objects.filter(job_state=getJobState('C')).order_by('comp_time').filter(server=ts)[0].comp_time # tsdata[ts]['endtime'] = Job.objects.filter(job_state=getJobState('C')).order_by('-comp_time').filter(server=ts)[0].comp_time # except IndexError: # pass return render_to_response_with_config( 'trqacc/overview.html', { 'info': info, 'tsdata' : tsdata } )
def report_form(request): """ View form for reporting job data. This report is than returned as html or pdf. """ return render_to_response_with_config( 'trqacc/jobs_report_form.html', {} )
def queue_detail(request, servername=None, queuename=None): queue_form = QueueSelectForm() queue = None if queuename and servername: queue = Queue.objects.get(name=queuename, server__name=servername) if request.POST.has_key('queue'): queue = Queue.objects.get(pk=request.POST['queue']) if not queue: return render_to_response_with_config( 'trqacc/queue_detail.html', {'queue':None, 'queue_form':queue_form} ) queue_form.data['queue'] = queue.pk queue_form.is_bound = True running_jobs = Job.objects.filter(queue=queue, job_state__shortname="R") return render_to_response_with_config( 'trqacc/queue_detail.html', {'queue':queue, 'running_jobs':running_jobs, 'queue_form':queue_form} )
def queues_overview(request): servers_name = BatchServer.objects.all().values_list('name') job_states_name = JobState.objects.all().values_list('name') restable = {} for sn in servers_name: restable[sn[0]] = {} queues_name = Queue.objects.filter(server__name=sn[0]).values_list('name') for qn in queues_name: restable[sn[0]][qn[0]] = {} for jsn in job_states_name: restable[sn[0]][qn[0]][jsn[0]] = 0 queue_results = Job.objects.all().values('server__name', 'queue__name','job_state__name').annotate(Count('job_state')) for qr in queue_results: restable[qr['server__name']][qr['queue__name']][qr['job_state__name']] += qr['job_state__count'] return render_to_response_with_config( 'trqacc/queues_overview.html', {'restable':restable } )
def stats(request): jobs = dfrom = dto = None if request.POST: if request.POST.has_key('wfrom'): dfrom = request.POST['wfrom'] if request.POST.has_key('wto'): dto = request.POST['wto'] jobs=[] graph_data = {} if dfrom and dto: jobs=Job.objects.filter(start_time__gte=dfrom, comp_time__lte=dto) for q in Queue.objects.all().order_by('name'): graph_data[q.name] = jobs.filter(queue=q).count() query_form = JobsStatsForm() if request.POST: query_form.data['wfrom'] = request.POST['wfrom'] query_form.data['wto'] = request.POST['wto'] query_form.is_bound = True return render_to_response_with_config( 'trqacc/jobs_stats.html', {'query_form':query_form, 'jobs':jobs, 'graph_data':graph_data} )
def nodes_table(request, nodename=None): # Tabulka vsech uzlu s graficky naznacenim v jakem stavu jsou # z pohledu torque a jak moc jsou zaplnene joby. # Pri najeti mysi by se mel ukazat detail uzlu - nejlepe # v leve "formularove" oblasti - seznam bezicich jobu na uzlu (max s frontou). # nodes = Node.objects.all().order_by('subcluster__name', 'name') node_form = NodeSelectForm() if not request.POST and not nodename: detailnode = None elif nodename: detailnode = Node.objects.get(name=nodename) elif request.POST.has_key('node'): detailnode = Node.objects.get(pk=request.POST['node']) if detailnode: node_form.data['node'] = detailnode.pk node_form.is_bound = True cols = 6 sc = SubCluster.objects.all() sc_nodes = [] for s in sc: sn = { 'subcluster': s, 'rows' : [] } nodes = Node.objects.filter(subcluster=s) i = 0 while i<len(nodes): sn['rows'].append(nodes[i:i+cols]) i = i + cols sn['rows'][-1].extend([None]*(i-len(nodes))) sc_nodes.append(sn) nodestates = NodeState.objects.all().order_by('name') return render_to_response_with_config( 'trqacc/nodes_table.html', {'sc_nodes':sc_nodes, 'nodestates':nodestates, 'colswidth':cols, 'detailnode':detailnode, 'detailform':node_form} )
def queues_stats(request): stat_form = QueuesStatsForm() queues_form = forms.Form() for ts in BatchServer.objects.all(): ch = [] for q in Queue.objects.filter(server=ts).order_by('name'): ch.append(('queue_'+str(q.pk),q.name)) queues_form.fields['server_'+str(ts.pk)] = forms.MultipleChoiceField( choices=ch, label=ts.name, widget=forms.SelectMultiple(attrs={'class':'dropdown_qlist'})) queues_form.is_bound = True if request.POST: stat_form.data['graph_type'] = request.POST['graph_type'] stat_form.data['wfrom'] = request.POST['wfrom'] stat_form.data['wto'] = request.POST['wto'] stat_form.data['aggregation'] = request.POST['aggregation'] stat_form.data['data_type'] = request.POST['data_type'] stat_form.is_bound = True for ts in BatchServer.objects.all(): if request.POST.has_key('server_'+str(ts.pk)): queues_form.data['server_'+str(ts.pk)] = request.POST.getlist('server_'+str(ts.pk)) queues_form.is_bound = True graph_data = False graph_values = False if request.POST: graph_data = request.POST graph_values = get_graph_values(graph_data) return render_to_response_with_config( 'trqacc/queues_stats.html', {'stat_form':stat_form, 'queues_form':queues_form, 'graph_data':graph_data, 'graph_values':graph_values} )
def griduser_detail(request, gridusername=None): griduser_form = GridUserSelectForm() summary = [] if not request.POST and not gridusername: detailuser = None elif gridusername: detailuser = GridUser.objects.get(dn=gridusername) elif request.POST.has_key('user'): detailuser = GridUser.objects.get(pk=request.POST['user']) if detailuser: griduser_form.data['user'] = detailuser.pk griduser_form.is_bound = True if request.POST and request.POST.has_key('summary'): griduser_form.data['summary'] = request.POST['summary'] griduser_form.is_bound = True if request.POST['summary']: summary = create_summary({'job_gridowner': detailuser}) return render_to_response_with_config( 'trqacc/user_detail.html', {'user':detailuser, 'user_form':griduser_form, 'summary':summary} )
def index(request): return render_to_response_with_config('trqacc/index.html', {})
def jobs_completed_listing(request): comp_form = CompletedForm() if not request.POST: return render_to_response_with_config( 'trqacc/jobs_completed_listing.html', {'jobs_page':[], 'paginator':None, 'comp_form':comp_form} ) comp_form.data['wfrom'] = request.POST['wfrom'] comp_form.data['wto'] = request.POST['wto'] comp_form.data['mineff'] = request.POST['mineff'] comp_form.data['maxeff'] = request.POST['maxeff'] comp_form.data['minwalltime'] = request.POST['minwalltime'] comp_form.data['mincput'] = request.POST['mincput'] comp_form.data['queue'] = request.POST['queue'] comp_form.data['user'] = request.POST['user'] comp_form.data['group'] = request.POST['group'] comp_form.data['griduser'] = request.POST['griduser'] comp_form.data['node'] = request.POST['node'] comp_form.data['submithost'] = request.POST['submithost'] comp_form.data['exitstatus'] = request.POST['exitstatus'] comp_form.data['job_state'] = request.POST['job_state'] comp_form.data['page'] = request.POST['page'] if request.POST['submit']=='>>': comp_form.data['page'] = int(comp_form.data['page']) + 1 elif request.POST['submit']=='<<': comp_form.data['page'] = int(comp_form.data['page']) - 1 comp_form.is_bound = True args = { 'job_state__shortname':'C', 'comp_time__range':(comp_form.data['wfrom'], comp_form.data['wto']), 'efficiency__range':(comp_form.data['mineff'], comp_form.data['maxeff']), 'walltime__gte':comp_form.data['minwalltime'], 'cput__gte':comp_form.data['mincput'] } if comp_form.data['queue'] != '0': args['queue__pk'] = comp_form.data['queue'] if comp_form.data['user'] != '0': args['job_owner__pk'] = comp_form.data['user'] if comp_form.data['group'] != '0': args['job_owner__group__pk'] = comp_form.data['group'] if comp_form.data['griduser'] != '0': args['job_gridowner__pk'] = comp_form.data['griduser'] if comp_form.data['node'] != '0': args['jobslots__node__pk'] = comp_form.data['node'] if comp_form.data['submithost'] != '0': args['submithost__pk'] = comp_form.data['submithost'] if comp_form.data['exitstatus'] == '1': args['exit_status__exact'] = 0 elif comp_form.data['exitstatus'] == '2': args['exit_status__gt'] = 0 if comp_form.data['job_state'] != '0': args['job_state__pk'] = comp_form.data['job_state'] object_list = Job.objects.filter(**args) page = int(comp_form.data['page']) paginator = Paginator(object_list, 50) if page>paginator.num_pages: page=1 jobs_page = paginator.page(page) return render_to_response_with_config( 'trqacc/jobs_completed_listing.html', {'jobs_page':jobs_page, 'paginator':paginator, 'comp_form':comp_form} )
def fairshare(request): """ View info about total used walltime and cputime. Compare it with walltime/cputime per entity (queue, unix group, unix user). """ fs_form = FairshareForm() if not request.POST: return render_to_response_with_config( 'trqacc/jobs_fairshare.html', {'fs_form':fs_form} ) fs_form.data['timescale'] = request.POST['timescale'] fs_form.data['minutes'] = request.POST['minutes'] fs_form.data['entity'] = request.POST['entity'] fs_form.data['server'] = request.POST['server'] fs_form.is_bound = True minutes = int(request.POST['timescale']) if minutes == 0: minutes = int(request.POST['minutes']) endtime = datetime.datetime.now() starttime = datetime.datetime.fromtimestamp(int(endtime.strftime("%s"))-60*minutes) # Job.objects.filter(comp_time__range=("2010-01-01", "2010-01-02")).values('queue__name').annotate(Sum('walltime')) if request.POST['entity']=='0': # Queue entity_name = 'queue__name' entity_color = 'queue__color' elif request.POST['entity']=='1': # Group entity_name = 'job_owner__group__name' entity_color = 'job_owner__group__color' else: # request.POST['entity']=='2': # User entity_name = 'job_owner__name' entity_color = 'job_owner__color' result = [] total_sum = 0 for j in Job.objects.filter(server__pk=request.POST['server'], comp_time__range=(starttime, endtime)).values(entity_name, entity_color).annotate(Sum('walltime')): secs = int(j['walltime__sum']) tstr = "%d %d:%d:%d" % ((secs/86400), (secs/3600)%24, (secs/60)%60, secs%60) result.append({ 'entity_name':j[entity_name], 'walltime__sum':j['walltime__sum'], 'walltime__str':tstr, 'entity_color':j[entity_color] }) total_sum += int(j['walltime__sum']) # check color validity colors_valid = False for r in result: if r['entity_color']: colors_valid = True break if not colors_valid: i = 0 generated_colors = getColorArrayHTML(len(result)) for r in result: r['entity_color'] = generated_colors[i] i += 1 total_str = "%d %d:%d:%d" % ((total_sum/86400), (total_sum/3600)%24, (total_sum/60)%60, total_sum%60) total = {'entity_name':'total', 'walltime__sum':total_sum, 'walltime__str':total_str} for row in result: if total_sum==0: row['percentage'] = 0 else: row['percentage'] = 100*float(row['walltime__sum'])/total_sum return render_to_response_with_config( 'trqacc/jobs_fairshare.html', {'fs_form':fs_form, 'result':result, 'total':total} )
def personal(request): return render_to_response_with_config( 'trqacc/config_personal.html', { 'session': request.session } )
def nodes(request): return render_to_response_with_config('trqacc/nodes.html', {})
def nodes_listing(request, filtertype=None, filtervalue=None): # Podrobny seznam uzlu s formularem na vyber podmnozin podle # torque vlastnosti. if filtertype=="subcluster": nodes = Node.objects.filter(subcluster__name=filtervalue).distinct() elif filtertype=="property": nodes = Node.objects.filter(properties__name=filtervalue).distinct() elif request.POST: sc_list = [] prop_list = [] state_list = [] for key,val in request.POST.items(): prefix, attr = key.split("_", 1) if prefix == "subcluster": if 'on' in val: sc_list.append(attr) elif prefix == "properties": if 'on' in val: prop_list.append(attr) elif prefix == "nodestates": if 'on' in val: state_list.append(attr) nodes = Node.objects.filter( subcluster__name__in=sc_list, properties__name__in=prop_list, state__name__in=state_list ).distinct() else: nodes = Node.objects.all() subclusters2 = [(x.pk,x.name) for x in SubCluster.objects.all()] # subcluster2_form = forms.Form() subcluster2_form = BooleanListForm('subcluster') subcluster2_form.fields['subclusters'] = forms.MultipleChoiceField(choices=subclusters2, label='Subclusters', widget=forms.SelectMultiple(attrs={'class':'dropdown_qlist'})) subcluster2_form.is_bound = True properties2 = [(x.pk,x.name) for x in NodeProperty.objects.all()] # properties2_form = forms.Form() properties2_form = BooleanListForm('properties') properties2_form.fields['properties'] = forms.MultipleChoiceField(choices=properties2, label='Node properties', widget=forms.SelectMultiple(attrs={'class':'dropdown_qlist'})) properties2_form.is_bound = True states2 = [(x.pk,x.name) for x in NodeState.objects.all()] # states2_form = forms.Form() states2_form = BooleanListForm('states') states2_form.fields['states'] = forms.MultipleChoiceField(choices=states2, label='Node states', widget=forms.SelectMultiple(attrs={'class':'dropdown_qlist'})) states2_form.is_bound = True if filtertype=="subcluster": properties2_form.setData( dict(zip(properties, len(properties)*[True])) ) states2_form.setData( dict(zip(states, len(states)*[True])) ) subcluster2_form.setData( dict(zip(subclusters, len(subclusters)*[False])) ) subcluster2_form.data['subcluster_' + filtervalue] = True subcluster2_form.is_bound = True elif filtertype=="property": subcluster2_form.setData( dict(zip(subclusters, len(subclusters)*[True])) ) states2_form.setData( dict(zip(states, len(states)*[True])) ) properties2_form.setData( dict(zip(properties, len(properties)*[False])) ) properties2_form.data['properties_' + filtervalue] = True properties2_form.is_bound = True elif request.POST: subcluster2_form.setData(request.POST, useprefix=False) properties2_form.setData(request.POST, useprefix=False) states2_form.setData(request.POST, useprefix=False) else: print subcluster2_form subcluster2_form.setData( dict(zip(subclusters, len(subclusters)*[True])) ) properties2_form.setData( dict(zip(properties, len(properties)*[True])) ) states2_form.setData( dict(zip(states, len(states)*[True])) ) return render_to_response_with_config( 'trqacc/nodes_listing.html', {'nodes_list':nodes, 'subcluster2_form':subcluster2_form, 'properties2_form':properties2_form, 'states2_form':states2_form} )