mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 18:40:01 -03:30
Add JobOutput tests
This commit is contained in:
parent
b2922792bc
commit
475645f604
39
awx/ui_next/package-lock.json
generated
39
awx/ui_next/package-lock.json
generated
@ -2307,6 +2307,14 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
},
|
||||
"ansi-to-html": {
|
||||
"version": "0.6.11",
|
||||
"resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.11.tgz",
|
||||
"integrity": "sha512-88XZtrcwrfkyn6fGstHnkaF1kl7hGtNCYh4vSmItgEV+6JnQHryDBf7udF4f2RhTRQmYvJvPcTtqgaqrxzc9oA==",
|
||||
"requires": {
|
||||
"entities": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"ansi-wrap": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
|
||||
@ -4242,6 +4250,16 @@
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chardet": {
|
||||
@ -5680,8 +5698,7 @@
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"enzyme": {
|
||||
"version": "3.9.0",
|
||||
@ -7953,11 +7970,18 @@
|
||||
}
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-3.0.0.tgz",
|
||||
"integrity": "sha1-Ngd+8dFfMzSEqn+neihgbxxlWzc=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
"ansi-regex": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
@ -8170,8 +8194,7 @@
|
||||
"html-entities": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
|
||||
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8="
|
||||
},
|
||||
"html-tokenize": {
|
||||
"version": "2.0.0",
|
||||
|
||||
@ -15,7 +15,7 @@ import ContentError from '@components/ContentError';
|
||||
import ContentLoading from '@components/ContentLoading';
|
||||
import JobEvent from './JobEvent';
|
||||
import JobEventSkeleton from './JobEventSkeleton';
|
||||
import MenuControls from './shared/MenuControls';
|
||||
import MenuControls from './MenuControls';
|
||||
|
||||
const OutputHeader = styled.div`
|
||||
font-weight: var(--pf-global--FontWeight--bold);
|
||||
@ -52,7 +52,7 @@ function range(low, high) {
|
||||
class JobOutput extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.listRef = React.createRef();
|
||||
this.state = {
|
||||
contentError: null,
|
||||
hasContentLoading: true,
|
||||
@ -68,13 +68,14 @@ class JobOutput extends Component {
|
||||
|
||||
this.loadJobEvents = this.loadJobEvents.bind(this);
|
||||
this.rowRenderer = this.rowRenderer.bind(this);
|
||||
this.handleScrollTop = this.handleScrollTop.bind(this);
|
||||
this.handleScrollBottom = this.handleScrollBottom.bind(this);
|
||||
this.handleScrollFirst = this.handleScrollFirst.bind(this);
|
||||
this.handleScrollLast = this.handleScrollLast.bind(this);
|
||||
this.handleScrollNext = this.handleScrollNext.bind(this);
|
||||
this.handleScrollPrevious = this.handleScrollPrevious.bind(this);
|
||||
this.handleResize = this.handleResize.bind(this);
|
||||
this.isRowLoaded = this.isRowLoaded.bind(this);
|
||||
this.loadMoreRows = this.loadMoreRows.bind(this);
|
||||
this.scrollToRow = this.scrollToRow.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -93,12 +94,12 @@ class JobOutput extends Component {
|
||||
this.cache.clear(n);
|
||||
});
|
||||
if (shouldRecomputeRowHeights) {
|
||||
this.listRef.recomputeRowHeights();
|
||||
if (this.listRef.recomputeRowHeights) {
|
||||
this.listRef.recomputeRowHeights();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listRef = React.createRef();
|
||||
|
||||
async loadJobEvents() {
|
||||
const { job } = this.props;
|
||||
|
||||
@ -193,25 +194,29 @@ class JobOutput extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
scrollToRow(rowIndex) {
|
||||
this.listRef.scrollToRow(rowIndex);
|
||||
}
|
||||
|
||||
handleScrollPrevious() {
|
||||
const startIndex = this.listRef.Grid._renderedRowStartIndex;
|
||||
const stopIndex = this.listRef.Grid._renderedRowStopIndex;
|
||||
const scrollRange = stopIndex - startIndex + 1;
|
||||
this.listRef.scrollToRow(Math.max(0, startIndex - scrollRange));
|
||||
this.scrollToRow(Math.max(0, startIndex - scrollRange));
|
||||
}
|
||||
|
||||
handleScrollNext() {
|
||||
const stopIndex = this.listRef.Grid._renderedRowStopIndex;
|
||||
this.listRef.scrollToRow(stopIndex - 1);
|
||||
this.scrollToRow(stopIndex - 1);
|
||||
}
|
||||
|
||||
handleScrollTop() {
|
||||
this.listRef.scrollToRow(0);
|
||||
handleScrollFirst() {
|
||||
this.scrollToRow(0);
|
||||
}
|
||||
|
||||
handleScrollBottom() {
|
||||
handleScrollLast() {
|
||||
const { remoteRowCount } = this.state;
|
||||
this.listRef.scrollToRow(remoteRowCount - 1);
|
||||
this.scrollToRow(remoteRowCount - 1);
|
||||
}
|
||||
|
||||
handleResize({ width }) {
|
||||
@ -239,8 +244,8 @@ class JobOutput extends Component {
|
||||
<OutputHeader>{job.name}</OutputHeader>
|
||||
<OutputToolbar>
|
||||
<MenuControls
|
||||
onScrollTop={this.handleScrollTop}
|
||||
onScrollBottom={this.handleScrollBottom}
|
||||
onScrollFirst={this.handleScrollFirst}
|
||||
onScrollLast={this.handleScrollLast}
|
||||
onScrollNext={this.handleScrollNext}
|
||||
onScrollPrevious={this.handleScrollPrevious}
|
||||
/>
|
||||
@ -261,13 +266,13 @@ class JobOutput extends Component {
|
||||
registerChild(ref);
|
||||
}}
|
||||
deferredMeasurementCache={this.cache}
|
||||
height={height}
|
||||
height={height || 1}
|
||||
onRowsRendered={onRowsRendered}
|
||||
rowCount={remoteRowCount}
|
||||
rowHeight={this.cache.rowHeight}
|
||||
rowRenderer={this.rowRenderer}
|
||||
scrollToAlignment="start"
|
||||
width={width}
|
||||
width={width || 1}
|
||||
overscanRowCount={20}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -1,48 +1,196 @@
|
||||
import React from 'react';
|
||||
|
||||
import { mountWithContexts, waitForElement } from '@testUtils/enzymeHelpers';
|
||||
|
||||
import JobOutput from './JobOutput';
|
||||
import { JobsAPI } from '@api';
|
||||
import mockJobData from './data.job.json';
|
||||
import mockJobEventsData from './data.job_events.json';
|
||||
|
||||
jest.mock('@api');
|
||||
|
||||
async function checkOutput(wrapper, expectedLines) {
|
||||
await waitForElement(wrapper, 'div[type="job_event"]', (e) => e.length > 1);
|
||||
await waitForElement(wrapper, 'div[type="job_event"]', e => e.length > 1);
|
||||
const jobEventLines = wrapper.find('div[type="job_event_line_text"]');
|
||||
const actualLines = [];
|
||||
jobEventLines.forEach(line => {
|
||||
actualLines.push(line.text());
|
||||
});
|
||||
expect(actualLines.length).toEqual(expectedLines.length);
|
||||
expectedLines.forEach((line, index) => {
|
||||
expect(actualLines[index]).toEqual(line);
|
||||
});
|
||||
}
|
||||
|
||||
describe('<JobOutput />', () => {
|
||||
const mockDetails = {
|
||||
name: 'Foo',
|
||||
async function findScrollButtons(wrapper) {
|
||||
const menuControls = await waitForElement(wrapper, 'MenuControls');
|
||||
const scrollFirstButton = menuControls.find(
|
||||
'button[aria-label="scroll first"]'
|
||||
);
|
||||
const scrollLastButton = menuControls.find(
|
||||
'button[aria-label="scroll last"]'
|
||||
);
|
||||
const scrollPreviousButton = menuControls.find(
|
||||
'button[aria-label="scroll previous"]'
|
||||
);
|
||||
return {
|
||||
scrollFirstButton,
|
||||
scrollLastButton,
|
||||
scrollPreviousButton,
|
||||
};
|
||||
}
|
||||
|
||||
describe('<JobOutput />', () => {
|
||||
let wrapper;
|
||||
const mockJob = mockJobData;
|
||||
const mockJobEvents = mockJobEventsData;
|
||||
const scrollMock = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
JobsAPI.readEvents.mockResolvedValue({
|
||||
data: {
|
||||
count: 100,
|
||||
next: null,
|
||||
previous: null,
|
||||
results: mockJobEvents.results,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('initially renders succesfully', async done => {
|
||||
const wrapper = mountWithContexts(<JobOutput job={mockDetails} />);
|
||||
// wait until not loading
|
||||
await waitForElement(wrapper, 'EmptyStateBody', (e) => e.length === 0);
|
||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||
await waitForElement(wrapper, 'JobEvent', el => el.length > 0);
|
||||
await checkOutput(wrapper, [
|
||||
'',
|
||||
'PLAY [all] *********************************************************************11:37:25',
|
||||
'',
|
||||
'TASK [debug] *******************************************************************11:37:25',
|
||||
'ok: [localhost] => (item=1) => {',
|
||||
' "msg": "This is a debug message: 1"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=2) => {',
|
||||
' "msg": "This is a debug message: 2"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=3) => {',
|
||||
' "msg": "This is a debug message: 3"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=4) => {',
|
||||
' "msg": "This is a debug message: 4"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=5) => {',
|
||||
' "msg": "This is a debug message: 5"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=6) => {',
|
||||
' "msg": "This is a debug message: 6"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=7) => {',
|
||||
' "msg": "This is a debug message: 7"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=8) => {',
|
||||
' "msg": "This is a debug message: 8"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=9) => {',
|
||||
' "msg": "This is a debug message: 9"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=10) => {',
|
||||
' "msg": "This is a debug message: 10"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=11) => {',
|
||||
' "msg": "This is a debug message: 11"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=12) => {',
|
||||
' "msg": "This is a debug message: 12"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=13) => {',
|
||||
' "msg": "This is a debug message: 13"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=14) => {',
|
||||
' "msg": "This is a debug message: 14"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=15) => {',
|
||||
' "msg": "This is a debug message: 15"',
|
||||
'}',
|
||||
'ok: [localhost] => (item=16) => {',
|
||||
' "msg": "This is a debug message: 16"',
|
||||
'}',
|
||||
]);
|
||||
|
||||
// await checkOutput(wrapper, [
|
||||
// '',
|
||||
// 'PLAY [localhost] ***************************************************************08:00:52',
|
||||
// '',
|
||||
// 'TASK [Gathering Facts] *********************************************************08:00:52',
|
||||
// 'ok: [localhost]',
|
||||
// '',
|
||||
// 'TASK [Check Slack accounts against ldap] ***************************************08:00:53',
|
||||
// 'changed: [localhost]',
|
||||
// '',
|
||||
// 'TASK [E-mail output] ***********************************************************08:00:58',
|
||||
// 'skipping: [localhost]',
|
||||
// '',
|
||||
// 'PLAY RECAP *********************************************************************08:00:58',
|
||||
// 'localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 ',
|
||||
// '',
|
||||
// ]);
|
||||
expect(wrapper.find('JobOutput').length).toBe(1);
|
||||
done();
|
||||
});
|
||||
|
||||
test('should call scrollToRow with expected index when scroll "previous" button is clicked', async done => {
|
||||
const handleScrollPrevious = jest.spyOn(
|
||||
JobOutput.prototype,
|
||||
'handleScrollPrevious'
|
||||
);
|
||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||
await waitForElement(wrapper, 'JobEvent', el => el.length > 0);
|
||||
const { scrollLastButton, scrollPreviousButton } = await findScrollButtons(
|
||||
wrapper
|
||||
);
|
||||
wrapper.find('JobOutput').instance().scrollToRow = scrollMock;
|
||||
|
||||
scrollLastButton.simulate('click');
|
||||
scrollPreviousButton.simulate('click');
|
||||
|
||||
expect(handleScrollPrevious).toHaveBeenCalled();
|
||||
expect(scrollMock).toHaveBeenCalledTimes(2);
|
||||
expect(scrollMock.mock.calls).toEqual([[100], [0]]);
|
||||
done();
|
||||
});
|
||||
|
||||
test('should call scrollToRow with expected indices on when scroll "first" and "last" buttons are clicked', async done => {
|
||||
const handleScrollFirst = jest.spyOn(
|
||||
JobOutput.prototype,
|
||||
'handleScrollFirst'
|
||||
);
|
||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||
await waitForElement(wrapper, 'JobEvent', el => el.length > 0);
|
||||
const { scrollFirstButton, scrollLastButton } = await findScrollButtons(
|
||||
wrapper
|
||||
);
|
||||
wrapper.find('JobOutput').instance().scrollToRow = scrollMock;
|
||||
|
||||
scrollFirstButton.simulate('click');
|
||||
scrollLastButton.simulate('click');
|
||||
scrollFirstButton.simulate('click');
|
||||
|
||||
expect(handleScrollFirst).toHaveBeenCalled();
|
||||
expect(scrollMock).toHaveBeenCalledTimes(3);
|
||||
expect(scrollMock.mock.calls).toEqual([[0], [100], [0]]);
|
||||
done();
|
||||
});
|
||||
|
||||
test('should call scrollToRow with expected index on when scroll "last" button is clicked', async done => {
|
||||
const handleScrollLast = jest.spyOn(
|
||||
JobOutput.prototype,
|
||||
'handleScrollLast'
|
||||
);
|
||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||
await waitForElement(wrapper, 'EmptyStateBody', e => e.length === 0);
|
||||
wrapper
|
||||
.find('JobOutput')
|
||||
.instance()
|
||||
.handleResize({ width: 100 });
|
||||
const { scrollLastButton } = await findScrollButtons(wrapper);
|
||||
wrapper.find('JobOutput').instance().scrollToRow = scrollMock;
|
||||
|
||||
scrollLastButton.simulate('click');
|
||||
|
||||
expect(handleScrollLast).toHaveBeenCalled();
|
||||
expect(scrollMock).toHaveBeenCalledTimes(1);
|
||||
expect(scrollMock.mock.calls).toEqual([[100]]);
|
||||
done();
|
||||
});
|
||||
|
||||
test('should throw error', async done => {
|
||||
JobsAPI.readEvents = () => Promise.reject(new Error());
|
||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||
await waitForElement(wrapper, 'ContentError', e => e.length === 1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@ -23,8 +23,8 @@ const Button = styled(PFButton)`
|
||||
`;
|
||||
|
||||
const MenuControls = ({
|
||||
onScrollTop,
|
||||
onScrollBottom,
|
||||
onScrollFirst,
|
||||
onScrollLast,
|
||||
onScrollNext,
|
||||
onScrollPrevious,
|
||||
}) => (
|
||||
@ -32,16 +32,20 @@ const MenuControls = ({
|
||||
<Button variant="plain">
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
<Button onClick={onScrollPrevious} variant="plain">
|
||||
<Button
|
||||
aria-label="scroll previous"
|
||||
onClick={onScrollPrevious}
|
||||
variant="plain"
|
||||
>
|
||||
<AngleUpIcon />
|
||||
</Button>
|
||||
<Button onClick={onScrollNext} variant="plain">
|
||||
<Button aria-label="scroll next" onClick={onScrollNext} variant="plain">
|
||||
<AngleDownIcon />
|
||||
</Button>
|
||||
<Button onClick={onScrollTop} variant="plain">
|
||||
<Button aria-label="scroll first" onClick={onScrollFirst} variant="plain">
|
||||
<AngleDoubleUpIcon />
|
||||
</Button>
|
||||
<Button onClick={onScrollBottom} variant="plain">
|
||||
<Button aria-label="scroll last" onClick={onScrollLast} variant="plain">
|
||||
<AngleDoubleDownIcon />
|
||||
</Button>
|
||||
</Wrapper>
|
||||
194
awx/ui_next/src/screens/Job/JobOutput/data.job.json
Normal file
194
awx/ui_next/src/screens/Job/JobOutput/data.job.json
Normal file
@ -0,0 +1,194 @@
|
||||
{
|
||||
"id": 2,
|
||||
"type": "job",
|
||||
"url": "/api/v2/jobs/2/",
|
||||
"related": {
|
||||
"created_by": "/api/v2/users/1/",
|
||||
"labels": "/api/v2/jobs/2/labels/",
|
||||
"inventory": "/api/v2/inventories/1/",
|
||||
"project": "/api/v2/projects/6/",
|
||||
"extra_credentials": "/api/v2/jobs/2/extra_credentials/",
|
||||
"credentials": "/api/v2/jobs/2/credentials/",
|
||||
"unified_job_template": "/api/v2/job_templates/7/",
|
||||
"stdout": "/api/v2/jobs/2/stdout/",
|
||||
"job_events": "/api/v2/jobs/2/job_events/",
|
||||
"job_host_summaries": "/api/v2/jobs/2/job_host_summaries/",
|
||||
"activity_stream": "/api/v2/jobs/2/activity_stream/",
|
||||
"notifications": "/api/v2/jobs/2/notifications/",
|
||||
"create_schedule": "/api/v2/jobs/2/create_schedule/",
|
||||
"job_template": "/api/v2/job_templates/7/",
|
||||
"cancel": "/api/v2/jobs/2/cancel/",
|
||||
"project_update": "/api/v2/project_updates/4/",
|
||||
"relaunch": "/api/v2/jobs/2/relaunch/"
|
||||
},
|
||||
"summary_fields": {
|
||||
"inventory": {
|
||||
"id": 1,
|
||||
"name": "Demo Inventory",
|
||||
"description": "",
|
||||
"has_active_failures": false,
|
||||
"total_hosts": 1,
|
||||
"hosts_with_active_failures": 0,
|
||||
"total_groups": 0,
|
||||
"groups_with_active_failures": 0,
|
||||
"has_inventory_sources": false,
|
||||
"total_inventory_sources": 0,
|
||||
"inventory_sources_with_failures": 0,
|
||||
"organization_id": 1,
|
||||
"kind": ""
|
||||
},
|
||||
"project": {
|
||||
"id": 6,
|
||||
"name": "Demo Project",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"scm_type": "git"
|
||||
},
|
||||
"project_update": {
|
||||
"id": 4,
|
||||
"name": "Demo Project",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"failed": false
|
||||
},
|
||||
"job_template": {
|
||||
"id": 7,
|
||||
"name": "Demo Job Template",
|
||||
"description": ""
|
||||
},
|
||||
"unified_job_template": {
|
||||
"id": 7,
|
||||
"name": "Demo Job Template",
|
||||
"description": "",
|
||||
"unified_job_type": "job"
|
||||
},
|
||||
"instance_group": {
|
||||
"id": 1,
|
||||
"name": "tower"
|
||||
},
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"user_capabilities": {
|
||||
"delete": true,
|
||||
"start": true
|
||||
},
|
||||
"labels": {
|
||||
"count": 0,
|
||||
"results": []
|
||||
},
|
||||
"extra_credentials": [],
|
||||
"credentials": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Demo Credential",
|
||||
"description": "",
|
||||
"kind": "ssh",
|
||||
"cloud": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "2019-08-08T19:24:05.344276Z",
|
||||
"modified": "2019-08-08T19:24:18.162949Z",
|
||||
"name": "Demo Job Template",
|
||||
"description": "",
|
||||
"job_type": "run",
|
||||
"inventory": 1,
|
||||
"project": 6,
|
||||
"playbook": "chatty_tasks.yml",
|
||||
"forks": 0,
|
||||
"limit": "",
|
||||
"verbosity": 0,
|
||||
"extra_vars": "{\"num_messages\": 94}",
|
||||
"job_tags": "",
|
||||
"force_handlers": false,
|
||||
"skip_tags": "",
|
||||
"start_at_task": "",
|
||||
"timeout": 0,
|
||||
"use_fact_cache": false,
|
||||
"unified_job_template": 7,
|
||||
"launch_type": "manual",
|
||||
"status": "successful",
|
||||
"failed": false,
|
||||
"started": "2019-08-08T19:24:18.329589Z",
|
||||
"finished": "2019-08-08T19:24:50.119995Z",
|
||||
"elapsed": 31.79,
|
||||
"job_args": "[\"bwrap\", \"--unshare-pid\", \"--dev-bind\", \"/\", \"/\", \"--proc\", \"/proc\", \"--bind\", \"/tmp/ansible_runner_pi_pzufy15c/ansible_runner_pi_r_aeukpy/tmpvsg8ly2y\", \"/etc/ssh\", \"--bind\", \"/tmp/ansible_runner_pi_pzufy15c/ansible_runner_pi_r_aeukpy/tmpq_grmdym\", \"/projects\", \"--bind\", \"/tmp/ansible_runner_pi_pzufy15c/ansible_runner_pi_r_aeukpy/tmpfq8ea2z6\", \"/tmp\", \"--bind\", \"/tmp/ansible_runner_pi_pzufy15c/ansible_runner_pi_r_aeukpy/tmpq6v4y_tt\", \"/var/lib/awx\", \"--bind\", \"/tmp/ansible_runner_pi_pzufy15c/ansible_runner_pi_r_aeukpy/tmpupj_jhhb\", \"/var/log\", \"--ro-bind\", \"/venv/ansible\", \"/venv/ansible\", \"--ro-bind\", \"/venv/awx\", \"/venv/awx\", \"--bind\", \"/projects/_6__demo_project\", \"/projects/_6__demo_project\", \"--bind\", \"/tmp/awx_2_a4b1afiw\", \"/tmp/awx_2_a4b1afiw\", \"--chdir\", \"/projects/_6__demo_project\", \"ansible-playbook\", \"-u\", \"admin\", \"-i\", \"/tmp/awx_2_a4b1afiw/tmppb57i4_e\", \"-e\", \"@/tmp/awx_2_a4b1afiw/env/extravars\", \"chatty_tasks.yml\"]",
|
||||
"job_cwd": "/projects/_6__demo_project",
|
||||
"job_env": {
|
||||
"HOSTNAME": "awx",
|
||||
"MAKEFLAGS": "w",
|
||||
"RABBITMQ_USER": "guest",
|
||||
"OS": "Operating System: Docker for Mac",
|
||||
"LC_ALL": "en_US.UTF-8",
|
||||
"RABBITMQ_VHOST": "/",
|
||||
"SDB_HOST": "0.0.0.0",
|
||||
"MAKELEVEL": "2",
|
||||
"VIRTUAL_ENV": "/venv/ansible",
|
||||
"MFLAGS": "-w",
|
||||
"PATH": "/venv/ansible/bin:/venv/awx/bin:/venv/awx/bin:/usr/local/n/versions/node/10.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"RABBITMQ_PASS": "**********",
|
||||
"SUPERVISOR_GROUP_NAME": "tower-processes",
|
||||
"PWD": "/awx_devel",
|
||||
"LANG": "\"en-us\"",
|
||||
"PS1": "(awx) ",
|
||||
"SUPERVISOR_ENABLED": "1",
|
||||
"SHLVL": "2",
|
||||
"HOME": "/var/lib/awx",
|
||||
"LANGUAGE": "en_US:en",
|
||||
"AWX_GROUP_QUEUES": "tower",
|
||||
"SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
|
||||
"SUPERVISOR_PROCESS_NAME": "awx-dispatcher",
|
||||
"RABBITMQ_HOST": "rabbitmq",
|
||||
"CURRENT_UID": "501",
|
||||
"_": "/venv/awx/bin/python3",
|
||||
"DJANGO_SETTINGS_MODULE": "awx.settings.development",
|
||||
"DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
|
||||
"SDB_NOTIFY_HOST": "docker.for.mac.host.internal",
|
||||
"TZ": "UTC",
|
||||
"ANSIBLE_FORCE_COLOR": "True",
|
||||
"ANSIBLE_HOST_KEY_CHECKING": "False",
|
||||
"ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
|
||||
"ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
|
||||
"ANSIBLE_VENV_PATH": "/venv/ansible",
|
||||
"PROOT_TMP_DIR": "/tmp",
|
||||
"AWX_PRIVATE_DATA_DIR": "/tmp/awx_2_a4b1afiw",
|
||||
"ANSIBLE_COLLECTIONS_PATHS": "/tmp/collections",
|
||||
"PYTHONPATH": "/venv/ansible/lib/python2.7/site-packages:/awx_devel/awx/lib:",
|
||||
"JOB_ID": "2",
|
||||
"INVENTORY_ID": "1",
|
||||
"PROJECT_REVISION": "23f070aad8e2da131d97ea98b42b553ccf0b0b82",
|
||||
"ANSIBLE_RETRY_FILES_ENABLED": "False",
|
||||
"MAX_EVENT_RES": "700000",
|
||||
"ANSIBLE_CALLBACK_PLUGINS": "/awx_devel/awx/plugins/callback",
|
||||
"AWX_HOST": "https://towerhost",
|
||||
"ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_2_a4b1afiw/cp",
|
||||
"ANSIBLE_STDOUT_CALLBACK": "awx_display",
|
||||
"AWX_ISOLATED_DATA_DIR": "/tmp/awx_2_a4b1afiw/artifacts/2"
|
||||
},
|
||||
"job_explanation": "",
|
||||
"execution_node": "awx",
|
||||
"controller_node": "",
|
||||
"result_traceback": "",
|
||||
"event_processing_finished": true,
|
||||
"job_template": 7,
|
||||
"passwords_needed_to_start": [],
|
||||
"allow_simultaneous": false,
|
||||
"artifacts": {},
|
||||
"scm_revision": "23f070aad8e2da131d97ea98b42b553ccf0b0b82",
|
||||
"instance_group": 1,
|
||||
"diff_mode": false,
|
||||
"job_slice_number": 0,
|
||||
"job_slice_count": 1,
|
||||
"host_status_counts": {
|
||||
"ok": 1
|
||||
},
|
||||
"playbook_counts": {
|
||||
"play_count": 1,
|
||||
"task_count": 1
|
||||
},
|
||||
"custom_virtualenv": "/venv/ansible"
|
||||
}
|
||||
8461
awx/ui_next/src/screens/Job/JobOutput/data.job_events.json
Normal file
8461
awx/ui_next/src/screens/Job/JobOutput/data.job_events.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
export { default } from './MenuControls';
|
||||
Loading…
x
Reference in New Issue
Block a user