def view_client(request, client_id): """ View details about a client, along with some a list of paginated jobs it has run """ client = get_object_or_404(models.Client, pk=client_id) allowed = Permissions.is_allowed_to_see_clients(request.session) if not allowed: return render(request, 'ci/client.html', { 'client': None, 'allowed': False }) jobs_list = models.Job.objects.filter( client=client).order_by('-last_modified').select_related( 'config', 'event__pull_request', 'event__base__branch__repository__user', 'event__head__branch__repository__user', 'recipe', ) jobs = get_paginated(request, jobs_list) return render(request, 'ci/client.html', { 'client': client, 'jobs': jobs, 'allowed': True })
def cronjobs(request): # TODO: make this check for permission to view cron stuff instead allowed = Permissions.is_allowed_to_see_clients(request.session) if not allowed: return render(request, 'ci/cronjobs.html', { 'recipes': None, 'allowed': False }) recipe_list = models.Recipe.objects.filter( active=True, current=True, scheduler__isnull=False, branch__isnull=False).exclude(scheduler="") local_tz = pytz.timezone('US/Mountain') for r in recipe_list: event_list = (EventsStatus.get_default_events_query().filter( jobs__recipe__filename=r.filename, jobs__recipe__cause=r.cause)) events = get_paginated(request, event_list) evs_info = EventsStatus.multiline_events_info(events) r.most_recent_event = evs_info[0]['id'] if len(evs_info) > 0 else None c = croniter(r.scheduler, start_time=r.last_scheduled.astimezone(local_tz)) r.next_run_time = c.get_next(datetime) # TODO: augment recipes objects with fields that html template will need. data = { 'recipes': recipe_list, 'allowed': True, 'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL, } return render(request, 'ci/cronjobs.html', data)
def client_list(request): allowed = Permissions.is_allowed_to_see_clients(request.session) if not allowed: return render(request, 'ci/clients.html', {'clients': None, 'allowed': False}) client_list = clients_info() data = {'clients': client_list, 'allowed': True, 'update_interval': settings.HOME_PAGE_UPDATE_INTERVAL, } return render(request, 'ci/clients.html', data)
def clients_update(request): """ Get the updates for the clients page. """ allowed = Permissions.is_allowed_to_see_clients(request.session) if not allowed: return HttpResponseBadRequest('Not allowed') clients = views.clients_info() return JsonResponse({ 'clients': clients })
def manual_cron(request, recipe_id): allowed = Permissions.is_allowed_to_see_clients(request.session) if not allowed: return HttpResponseForbidden('Not allowed to start manual cron runs') r = get_object_or_404(models.Recipe, pk=recipe_id) user = r.build_user branch = r.branch latest = user.api().last_sha(branch.repository.user.name, branch.repository.name, branch.name) #likely need to add exception checks for this! if latest: r.last_scheduled = datetime.now(tz=pytz.UTC); r.save(); mev = ManualEvent.ManualEvent(user, branch, latest, "", recipe=r); mev.force = True; mev.save(update_branch_status=True); return redirect('ci:cronjobs')
def job_results(request): """ Returns the job results and job info in JSON. GET parameters: job_id: The pk of the job last_request: A timestamp of when client last requested this information. If the job hasn't been updated since that time we don't have to send as much information. """ if 'last_request' not in request.GET or 'job_id' not in request.GET: return HttpResponseBadRequest('Missing parameters') this_request = TimeUtils.get_local_timestamp() job_id = int(request.GET['job_id']) last_request = int(float(request.GET['last_request'])) # in case it has decimals dt = timezone.localtime(timezone.make_aware(datetime.datetime.utcfromtimestamp(last_request))) job = get_object_or_404(models.Job.objects.select_related("recipe", "client").prefetch_related("step_results"), pk=job_id) if not Permissions.can_see_results(request.session, job.recipe): return HttpResponseForbidden("Can't see results") job_info = { 'id': job.pk, 'complete': job.complete, 'status': job.status_slug(), 'runtime': str(job.seconds), 'ready': job.ready, 'invalidated': job.invalidated, 'active': job.active, 'last_modified': TimeUtils.display_time_str(job.last_modified), 'created': TimeUtils.display_time_str(job.created), 'client_name': '', 'client_url': '', 'recipe_repo_sha': job.recipe_repo_sha[:6], 'recipe_sha': job.recipe.filename_sha[:6], } if job.last_modified < dt: # always return the basic info since we need to update the # "natural" time return JsonResponse({'job_info': job_info, 'results': [], 'last_request': this_request}) if job.client: can_see_client = Permissions.is_allowed_to_see_clients(request.session) if can_see_client: job_info['client_name'] = job.client.name job_info['client_url'] = reverse('ci:view_client', args=[job.client.pk,]) result_info = [] for result in job.step_results.all(): if dt > result.last_modified: continue exit_status = '' if result.complete: exit_status = result.exit_status info = {'id': result.id, 'name': result.name, 'runtime': str(result.seconds), 'exit_status': exit_status, 'output': result.clean_output(), 'status': result.status_slug(), 'running': result.status != models.JobStatus.NOT_STARTED, 'complete': result.complete, 'output_size': result.output_size(), } result_info.append(info) return JsonResponse({'job_info': job_info, 'results': result_info, 'last_request': this_request})