mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
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:
@@ -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]) => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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/`,
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user