</div>
</div>
+ {% if current_user and current_user.has_perm("builders") %}
+ <a class="warning button expanded" href="/builders/{{ builder.hostname }}/edit">
+ {{ _("Edit") }}
+ </a>
+ {% end %}
+
<!-- XXX add some realtime graph -->
{% if builder.active_jobs %}
{% extends "../base.html" %}
-{% block title %}{{ _("Manage builder %s") % builder.hostname }}{% end block %}
+{% block title %}{{ _("Edit Builder %s") % builder }}{% end block %}
-{% block body %}
- <div class="row">
- <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
- <nav aria-label="breadcrumb" role="navigation">
- <ol class="breadcrumb">
- <li class="breadcrumb-item"><a href="/">{{ _("Home") }}</a></li>
- <li class="breadcrumb-item"><a href="/builders">{{ _("Builders") }}</a></li>
- <li class="breadcrumb-item"><a href="/builders/{{ builder.name }}">{{ builder.name }}</a></li>
- <li class="breadcrumb-item active">
- <a href="/builders/{{ builder.name }}/edit">{{ _("Manage") }}</a>
- </li>
- </ol>
- </nav>
- </div>
- </div>
+{% block container %}
+ <nav aria-label="{{ _("You are here:") }}" role="navigation">
+ <ul class="breadcrumbs">
+ <li>
+ <a href="/">{{ _("Home") }}</a>
+ </li>
+ <li>
+ <a href="/builders">{{ _("Builders") }}</a>
+ </li>
+ <li>
+ <a href="/builders/{{ builder.hostname }}">{{ builder }}</a>
+ </li>
+ <li>
+ <span class="show-for-sr">{{ _("Current") }}: </span> {{ _("Edit") }}
+ </li>
+ </ul>
+ </nav>
- <div class="row">
- <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
- <h2 style="word-wrap: break-word;">
- {{ _("Manage builder: %s") % builder.hostname }}
- </h2>
- </div>
- </div>
+ <div class="grid-x grid-padding-x">
+ <div class="cell large-6 float-center">
+ <form method="POST" action="">
+ <div class="callout">
+ {% raw xsrf_form_html() %}
+ {# Hostname #}
+ <label>
+ {{ _("Hostname") }}
+ <input type="text" name="hostname" value="{{ builder.hostname }}"
+ aria-describedby="hostname-help" disabled>
+ </label>
+ <p class="help-text" id="hostname-help">
+ {{ _("The hostname cannot be changed") }}
+ </p>
- <div class="row">
- <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
- <form method="POST" action="">
- {% raw xsrf_form_html() %}
- <fieldset>
- <div class="form-group">
- <label for="name">{{ _("Hostname") }}</label>
- <input type="text" class="form-control" id="name" name="name"
- aria-describedby="nameHelp" value="{{ builder.hostname }}" disabled>
- <small id="nameHelp" class="form-text text-muted">
- {{ _("The hostname cannot be changed.") }}
- </small>
- </div>
+ {# Status #}
+ <input type="checkbox" name="enabled" id="enabled"
+ {% if builder.enabled %}checked{% end %}>
+ <label for="enabled">{{ _("Enabled") }}</label>
- <div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" id="enabled" name="enabled"
- aria-describedby="enabledHelp" {% if builder.enabled %}checked{% end %}>
- {{ _("Enabled") }}
- </label>
- <small id="enabledHelp" class="form-text text-muted">
- {{ _("The builder must be enabled in order to process build jobs.") }}
- </small>
- </div>
- </fieldset>
+ <fieldset>
+ <legend>{{ _("Job Settings") }}</legend>
- <fieldset>
- <legend>{{ _("Build job settings") }}</legend>
- <div class="form-group">
- <label for="max_jobs">{{ _("Maximum number of parallel build jobs") }}</label>
- <select class="form-control" id="max_jobs" name="max_jobs" aria-describedby="max_jobsHelp">
- {% for i in range(1, (2 * builder.cpu_count) + 1) %}
- <option value="{{ i }}" {% if i == builder.max_jobs %}selected="selected"{% end %}>{{ i }}</option>
- {% end %}
- </select>
- <small id="max_jobsHelp" class="form-text text-muted">
- {{ _("This is the number of build jobs that are started in parallel.") }}
- </small>
- </div>
- <div class="form-check">
- <label class="form-check-label">
- <input class="form-check-input" type="checkbox" name="testmode"
- aria-describedby="testmodeHelp" {%if builder.testmode %}checked{% end %}>
- {{ _("Test Mode") }}
+ {# Build Jobs #}
+ <label>
+ {{ _("Maximum Parallel Build Jobs") }}
+ <input type="number" name="max_jobs" value="{{ builder.max_jobs }}"
+ min="1" {% if builder.cpu_count %}max="{{ builder.cpu_count * 4 }}"{% end %}
+ required>
</label>
- </div>
- </fieldset>
- <button type="submit" class="btn btn-primary">{{ _("Save changes") }}</button>
- <a class="btn" href="/builders/{{ builder.name }}">{{ _("Cancel") }}</a>
+ {# Test Mode #}
+ <input type="checkbox" name="testmode" id="testmode"
+ {% if builder.testmode %}checked{% end %}
+ aria-describedby="testmode-help">
+ <label for="testmode">{{ _("Enable Test Mode") }}</label>
+ <p class="help-text" id="testmode-help">
+ {{ _("Only build test jobs on this builder") }}
+ </p>
+ </fieldset>
+ </div>
+
+ <button class="success button expanded" type="submit">{{ _("Save") }}</button>
+
+ <a class="small danger button expanded" href="/builders/{{ builder.hostname }}/delete">
+ {{ _("Delete") }}
+ </a>
</form>
</div>
</div>
# Builders
(r"/builders", builders.BuilderListHandler),
(r"/builders/new", builders.BuilderNewHandler),
- (r"/builders/([A-Za-z0-9\-\.]+)/enable", builders.BuilderEnableHander),
- (r"/builders/([A-Za-z0-9\-\.]+)/disable", builders.BuilderDisableHander),
(r"/builders/([A-Za-z0-9\-\.]+)/delete", builders.BuilderDeleteHandler),
(r"/builders/([A-Za-z0-9\-\.]+)/edit", builders.BuilderEditHandler),
(r"/builders/([A-Za-z0-9\-\.]+)/renew", builders.BuilderRenewPassphraseHandler),
(r"/builders/([A-Za-z0-9\-\.]+)", builders.BuilderDetailHandler),
- (r"/builder/([A-Za-z0-9\-\.]+)", builders.RedirectHandler),
# Distributions
(r"/distros", distributions.DistributionListHandler),
self.render(error_document, status_code=status_code,
status_message=status_message, exc_info=exc_info, tb=tb, **kwargs)
+
+ # Typed Arguments
+
+ def get_argument_int(self, *args, **kwargs):
+ arg = self.get_argument(*args, **kwargs)
+
+ try:
+ return int(arg)
+ except (TypeError, ValueError):
+ raise tornado.web.HTTPError(400, "%s is not an integer" % arg)
self.render("builders/detail.html", builder=builder, log=log)
- @tornado.web.authenticated
- def post(self, hostname):
- if not self.current_user.has_perm("maintain_mirrors"):
- raise tornado.web.HTTPError(403, "User is not allowed to do this.")
-
- builder = self.backend.builders.get_by_name(hostname)
-
- with self.db.transaction():
- builder.description = self.get_argument("description", None)
-
- self.redirect("/builders/%s" % builder.hostname)
-
class BuilderNewHandler(base.BaseHandler):
def get(self):
raise tornado.web.HTTPError(404, "Builder not found: %s" % hostname)
# Check for sufficient right to edit things.
- if not self.current_user.has_perm("maintain_builders"):
+ if not self.current_user.has_perm("builders"):
raise tornado.web.HTTPError(403)
with self.db.transaction():
builder.enabled = self.get_argument("enabled", False)
- builder.testmode = self.get_argument("testmode", True)
-
- # Save max_jobs.
- max_jobs = self.get_argument("max_jobs", builder.max_jobs)
- try:
- max_jobs = int(max_jobs)
- except TypeError:
- max_jobs = 1
-
- if not max_jobs in range(1, 100):
- max_jobs = 1
- builder.max_jobs = max_jobs
+ builder.testmode = self.get_argument("testmode", False)
+ builder.max_jobs = self.get_argument_int("max_jobs")
self.redirect("/builders/%s" % builder.hostname)
raise tornado.web.HTTPError(404, "Builder not found: %s" % name)
# Check for sufficient right to delete this builder.
- if not self.current_user.has_perm("maintain_builders"):
+ if not self.current_user.has_perm("builders"):
raise tornado.web.HTTPError(403)
confirmed = self.get_argument("confirmed", None)
return
self.render("builders/delete.html", builder=builder)
-
-
-class BuilderStatusChangeHandler(base.BaseHandler):
- enabled = None
-
- @tornado.web.authenticated
- def get(self, hostname):
- builder = self.backend.builders.get_by_name(hostname)
- if not builder:
- raise tornado.web.HTTPError(404, "Builder not found: %s" % hostname)
-
- # Check for sufficient right to edit things.
- if self.current_user.has_perm("maintain_builders"):
- with self.db.transaction():
- builder.enabled = self.enabled
-
- self.redirect("/builders/%s" % builder.name)
-
-
-class BuilderEnableHander(BuilderStatusChangeHandler):
- enabled = True
-
-
-class BuilderDisableHander(BuilderStatusChangeHandler):
- enabled = False
-
-
-class RedirectHandler(base.BaseHandler):
- def get(self, hostname):
- self.redirect("/builders/%s" % hostname, permanent=True)