Merge pull request #9172 from hashicorp/b-ui/logs-for-fails

UI: Always show the file browser for allocations and tasks.
This commit is contained in:
Michael Lange
2020-10-26 10:36:18 -07:00
committed by GitHub
5 changed files with 56 additions and 107 deletions

View File

@@ -7,12 +7,7 @@ export default class FsRoute extends Route {
const decodedPath = decodeURIComponent(path);
const allocation = this.modelFor('allocations.allocation');
if (!allocation.isRunning) {
return {
path: decodedPath,
allocation,
};
}
if (!allocation) return;
return RSVP.all([allocation.stat(decodedPath), allocation.get('node')])
.then(([statJson]) => {

View File

@@ -6,19 +6,14 @@ export default class FsRoute extends Route {
model({ path = '/' }) {
const decodedPath = decodeURIComponent(path);
const taskState = this.modelFor('allocations.allocation.task');
const allocation = taskState.allocation;
if (!taskState || !taskState.allocation) return;
const allocation = taskState.allocation;
const pathWithTaskName = `${taskState.name}${
decodedPath.startsWith('/') ? '' : '/'
}${decodedPath}`;
if (!taskState.isRunning) {
return {
path: decodedPath,
taskState,
};
}
return RSVP.all([allocation.stat(pathWithTaskName), taskState.get('allocation.node')])
.then(([statJson]) => {
if (statJson.IsDir) {

View File

@@ -1,47 +1,38 @@
<section class="section is-closer {{if this.isFile "is-full-width"}}">
{{#if this.model.isRunning}}
{{#if this.isFile}}
<Fs::File @allocation={{this.allocation}} @taskState={{this.taskState}} @file={{this.path}} @stat={{this.stat}} @class="fs-explorer">
<Fs::Breadcrumbs @allocation={{this.allocation}} @taskState={{this.taskState}} @path={{this.path}} />
</Fs::File>
{{else}}
<div class="fs-explorer boxed-section">
<div class="boxed-section-head">
<Fs::Breadcrumbs @allocation={{this.allocation}} @taskState={{this.taskState}} @path={{this.path}} />
</div>
{{#if this.directoryEntries}}
<ListTable
@source={{this.sortedDirectoryEntries}}
@sortProperty={{this.sortProperty}}
@sortDescending={{this.sortDescending}}
@class="boxed-section-body is-full-bleed is-compact" as |t|>
<t.head>
<t.sort-by @prop="Name" @class="is-two-thirds">Name</t.sort-by>
<t.sort-by @prop="Size" @class="has-text-right">File Size</t.sort-by>
<t.sort-by @prop="ModTime" @class="has-text-right">Last Modified</t.sort-by>
</t.head>
<t.body as |row|>
<Fs::DirectoryEntry @path={{this.path}} @allocation={{this.allocation}} @taskState={{this.taskState}} @entry={{row.model}} />
</t.body>
</ListTable>
{{else}}
<div class="boxed-section-body">
<div data-test-empty-directory class="empty-message">
<h3 data-test-empty-directory-headline class="empty-message-headline">No Files</h3>
<p data-test-empty-directory-body class="empty-message-body">
Directory is currently empty.
</p>
</div>
</div>
{{/if}}
</div>
{{/if}}
{{#if this.isFile}}
<Fs::File @allocation={{this.allocation}} @taskState={{this.taskState}} @file={{this.path}} @stat={{this.stat}} @class="fs-explorer">
<Fs::Breadcrumbs @allocation={{this.allocation}} @taskState={{this.taskState}} @path={{this.path}} />
</Fs::File>
{{else}}
<div data-test-not-running class="empty-message">
<h3 data-test-not-running-headline class="empty-message-headline">{{capitalize this.type}} is not Running</h3>
<p data-test-not-running-body class="empty-message-body">
Cannot access files of a{{if this.allocation 'n'}} {{this.type}} that is not running.
</p>
<div class="fs-explorer boxed-section">
<div class="boxed-section-head">
<Fs::Breadcrumbs @allocation={{this.allocation}} @taskState={{this.taskState}} @path={{this.path}} />
</div>
{{#if this.directoryEntries}}
<ListTable
@source={{this.sortedDirectoryEntries}}
@sortProperty={{this.sortProperty}}
@sortDescending={{this.sortDescending}}
@class="boxed-section-body is-full-bleed is-compact" as |t|>
<t.head>
<t.sort-by @prop="Name" @class="is-two-thirds">Name</t.sort-by>
<t.sort-by @prop="Size" @class="has-text-right">File Size</t.sort-by>
<t.sort-by @prop="ModTime" @class="has-text-right">Last Modified</t.sort-by>
</t.head>
<t.body as |row|>
<Fs::DirectoryEntry @path={{this.path}} @allocation={{this.allocation}} @taskState={{this.taskState}} @entry={{row.model}} />
</t.body>
</ListTable>
{{else}}
<div class="boxed-section-body">
<div data-test-empty-directory class="empty-message">
<h3 data-test-empty-directory-headline class="empty-message-headline">No Files</h3>
<p data-test-empty-directory-body class="empty-message-body">
Directory is currently empty.
</p>
</div>
</div>
{{/if}}
</div>
{{/if}}
</section>

View File

@@ -1,14 +1,11 @@
/* eslint-disable ember-a11y-testing/a11y-audit-called */ // Covered in behaviours/fs
import { module, test } from 'qunit';
import { module } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import Response from 'ember-cli-mirage/response';
import browseFilesystem from './behaviors/fs';
import FS from 'nomad-ui/tests/pages/allocations/fs';
let allocation;
let files;
@@ -48,24 +45,6 @@ module('Acceptance | allocation fs', function(hooks) {
this.nestedDirectory = files[1];
});
test('when the allocation is not running, an empty state is shown', async function(assert) {
// The API 500s on stat when not running
this.server.get('/client/fs/stat/:allocation_id', () => {
return new Response(500, {}, 'no such file or directory');
});
allocation.update({
clientStatus: 'complete',
});
await FS.visitAllocation({ id: allocation.id });
assert.ok(FS.hasEmptyState, 'Non-running allocation has no files');
assert.ok(
FS.emptyState.headline.includes('Allocation is not Running'),
'Empty state explains the condition'
);
});
browseFilesystem({
visitSegments: ({ allocation }) => ({ id: allocation.id }),
getExpectedPathBase: ({ allocation }) => `/allocations/${allocation.id}/fs/`,

View File

@@ -1,14 +1,11 @@
/* eslint-disable ember-a11y-testing/a11y-audit-called */ // Covered in behaviours/fs
import { module, test } from 'qunit';
import { module } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import Response from 'ember-cli-mirage/response';
import browseFilesystem from './behaviors/fs';
import FS from 'nomad-ui/tests/pages/allocations/fs';
let allocation;
let task;
let files, taskDirectory, directory, nestedDirectory;
@@ -37,10 +34,18 @@ module('Acceptance | task fs', function(hooks) {
files.push(taskDirectory);
// Nested files
directory = server.create('allocFile', { isDir: true, name: 'directory', parent: taskDirectory });
directory = server.create('allocFile', {
isDir: true,
name: 'directory',
parent: taskDirectory,
});
files.push(directory);
nestedDirectory = server.create('allocFile', { isDir: true, name: 'another', parent: directory });
nestedDirectory = server.create('allocFile', {
isDir: true,
name: 'another',
parent: directory,
});
files.push(nestedDirectory);
files.push(
@@ -51,7 +56,9 @@ module('Acceptance | task fs', function(hooks) {
})
);
files.push(server.create('allocFile', { isDir: true, name: 'empty-directory', parent: taskDirectory }));
files.push(
server.create('allocFile', { isDir: true, name: 'empty-directory', parent: taskDirectory })
);
files.push(server.create('allocFile', 'file', { fileType: 'txt', parent: taskDirectory }));
files.push(server.create('allocFile', 'file', { fileType: 'txt', parent: taskDirectory }));
@@ -60,29 +67,11 @@ module('Acceptance | task fs', function(hooks) {
this.nestedDirectory = nestedDirectory;
});
test('when the task is not running, an empty state is shown', async function(assert) {
// The API 500s on stat when not running
this.server.get('/client/fs/stat/:allocation_id', () => {
return new Response(500, {}, 'no such file or directory');
});
task.update({
finishedAt: new Date(),
});
await FS.visitTask({ id: allocation.id, name: task.name });
assert.ok(FS.hasEmptyState, 'Non-running task has no files');
assert.ok(
FS.emptyState.headline.includes('Task is not Running'),
'Empty state explains the condition'
);
});
browseFilesystem({
visitSegments: ({allocation,task}) => ({ id: allocation.id, name: task.name }),
getExpectedPathBase: ({allocation,task}) => `/allocations/${allocation.id}/${task.name}/fs/`,
getTitleComponent: ({task}) => `Task ${task.name} filesystem`,
getBreadcrumbComponent: ({task}) => task.name,
visitSegments: ({ allocation, task }) => ({ id: allocation.id, name: task.name }),
getExpectedPathBase: ({ allocation, task }) => `/allocations/${allocation.id}/${task.name}/fs/`,
getTitleComponent: ({ task }) => `Task ${task.name} filesystem`,
getBreadcrumbComponent: ({ task }) => task.name,
getFilesystemRoot: ({ task }) => task.name,
pageObjectVisitFunctionName: 'visitTask',
pageObjectVisitPathFunctionName: 'visitTaskPath',