mirror of
https://github.com/ansible/awx.git
synced 2026-01-22 15:08:03 -03:30
Merge pull request #11342 from shanemcd/custom-uwsgi-mount-path
Allow for running AWX at non-root path (URL prefixing)
This commit is contained in:
commit
750e1bd80a
@ -379,19 +379,22 @@ class BaseSerializer(serializers.ModelSerializer, metaclass=BaseSerializerMetacl
|
||||
def _get_related(self, obj):
|
||||
return {} if obj is None else self.get_related(obj)
|
||||
|
||||
def _generate_named_url(self, url_path, obj, node):
|
||||
url_units = url_path.split('/')
|
||||
def _generate_friendly_id(self, obj, node):
|
||||
reset_counters()
|
||||
named_url = node.generate_named_url(obj)
|
||||
url_units[4] = named_url
|
||||
return '/'.join(url_units)
|
||||
return node.generate_named_url(obj)
|
||||
|
||||
def get_related(self, obj):
|
||||
res = OrderedDict()
|
||||
view = self.context.get('view', None)
|
||||
if view and (hasattr(view, 'retrieve') or view.request.method == 'POST') and type(obj) in settings.NAMED_URL_GRAPH:
|
||||
original_url = self.get_url(obj)
|
||||
res['named_url'] = self._generate_named_url(original_url, obj, settings.NAMED_URL_GRAPH[type(obj)])
|
||||
original_path = self.get_url(obj)
|
||||
path_components = original_path.lstrip('/').rstrip('/').split('/')
|
||||
|
||||
friendly_id = self._generate_friendly_id(obj, settings.NAMED_URL_GRAPH[type(obj)])
|
||||
path_components[-1] = friendly_id
|
||||
|
||||
new_path = '/' + '/'.join(path_components) + '/'
|
||||
res['named_url'] = new_path
|
||||
if getattr(obj, 'created_by', None):
|
||||
res['created_by'] = self.reverse('api:user_detail', kwargs={'pk': obj.created_by.pk})
|
||||
if getattr(obj, 'modified_by', None):
|
||||
|
||||
@ -180,11 +180,7 @@ class URLModificationMiddleware(MiddlewareMixin):
|
||||
return '/'.join(url_units)
|
||||
|
||||
def process_request(self, request):
|
||||
if hasattr(request, 'environ') and 'REQUEST_URI' in request.environ:
|
||||
old_path = urllib.parse.urlsplit(request.environ['REQUEST_URI']).path
|
||||
old_path = old_path[request.path.find(request.path_info) :]
|
||||
else:
|
||||
old_path = request.path_info
|
||||
old_path = request.path_info
|
||||
new_path = self._convert_named_url(old_path)
|
||||
if request.path_info != new_path:
|
||||
request.environ['awx.named_url_rewritten'] = request.path
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "ui",
|
||||
"homepage": ".",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "14.x"
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class ActivityStream extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/activity_stream/';
|
||||
this.baseUrl = 'api/v2/activity_stream/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class AdHocCommands extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/ad_hoc_commands/';
|
||||
this.baseUrl = 'api/v2/ad_hoc_commands/';
|
||||
}
|
||||
|
||||
readCredentials(id) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Applications extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/applications/';
|
||||
this.baseUrl = 'api/v2/applications/';
|
||||
}
|
||||
|
||||
readTokens(appId, params) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Auth extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/auth/';
|
||||
this.baseUrl = 'api/v2/auth/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Config extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/config/';
|
||||
this.baseUrl = 'api/v2/config/';
|
||||
this.read = this.read.bind(this);
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class CredentialInputSources extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/credential_input_sources/';
|
||||
this.baseUrl = 'api/v2/credential_input_sources/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class CredentialTypes extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/credential_types/';
|
||||
this.baseUrl = 'api/v2/credential_types/';
|
||||
}
|
||||
|
||||
async loadAllTypes(
|
||||
|
||||
@ -20,7 +20,7 @@ describe('CredentialTypesAPI', () => {
|
||||
|
||||
expect(mockHttp.get).toHaveBeenCalledTimes(1);
|
||||
expect(mockHttp.get.mock.calls[0]).toEqual([
|
||||
`/api/v2/credential_types/`,
|
||||
`api/v2/credential_types/`,
|
||||
{ params: { page_size: 200 } },
|
||||
]);
|
||||
expect(types).toEqual(typesData);
|
||||
@ -41,11 +41,11 @@ describe('CredentialTypesAPI', () => {
|
||||
|
||||
expect(mockHttp.get).toHaveBeenCalledTimes(2);
|
||||
expect(mockHttp.get.mock.calls[0]).toEqual([
|
||||
`/api/v2/credential_types/`,
|
||||
`api/v2/credential_types/`,
|
||||
{ params: { page_size: 200 } },
|
||||
]);
|
||||
expect(mockHttp.get.mock.calls[1]).toEqual([
|
||||
`/api/v2/credential_types/`,
|
||||
`api/v2/credential_types/`,
|
||||
{ params: { page_size: 200, page: 2 } },
|
||||
]);
|
||||
expect(types).toHaveLength(4);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Credentials extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/credentials/';
|
||||
this.baseUrl = 'api/v2/credentials/';
|
||||
|
||||
this.readAccessList = this.readAccessList.bind(this);
|
||||
this.readAccessOptions = this.readAccessOptions.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Dashboard extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/dashboard/';
|
||||
this.baseUrl = 'api/v2/dashboard/';
|
||||
}
|
||||
|
||||
readJobGraph(params) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class ExecutionEnvironments extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/execution_environments/';
|
||||
this.baseUrl = 'api/v2/execution_environments/';
|
||||
}
|
||||
|
||||
readUnifiedJobTemplates(id, params) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Groups extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/groups/';
|
||||
this.baseUrl = 'api/v2/groups/';
|
||||
|
||||
this.associateHost = this.associateHost.bind(this);
|
||||
this.createHost = this.createHost.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Hosts extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/hosts/';
|
||||
this.baseUrl = 'api/v2/hosts/';
|
||||
|
||||
this.readFacts = this.readFacts.bind(this);
|
||||
this.readAllGroups = this.readAllGroups.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class InstanceGroups extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/instance_groups/';
|
||||
this.baseUrl = 'api/v2/instance_groups/';
|
||||
|
||||
this.associateInstance = this.associateInstance.bind(this);
|
||||
this.disassociateInstance = this.disassociateInstance.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Instances extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/instances/';
|
||||
this.baseUrl = 'api/v2/instances/';
|
||||
|
||||
this.readHealthCheckDetail = this.readHealthCheckDetail.bind(this);
|
||||
this.healthCheck = this.healthCheck.bind(this);
|
||||
|
||||
@ -4,7 +4,7 @@ import InstanceGroupsMixin from '../mixins/InstanceGroups.mixin';
|
||||
class Inventories extends InstanceGroupsMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/inventories/';
|
||||
this.baseUrl = 'api/v2/inventories/';
|
||||
|
||||
this.readAccessList = this.readAccessList.bind(this);
|
||||
this.readAccessOptions = this.readAccessOptions.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class InventoryScripts extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/inventory_scripts/';
|
||||
this.baseUrl = 'api/v2/inventory_scripts/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ class InventorySources extends LaunchUpdateMixin(
|
||||
) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/inventory_sources/';
|
||||
this.baseUrl = 'api/v2/inventory_sources/';
|
||||
|
||||
this.createSchedule = this.createSchedule.bind(this);
|
||||
this.createSyncStart = this.createSyncStart.bind(this);
|
||||
|
||||
@ -4,7 +4,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class InventoryUpdates extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/inventory_updates/';
|
||||
this.baseUrl = 'api/v2/inventory_updates/';
|
||||
this.createSyncCancel = this.createSyncCancel.bind(this);
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ class JobTemplates extends SchedulesMixin(
|
||||
) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/job_templates/';
|
||||
this.baseUrl = 'api/v2/job_templates/';
|
||||
|
||||
this.createSchedule = this.createSchedule.bind(this);
|
||||
this.launch = this.launch.bind(this);
|
||||
|
||||
@ -4,7 +4,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class Jobs extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/jobs/';
|
||||
this.baseUrl = 'api/v2/jobs/';
|
||||
this.jobEventSlug = '/job_events/';
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Labels extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/labels/';
|
||||
this.baseUrl = 'api/v2/labels/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Me extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/me/';
|
||||
this.baseUrl = 'api/v2/me/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Metrics extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/metrics/';
|
||||
this.baseUrl = 'api/v2/metrics/';
|
||||
}
|
||||
}
|
||||
export default Metrics;
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class NotificationTemplates extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/notification_templates/';
|
||||
this.baseUrl = 'api/v2/notification_templates/';
|
||||
}
|
||||
|
||||
test(id) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Notifications extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/notifications/';
|
||||
this.baseUrl = 'api/v2/notifications/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import InstanceGroupsMixin from '../mixins/InstanceGroups.mixin';
|
||||
class Organizations extends InstanceGroupsMixin(NotificationsMixin(Base)) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/organizations/';
|
||||
this.baseUrl = 'api/v2/organizations/';
|
||||
}
|
||||
|
||||
readAccessList(id, params) {
|
||||
|
||||
@ -20,7 +20,7 @@ describe('OrganizationsAPI', () => {
|
||||
const testParams = { foo: 'bar' };
|
||||
const testParamsDuplicates = { foo: ['bar', 'baz'] };
|
||||
|
||||
const mockBaseURL = `/api/v2/organizations/${orgId}/access_list/`;
|
||||
const mockBaseURL = `api/v2/organizations/${orgId}/access_list/`;
|
||||
|
||||
await OrganizationsAPI.readAccessList(orgId);
|
||||
await OrganizationsAPI.readAccessList(orgId, testParams);
|
||||
@ -41,7 +41,7 @@ describe('OrganizationsAPI', () => {
|
||||
const testParams = { foo: 'bar' };
|
||||
const testParamsDuplicates = { foo: ['bar', 'baz'] };
|
||||
|
||||
const mockBaseURL = `/api/v2/organizations/${orgId}/teams/`;
|
||||
const mockBaseURL = `api/v2/organizations/${orgId}/teams/`;
|
||||
|
||||
await OrganizationsAPI.readTeams(orgId);
|
||||
await OrganizationsAPI.readTeams(orgId, testParams);
|
||||
|
||||
@ -4,7 +4,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class ProjectUpdates extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/project_updates/';
|
||||
this.baseUrl = 'api/v2/project_updates/';
|
||||
}
|
||||
|
||||
readCredentials(id) {
|
||||
|
||||
@ -8,7 +8,7 @@ class Projects extends SchedulesMixin(
|
||||
) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/projects/';
|
||||
this.baseUrl = 'api/v2/projects/';
|
||||
|
||||
this.readAccessList = this.readAccessList.bind(this);
|
||||
this.readAccessOptions = this.readAccessOptions.bind(this);
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Roles extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/roles/';
|
||||
this.baseUrl = 'api/v2/roles/';
|
||||
}
|
||||
|
||||
disassociateUserRole(roleId, userId) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Root extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/';
|
||||
this.baseUrl = 'api/';
|
||||
this.redirectURL = '/api/v2/config/';
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ class Root extends Base {
|
||||
// automation etc. should relocate this variable file to an importable
|
||||
// location in src prior to building. That said, a raw http call
|
||||
// works for now.
|
||||
return this.http.get('/static/media/default.strings.json');
|
||||
return this.http.get('static/media/default.strings.json');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Schedules extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/schedules/';
|
||||
this.baseUrl = 'api/v2/schedules/';
|
||||
}
|
||||
|
||||
createPreview(data) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Settings extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/settings/';
|
||||
this.baseUrl = 'api/v2/settings/';
|
||||
}
|
||||
|
||||
readAllOptions() {
|
||||
|
||||
@ -7,7 +7,7 @@ const Mixins = SchedulesMixin(NotificationsMixin(Base));
|
||||
class SystemJobTemplates extends Mixins {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/system_job_templates/';
|
||||
this.baseUrl = 'api/v2/system_job_templates/';
|
||||
}
|
||||
|
||||
launch(id, data) {
|
||||
|
||||
@ -5,7 +5,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class SystemJobs extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/system_jobs/';
|
||||
this.baseUrl = 'api/v2/system_jobs/';
|
||||
}
|
||||
|
||||
readCredentials(id) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Teams extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/teams/';
|
||||
this.baseUrl = 'api/v2/teams/';
|
||||
}
|
||||
|
||||
associateRole(teamId, roleId) {
|
||||
|
||||
@ -23,7 +23,7 @@ describe('TeamsAPI', () => {
|
||||
|
||||
expect(mockHttp.post).toHaveBeenCalledTimes(1);
|
||||
expect(mockHttp.post.mock.calls[0]).toContainEqual(
|
||||
`/api/v2/teams/${teamId}/roles/`,
|
||||
`api/v2/teams/${teamId}/roles/`,
|
||||
{ id: roleId }
|
||||
);
|
||||
});
|
||||
@ -33,7 +33,7 @@ describe('TeamsAPI', () => {
|
||||
|
||||
expect(mockHttp.post).toHaveBeenCalledTimes(1);
|
||||
expect(mockHttp.post.mock.calls[0]).toContainEqual(
|
||||
`/api/v2/teams/${teamId}/roles/`,
|
||||
`api/v2/teams/${teamId}/roles/`,
|
||||
{
|
||||
id: roleId,
|
||||
disassociate: true,
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Tokens extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/tokens/';
|
||||
this.baseUrl = 'api/v2/tokens/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class UnifiedJobTemplates extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/unified_job_templates/';
|
||||
this.baseUrl = 'api/v2/unified_job_templates/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class UnifiedJobs extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/unified_jobs/';
|
||||
this.baseUrl = 'api/v2/unified_jobs/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class Users extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/users/';
|
||||
this.baseUrl = 'api/v2/users/';
|
||||
}
|
||||
|
||||
associateRole(userId, roleId) {
|
||||
|
||||
@ -20,7 +20,7 @@ describe('UsersAPI', () => {
|
||||
|
||||
expect(mockHttp.post).toHaveBeenCalledTimes(1);
|
||||
expect(mockHttp.post.mock.calls[0]).toContainEqual(
|
||||
`/api/v2/users/${userId}/roles/`,
|
||||
`api/v2/users/${userId}/roles/`,
|
||||
{ id: roleId }
|
||||
);
|
||||
});
|
||||
@ -30,7 +30,7 @@ describe('UsersAPI', () => {
|
||||
|
||||
expect(mockHttp.post).toHaveBeenCalledTimes(1);
|
||||
expect(mockHttp.post.mock.calls[0]).toContainEqual(
|
||||
`/api/v2/users/${userId}/roles/`,
|
||||
`api/v2/users/${userId}/roles/`,
|
||||
{
|
||||
id: roleId,
|
||||
disassociate: true,
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class WorkflowApprovalTemplates extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/workflow_approval_templates/';
|
||||
this.baseUrl = 'api/v2/workflow_approval_templates/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class WorkflowApprovals extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/workflow_approvals/';
|
||||
this.baseUrl = 'api/v2/workflow_approvals/';
|
||||
}
|
||||
|
||||
approve(id) {
|
||||
|
||||
@ -3,7 +3,7 @@ import Base from '../Base';
|
||||
class WorkflowJobTemplateNodes extends Base {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/workflow_job_template_nodes/';
|
||||
this.baseUrl = 'api/v2/workflow_job_template_nodes/';
|
||||
}
|
||||
|
||||
createApprovalTemplate(id, data) {
|
||||
|
||||
@ -5,7 +5,7 @@ import NotificationsMixin from '../mixins/Notifications.mixin';
|
||||
class WorkflowJobTemplates extends SchedulesMixin(NotificationsMixin(Base)) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/workflow_job_templates/';
|
||||
this.baseUrl = 'api/v2/workflow_job_templates/';
|
||||
this.createSchedule = this.createSchedule.bind(this);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import RunnableMixin from '../mixins/Runnable.mixin';
|
||||
class WorkflowJobs extends RunnableMixin(Base) {
|
||||
constructor(http) {
|
||||
super(http);
|
||||
this.baseUrl = '/api/v2/workflow_jobs/';
|
||||
this.baseUrl = 'api/v2/workflow_jobs/';
|
||||
}
|
||||
|
||||
readNodes(id, params) {
|
||||
|
||||
@ -41,7 +41,7 @@ function About({ version, isOpen, onClose }) {
|
||||
onClose={onClose}
|
||||
productName={brandName}
|
||||
trademark={`${copyright} ${new Date().getFullYear()} ${redHatInc}`}
|
||||
brandImageSrc="/static/media/logo-header.svg"
|
||||
brandImageSrc="static/media/logo-header.svg"
|
||||
brandImageAlt={t`Brand Image`}
|
||||
>
|
||||
<pre>
|
||||
|
||||
@ -14,7 +14,7 @@ const BrandImg = styled.img`
|
||||
`;
|
||||
|
||||
const BrandLogo = ({ alt }) => (
|
||||
<BrandImg src="/static/media/logo-header.svg" alt={alt} />
|
||||
<BrandImg src="static/media/logo-header.svg" alt={alt} />
|
||||
);
|
||||
|
||||
export default BrandLogo;
|
||||
|
||||
@ -8,7 +8,7 @@ export default function useWebsocket(subscribeGroups) {
|
||||
ws.current = new WebSocket(
|
||||
`${window.location.protocol === 'http:' ? 'ws:' : 'wss:'}//${
|
||||
window.location.host
|
||||
}/websocket/`
|
||||
}${window.location.pathname}websocket/`
|
||||
);
|
||||
|
||||
const connect = () => {
|
||||
|
||||
@ -4,7 +4,7 @@ export default function connectJobSocket({ type, id }, onMessage) {
|
||||
ws = new WebSocket(
|
||||
`${window.location.protocol === 'http:' ? 'ws:' : 'wss:'}//${
|
||||
window.location.host
|
||||
}/websocket/`
|
||||
}${window.location.pathname}websocket/`
|
||||
);
|
||||
|
||||
ws.onopen = () => {
|
||||
|
||||
@ -33,7 +33,7 @@ import ErrorDetail from 'components/ErrorDetail';
|
||||
import { useSession } from 'contexts/Session';
|
||||
import { SESSION_REDIRECT_URL } from '../../constants';
|
||||
|
||||
const loginLogoSrc = '/static/media/logo-login.svg';
|
||||
const loginLogoSrc = 'static/media/logo-login.svg';
|
||||
|
||||
const Login = styled(PFLogin)`
|
||||
& .pf-c-brand {
|
||||
|
||||
@ -121,7 +121,7 @@ describe('<Login />', () => {
|
||||
});
|
||||
const { loginHeaderLogo } = await findChildren(wrapper);
|
||||
const { alt, src } = loginHeaderLogo.props();
|
||||
expect([alt, src]).toEqual(['AWX', '/static/media/logo-login.svg']);
|
||||
expect([alt, src]).toEqual(['AWX', 'static/media/logo-login.svg']);
|
||||
});
|
||||
|
||||
test('custom login info handled correctly', async () => {
|
||||
@ -152,7 +152,7 @@ describe('<Login />', () => {
|
||||
});
|
||||
const { loginHeaderLogo } = await findChildren(wrapper);
|
||||
const { alt, src } = loginHeaderLogo.props();
|
||||
expect([alt, src]).toEqual([null, '/static/media/logo-login.svg']);
|
||||
expect([alt, src]).toEqual([null, 'static/media/logo-login.svg']);
|
||||
expect(wrapper.find('AlertModal').length).toBe(1);
|
||||
});
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ function AnalyticsStep() {
|
||||
<Flex alignItems={{ default: 'alignItemsCenter' }}>
|
||||
<img
|
||||
width="300"
|
||||
src="/static/media/insights-analytics-dashboard.jpeg"
|
||||
src="static/media/insights-analytics-dashboard.jpeg"
|
||||
alt={t`Insights for Ansible Automation Platform dashboard`}
|
||||
/>
|
||||
<Button
|
||||
|
||||
19
tools/ansible/roles/dockerfile/files/uwsgi.ini
Normal file
19
tools/ansible/roles/dockerfile/files/uwsgi.ini
Normal file
@ -0,0 +1,19 @@
|
||||
[uwsgi]
|
||||
socket = 127.0.0.1:8050
|
||||
processes = 5
|
||||
master = true
|
||||
vacuum = true
|
||||
no-orphans = true
|
||||
lazy-apps = true
|
||||
manage-script-name = true
|
||||
master-fifo = /var/lib/awx/awxfifo
|
||||
max-requests = 1000
|
||||
buffer-size = 32768
|
||||
|
||||
if-env = UWSGI_MOUNT_PATH
|
||||
mount = %(_)=awx.wsgi:application
|
||||
endif =
|
||||
|
||||
if-not-env = UWSGI_MOUNT_PATH
|
||||
mount = /=awx.wsgi:application
|
||||
endif =
|
||||
@ -210,6 +210,7 @@ ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanima
|
||||
ADD tools/ansible/roles/dockerfile/files/launch_awx.sh /usr/bin/launch_awx.sh
|
||||
ADD tools/ansible/roles/dockerfile/files/launch_awx_task.sh /usr/bin/launch_awx_task.sh
|
||||
ADD tools/ansible/roles/dockerfile/files/settings.py /etc/tower/settings.py
|
||||
ADD tools/ansible/roles/dockerfile/files/uwsgi.ini /etc/tower/uwsgi.ini
|
||||
ADD {{ template_dest }}/supervisor.conf /etc/supervisord.conf
|
||||
ADD {{ template_dest }}/supervisor_task.conf /etc/supervisord_task.conf
|
||||
{% endif %}
|
||||
|
||||
@ -28,7 +28,7 @@ directory = /awx_devel
|
||||
environment =
|
||||
UWSGI_DEV_RELOAD_COMMAND='supervisorctl -c /etc/supervisord_task.conf restart all; supervisorctl restart tower-processes:daphne tower-processes:wsbroadcast'
|
||||
{% else %}
|
||||
command = /var/lib/awx/venv/awx/bin/uwsgi --socket 127.0.0.1:8050 --module=awx.wsgi:application --vacuum --processes=5 --harakiri=120 --no-orphans --master --max-requests=1000 --master-fifo=/var/lib/awx/awxfifo --lazy-apps -b 32768
|
||||
command = /var/lib/awx/venv/awx/bin/uwsgi /etc/tower/uwsgi.ini
|
||||
directory = /var/lib/awx
|
||||
{% endif %}
|
||||
autostart = true
|
||||
|
||||
@ -56,6 +56,7 @@ services:
|
||||
- "8013:8013" # http
|
||||
- "8043:8043" # https
|
||||
- "2222:2222" # receptor foo node
|
||||
- "3000:3001" # used by the UI dev env
|
||||
{% endif %}
|
||||
redis_{{ container_postfix }}:
|
||||
image: redis:latest
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user