Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions server/devel/create_sample_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@ def _server_validator(server: str) -> str:
"--queues",
type=int,
default=10,
help="Number of queues to create",
help="Number of queues to distribute amongst jobs and agents",
)

parser.add_argument(
"-d",
"--advertised-queues",
type=int,
default=1,
help="Number of advertised queues to create",
)

parser.add_argument(
Expand Down Expand Up @@ -112,7 +120,7 @@ def __iter__(self):
"state": random.choice(("waiting", "test", "provision")),
}
if self.queue_list:
agent_data["queues"] = [random.choice(self.queue_list)]
agent_data["queues"] = random.sample(self.queue_list, random.randint(1, len(self.queue_list)))
yield (f"{self.prefix}{agent_num}", agent_data)


Expand Down Expand Up @@ -241,7 +249,8 @@ def main():
testflinger_client = TestflingerClient(server_url=args.server)

queues = QueueDataGenerator(num_queues=args.queues)
testflinger_client.post_queue_data(queues=queues)
# configure "advertised" queues:
testflinger_client.post_queue_data(random.sample(tuple(queues), random.randint(1, args.advertised_queues)))
logging.info("Created %s queues", args.queues)

valid_queue_names = extract_queue_names(queues=queues)
Expand Down
124 changes: 69 additions & 55 deletions server/src/testflinger/templates/agent_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,72 +33,86 @@ <h1 class="p-heading--3">Agent Detail - {{ agent.name }}</h1>
</table>
<h2 class="p-muted-heading">Queues</h2>
<ul>
{% for queue in agent.queues %}
<li>
<a href="{{ url_for('testflinger.queue_detail', queue_name=queue) }}">{{ queue }}</a>
{% if agent.restricted_to[queue]|default([]) %}
<small>(restricted to: {{ agent.restricted_to[queue]|join(", ") }})</small>
{% endif %}
</li>
{% endfor %}
</ul>
<h2 class="p-muted-heading">Provision History</h2>
<form action="" method="get" class="p-form--inline">
<div class="p-form__group">
<label for="start-date" class="p-form__label">Start Date</label>
<input type="date"
id="start-date"
name="start"
class="p-form__control"
value="{{ request.args.get('start', agent.start) }}">
</div>
<div class="p-form__group">
<label for="stop-date" class="p-form__label">Stop Date</label>
<input type="date"
id="stop-date"
name="stop"
class="p-form__control"
value="{{ request.args.get('stop', agent.stop) }}">
</div>
<button type="submit" class="p-button--positive">Refresh</button>
</form>
<div>
<strong>Provision success rate for this range:</strong> {{ agent.provision_success_rate }}%
</div>
<div>
<table>
<table aria-label="Queues table" class="p-table--mobile-card">
<thead>
<tr>
<th style="width: 150pt">Finished At</th>
<th style="width: 300pt">Job ID</th>
<th class="p-table__cell--icon-placeholder" style="width: 75pt">Status</th>
<th>Detail</th>
<th>Name</th>
<th>Number of jobs</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for log in agent.provision_log|reverse %}
<tr>
<td>{{ log.timestamp.strftime("%Y-%m-%d %H:%M:%S") }}</td>
<td>
<a href="{{ url_for('testflinger.job_detail', job_id=log.job_id) }}">{{ log.job_id }}</a>
</td>
<td class="u-align--right p-table__cell--icon-placeholder">
<i class="{{ 'p-icon--success' if log.exit_code==0 else 'p-icon--error' }}"></i>{{ log.exit_code }}
{% for queue in agent.queues %}
<tr class="searchable-row">
<td data-heading="Name">
<a href="{{ url_for('testflinger.queue_detail', queue_name=queue.name) }}">{{ queue.name }}</a>
{% if agent.restricted_to[queue.name]|default([]) %}
<small>(restricted to: {{ agent.restricted_to[queue.name]|join(", ") }})</small>
{% endif %}
</td>
<td>{{ log.detail }}</td>
<td data-heading="Number of Unfinished Jobs">{{ queue.numjobs }}</td>
<td data-heading="Description">{{ queue.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 class="p-muted-heading">Agent Log</h2>
<div class="p-code-snippet">
<div class="scrollable">
<pre class="p-code-snippet__block">
</ul>
<h2 class="p-muted-heading">Provision History</h2>
<form action="" method="get" class="p-form--inline">
<div class="p-form__group">
<label for="start-date" class="p-form__label">Start Date</label>
<input type="date"
id="start-date"
name="start"
class="p-form__control"
value="{{ request.args.get('start', agent.start) }}">
</div>
<div class="p-form__group">
<label for="stop-date" class="p-form__label">Stop Date</label>
<input type="date"
id="stop-date"
name="stop"
class="p-form__control"
value="{{ request.args.get('stop', agent.stop) }}">
</div>
<button type="submit" class="p-button--positive">Refresh</button>
</form>
<div>
<strong>Provision success rate for this range:</strong> {{ agent.provision_success_rate }}%
</div>
<div>
<table>
<thead>
<tr>
<th style="width: 150pt">Finished At</th>
<th style="width: 300pt">Job ID</th>
<th class="p-table__cell--icon-placeholder" style="width: 75pt">Status</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
{% for log in agent.provision_log|reverse %}
<tr>
<td>{{ log.timestamp.strftime("%Y-%m-%d %H:%M:%S") }}</td>
<td>
<a href="{{ url_for('testflinger.job_detail', job_id=log.job_id) }}">{{ log.job_id }}</a>
</td>
<td class="u-align--right p-table__cell--icon-placeholder">
<i class="{{ 'p-icon--success' if log.exit_code==0 else 'p-icon--error' }}"></i>{{ log.exit_code }}
</td>
<td>{{ log.detail }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 class="p-muted-heading">Agent Log</h2>
<div class="p-code-snippet">
<div class="scrollable">
<pre class="p-code-snippet__block">
<code>
{{ agent.log|join('\n') }}
</code>
</pre>
</div>
</div>
</div>
{% endblock content %}
{% endblock content %}
19 changes: 19 additions & 0 deletions server/src/testflinger/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ def agent_detail(agent_id):
for queue in agent_info.get("queues", [])
}

queue_info = []
for queue_name in agent_info.pop("queues", []):
queue_data = mongo.db.queues.find_one({"name": queue_name})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just note that the queues collection only reports "advertised queues" which does not accurately reflect the queues available.

You can use testflinger-cli list-queues to take a look at what it is exposed in that collection in production...

So for this I would suggest to get the name of the queue directly from the agent_info

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated server/devel/create_sample_data.py to only add a select number of queues as advertised queues to help test this out.

if not queue_data:
# If it's not an advertised queue, create some dummy data
queue_data = {"description": "No description"}
queue_data["name"] = queue_name
queue_data["numjobs"] = mongo.db.jobs.count_documents(
{
"job_data.job_queue": queue_name,
"result_data.job_state": {
"$nin": ["complete", "completed", "cancelled"]
},
}
)
queue_info.append(queue_data)

agent_info["queues"] = queue_info

# We want to include the start/stop dates so that default values
# can be filled in for the date pickers
agent_info["start"] = start_date
Expand Down
Loading