Compare commits
35 Commits
avoid_reap
...
21.14.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32a5186eea | ||
|
|
bf98f62654 | ||
|
|
1f9925cf51 | ||
|
|
4bf8366687 | ||
|
|
21b4755587 | ||
|
|
b4163dd00f | ||
|
|
6908f415a1 | ||
|
|
746cd4bf77 | ||
|
|
39ea162aa9 | ||
|
|
5bd00adb59 | ||
|
|
28b1c62275 | ||
|
|
f3cdf368df | ||
|
|
4302348e8e | ||
|
|
cd6cb3352e | ||
|
|
d1895bb92e | ||
|
|
8d47644659 | ||
|
|
46227f14a1 | ||
|
|
2d114a4d16 | ||
|
|
7deddabea6 | ||
|
|
e15f4de0dd | ||
|
|
f558957538 | ||
|
|
fa3920d3a3 | ||
|
|
48a04bff5a | ||
|
|
c30760aaa9 | ||
|
|
3636c5e95e | ||
|
|
ae0d868681 | ||
|
|
edbed92c95 | ||
|
|
b75b098ee9 | ||
|
|
4f2f345e23 | ||
|
|
41a4551c91 | ||
|
|
229dbe0905 | ||
|
|
d137086870 | ||
|
|
f53aa2d26b | ||
|
|
42c848b57b | ||
|
|
64b0e09e87 |
3
.gitignore
vendored
@@ -161,3 +161,6 @@ use_dev_supervisor.txt
|
||||
/_build/
|
||||
/_build_kube_dev/
|
||||
/Dockerfile.kube-dev
|
||||
|
||||
awx/ui_next/src
|
||||
awx/ui_next/build
|
||||
|
||||
@@ -6,6 +6,7 @@ recursive-include awx/templates *.html
|
||||
recursive-include awx/api/templates *.md *.html *.yml
|
||||
recursive-include awx/ui/build *.html
|
||||
recursive-include awx/ui/build *
|
||||
recursive-include awx/ui_next/build *
|
||||
recursive-include awx/playbooks *.yml
|
||||
recursive-include awx/lib/site-packages *
|
||||
recursive-include awx/plugins *.ps1
|
||||
|
||||
14
Makefile
@@ -1,3 +1,5 @@
|
||||
-include awx/ui_next/Makefile
|
||||
|
||||
PYTHON ?= python3.9
|
||||
DOCKER_COMPOSE ?= docker-compose
|
||||
OFFICIAL ?= no
|
||||
@@ -418,7 +420,7 @@ ui-devel: awx/ui/node_modules
|
||||
cp -r awx/ui/build/static/css/* /var/lib/awx/public/static/css; \
|
||||
cp -r awx/ui/build/static/js/* /var/lib/awx/public/static/js; \
|
||||
cp -r awx/ui/build/static/media/* /var/lib/awx/public/static/media; \
|
||||
fi
|
||||
fi
|
||||
|
||||
ui-devel-instrumented: awx/ui/node_modules
|
||||
$(NPM_BIN) --prefix awx/ui --loglevel warn run start-instrumented
|
||||
@@ -445,11 +447,12 @@ ui-test-general:
|
||||
$(NPM_BIN) run --prefix awx/ui pretest
|
||||
$(NPM_BIN) run --prefix awx/ui/ test-general --runInBand
|
||||
|
||||
# NOTE: The make target ui-next is imported from awx/ui_next/Makefile
|
||||
HEADLESS ?= no
|
||||
ifeq ($(HEADLESS), yes)
|
||||
dist/$(SDIST_TAR_FILE):
|
||||
else
|
||||
dist/$(SDIST_TAR_FILE): $(UI_BUILD_FLAG_FILE)
|
||||
dist/$(SDIST_TAR_FILE): $(UI_BUILD_FLAG_FILE) ui-next
|
||||
endif
|
||||
$(PYTHON) -m build -s
|
||||
ln -sf $(SDIST_TAR_FILE) dist/awx.tar.gz
|
||||
@@ -497,8 +500,6 @@ docker-compose-sources: .git/hooks/pre-commit
|
||||
-e enable_prometheus=$(PROMETHEUS) \
|
||||
-e enable_grafana=$(GRAFANA) $(EXTRA_SOURCES_ANSIBLE_OPTS)
|
||||
|
||||
|
||||
|
||||
docker-compose: awx/projects docker-compose-sources
|
||||
$(DOCKER_COMPOSE) -f tools/docker-compose/_sources/docker-compose.yml $(COMPOSE_OPTS) up $(COMPOSE_UP_OPTS) --remove-orphans
|
||||
|
||||
@@ -654,3 +655,8 @@ help/generate:
|
||||
} \
|
||||
{ lastLine = $$0 }' $(MAKEFILE_LIST) | sort -u
|
||||
@printf "\n"
|
||||
|
||||
## Display help for ui-next targets
|
||||
help/ui-next:
|
||||
@make -s help MAKEFILE_LIST="awx/ui_next/Makefile"
|
||||
|
||||
|
||||
@@ -272,6 +272,9 @@ class ApiV2ConfigView(APIView):
|
||||
|
||||
pendo_state = settings.PENDO_TRACKING_STATE if settings.PENDO_TRACKING_STATE in ('off', 'anonymous', 'detailed') else 'off'
|
||||
|
||||
# Guarding against settings.UI_NEXT being set to a non-boolean value
|
||||
ui_next_state = settings.UI_NEXT if settings.UI_NEXT in (True, False) else False
|
||||
|
||||
data = dict(
|
||||
time_zone=settings.TIME_ZONE,
|
||||
license_info=license_data,
|
||||
@@ -280,6 +283,7 @@ class ApiV2ConfigView(APIView):
|
||||
analytics_status=pendo_state,
|
||||
analytics_collectors=all_collectors(),
|
||||
become_methods=PRIVILEGE_ESCALATION_METHODS,
|
||||
ui_next=ui_next_state,
|
||||
)
|
||||
|
||||
# If LDAP is enabled, user_ldap_fields will return a list of field
|
||||
|
||||
@@ -795,6 +795,16 @@ register(
|
||||
category_slug='bulk',
|
||||
)
|
||||
|
||||
register(
|
||||
'UI_NEXT',
|
||||
field_class=fields.BooleanField,
|
||||
default=False,
|
||||
label=_('Enable Preview of New User Interface'),
|
||||
help_text=_('Enable preview of new user interface.'),
|
||||
category=_('System'),
|
||||
category_slug='system',
|
||||
)
|
||||
|
||||
|
||||
def logging_validate(serializer, attrs):
|
||||
if not serializer.instance or not hasattr(serializer.instance, 'LOG_AGGREGATOR_HOST') or not hasattr(serializer.instance, 'LOG_AGGREGATOR_TYPE'):
|
||||
|
||||
@@ -70,7 +70,7 @@ def reap_waiting(instance=None, status='failed', job_explanation=None, grace_per
|
||||
reap_job(j, status, job_explanation=job_explanation)
|
||||
|
||||
|
||||
def reap(instance=None, status='failed', job_explanation=None, excluded_uuids=None):
|
||||
def reap(instance=None, status='failed', job_explanation=None, excluded_uuids=None, ref_time=None):
|
||||
"""
|
||||
Reap all jobs in running for this instance.
|
||||
"""
|
||||
@@ -79,9 +79,11 @@ def reap(instance=None, status='failed', job_explanation=None, excluded_uuids=No
|
||||
else:
|
||||
hostname = instance.hostname
|
||||
workflow_ctype_id = ContentType.objects.get_for_model(WorkflowJob).id
|
||||
jobs = UnifiedJob.objects.filter(
|
||||
Q(status='running') & (Q(execution_node=hostname) | Q(controller_node=hostname)) & ~Q(polymorphic_ctype_id=workflow_ctype_id)
|
||||
)
|
||||
base_Q = Q(status='running') & (Q(execution_node=hostname) | Q(controller_node=hostname)) & ~Q(polymorphic_ctype_id=workflow_ctype_id)
|
||||
if ref_time:
|
||||
jobs = UnifiedJob.objects.filter(base_Q & Q(started__lte=ref_time))
|
||||
else:
|
||||
jobs = UnifiedJob.objects.filter(base_Q)
|
||||
if excluded_uuids:
|
||||
jobs = jobs.exclude(celery_task_id__in=excluded_uuids)
|
||||
for j in jobs:
|
||||
|
||||
18
awx/main/migrations/0179_change_cyberark_plugin_names.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.2.16 on 2023-03-16 15:16
|
||||
from django.db import migrations
|
||||
|
||||
from awx.main.migrations._credentialtypes import migrate_credential_type
|
||||
from awx.main.models import CredentialType
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
def update_cyberark_plugin_names(apps, schema_editor):
|
||||
CredentialType.setup_tower_managed_defaults(apps)
|
||||
migrate_credential_type(apps, 'aim')
|
||||
migrate_credential_type(apps, 'conjur')
|
||||
|
||||
dependencies = [
|
||||
('main', '0178_instance_group_admin_migration'),
|
||||
]
|
||||
|
||||
operations = [migrations.RunPython(update_cyberark_plugin_names)]
|
||||
@@ -1,6 +1,9 @@
|
||||
import logging
|
||||
|
||||
from awx.main.models import CredentialType
|
||||
from django.db.models import Q
|
||||
|
||||
logger = logging.getLogger('awx.main.migrations')
|
||||
|
||||
DEPRECATED_CRED_KIND = {
|
||||
'rax': {
|
||||
@@ -76,3 +79,14 @@ def add_tower_verify_field(apps, schema_editor):
|
||||
def remove_become_methods(apps, schema_editor):
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def migrate_credential_type(apps, namespace):
|
||||
ns_types = apps.get_model('main', 'CredentialType').objects.filter(namespace=namespace).order_by('created')
|
||||
if ns_types.count() == 2:
|
||||
original, renamed = ns_types.all()
|
||||
logger.info(f'There are credential types to migrate in the "{namespace}" namespace: {original.name}')
|
||||
apps.get_model('main', 'Credential').objects.filter(credential_type_id=original.id).update(credential_type_id=renamed.id)
|
||||
|
||||
logger.info(f'Removing old credential type: {renamed.name}')
|
||||
original.delete()
|
||||
|
||||
@@ -831,6 +831,9 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_job_template_id'.format(name)] = self.job_template.pk
|
||||
r['{}_job_template_name'.format(name)] = self.job_template.name
|
||||
if self.execution_node:
|
||||
for name in JOB_VARIABLE_PREFIXES:
|
||||
r['{}_execution_node'.format(name)] = self.execution_node
|
||||
return r
|
||||
|
||||
'''
|
||||
|
||||
@@ -581,7 +581,7 @@ def cluster_node_heartbeat(dispatch_time=None, worker_tasks=None):
|
||||
active_task_ids = []
|
||||
for task_list in worker_tasks.values():
|
||||
active_task_ids.extend(task_list)
|
||||
reaper.reap(instance=this_inst, excluded_uuids=active_task_ids)
|
||||
reaper.reap(instance=this_inst, excluded_uuids=active_task_ids, ref_time=datetime.fromisoformat(dispatch_time))
|
||||
if max(len(task_list) for task_list in worker_tasks.values()) <= 1:
|
||||
reaper.reap_waiting(instance=this_inst, excluded_uuids=active_task_ids, ref_time=datetime.fromisoformat(dispatch_time))
|
||||
|
||||
|
||||
@@ -337,6 +337,8 @@ class TestTaskPublisher:
|
||||
|
||||
|
||||
yesterday = tz_now() - datetime.timedelta(days=1)
|
||||
minute = tz_now() - datetime.timedelta(seconds=120)
|
||||
now = tz_now()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -379,13 +381,15 @@ class TestJobReaper(object):
|
||||
assert job.status == status
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'excluded_uuids, fail',
|
||||
'excluded_uuids, fail, started',
|
||||
[
|
||||
(['abc123'], False),
|
||||
([], True),
|
||||
(['abc123'], False, None),
|
||||
([], False, None),
|
||||
([], True, minute),
|
||||
],
|
||||
)
|
||||
def test_do_not_reap_excluded_uuids(self, excluded_uuids, fail):
|
||||
def test_do_not_reap_excluded_uuids(self, excluded_uuids, fail, started):
|
||||
"""Modified Test to account for ref_time in reap()"""
|
||||
i = Instance(hostname='awx')
|
||||
i.save()
|
||||
j = Job(
|
||||
@@ -396,10 +400,13 @@ class TestJobReaper(object):
|
||||
celery_task_id='abc123',
|
||||
)
|
||||
j.save()
|
||||
if started:
|
||||
Job.objects.filter(id=j.id).update(started=started)
|
||||
|
||||
# if the UUID is excluded, don't reap it
|
||||
reaper.reap(i, excluded_uuids=excluded_uuids)
|
||||
reaper.reap(i, excluded_uuids=excluded_uuids, ref_time=now)
|
||||
job = Job.objects.first()
|
||||
|
||||
if fail:
|
||||
assert job.status == 'failed'
|
||||
assert 'marked as failed' in job.job_explanation
|
||||
@@ -415,3 +422,20 @@ class TestJobReaper(object):
|
||||
reaper.reap(i)
|
||||
|
||||
assert WorkflowJob.objects.first().status == 'running'
|
||||
|
||||
def test_should_not_reap_new(self):
|
||||
"""
|
||||
This test is designed specifically to ensure that jobs that are launched after the dispatcher has provided a list of UUIDs aren't reaped.
|
||||
It is very racy and this test is designed with that in mind
|
||||
"""
|
||||
i = Instance(hostname='awx')
|
||||
# ref_time is set to 10 seconds in the past to mimic someone launching a job in the heartbeat window.
|
||||
ref_time = tz_now() - datetime.timedelta(seconds=10)
|
||||
# creating job at current time
|
||||
job = Job.objects.create(status='running', controller_node=i.hostname)
|
||||
reaper.reap(i, ref_time=ref_time)
|
||||
# explictly refreshing from db to ensure up to date cache
|
||||
job.refresh_from_db()
|
||||
assert job.started > ref_time
|
||||
assert job.status == 'running'
|
||||
assert job.job_explanation == ''
|
||||
|
||||
@@ -107,7 +107,11 @@ class TestMetaVars:
|
||||
result_hash['{}_user_id'.format(name)] = 47
|
||||
result_hash['{}_inventory_id'.format(name)] = 45
|
||||
result_hash['{}_inventory_name'.format(name)] = 'example-inv'
|
||||
assert Job(name='fake-job', pk=42, id=42, launch_type='manual', created_by=maker, inventory=inv).awx_meta_vars() == result_hash
|
||||
result_hash['{}_execution_node'.format(name)] = 'example-exec-node'
|
||||
assert (
|
||||
Job(name='fake-job', pk=42, id=42, launch_type='manual', created_by=maker, inventory=inv, execution_node='example-exec-node').awx_meta_vars()
|
||||
== result_hash
|
||||
)
|
||||
|
||||
def test_project_update_metavars(self):
|
||||
data = Job(
|
||||
|
||||
@@ -85,7 +85,11 @@ USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'ui', 'build', 'static'), os.path.join(BASE_DIR, 'static')]
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'ui', 'build', 'static'),
|
||||
os.path.join(BASE_DIR, 'ui_next', 'build'),
|
||||
os.path.join(BASE_DIR, 'static'),
|
||||
]
|
||||
|
||||
# Absolute filesystem path to the directory where static file are collected via
|
||||
# the collectstatic command.
|
||||
@@ -299,7 +303,12 @@ TEMPLATES = [
|
||||
],
|
||||
'builtins': ['awx.main.templatetags.swagger'],
|
||||
},
|
||||
'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'ui', 'build'), os.path.join(BASE_DIR, 'ui', 'public')],
|
||||
'DIRS': [
|
||||
os.path.join(BASE_DIR, 'templates'),
|
||||
os.path.join(BASE_DIR, 'ui', 'build'),
|
||||
os.path.join(BASE_DIR, 'ui', 'public'),
|
||||
os.path.join(BASE_DIR, 'ui_next', 'build', 'awx'),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1017,3 +1026,5 @@ AWX_MOUNT_ISOLATED_PATHS_ON_K8S = False
|
||||
|
||||
# This is overridden downstream via /etc/tower/conf.d/cluster_host_id.py
|
||||
CLUSTER_HOST_ID = socket.gethostname()
|
||||
|
||||
UI_NEXT = True
|
||||
|
||||
@@ -148,6 +148,16 @@ register(
|
||||
placeholder=['username', 'email'],
|
||||
)
|
||||
|
||||
register(
|
||||
'SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL',
|
||||
field_class=fields.BooleanField,
|
||||
default=False,
|
||||
label=_('Use Email address for usernames'),
|
||||
help_text=_('Enabling this setting will tell social auth to use the full Email as username instead of the full name'),
|
||||
category=_('Authentication'),
|
||||
category_slug='authentication',
|
||||
)
|
||||
|
||||
###############################################################################
|
||||
# LDAP AUTHENTICATION SETTINGS
|
||||
###############################################################################
|
||||
|
||||
BIN
awx/ui/public/static/media/192.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
awx/ui/public/static/media/256.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
awx/ui/public/static/media/384.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
awx/ui/public/static/media/512.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
awx/ui/public/static/media/brand-logo.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
232
awx/ui/public/static/media/brand-logo.svg
Normal file
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{display:none;}
|
||||
.st1{display:inline;fill:#ED1C24;}
|
||||
.st2{fill:#42210B;}
|
||||
.st3{fill:#FFFFFF;}
|
||||
.st4{fill:#C69C6D;stroke:#8C6239;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st5{fill:#FFFFFF;stroke:#42210B;stroke-width:3;stroke-miterlimit:10;}
|
||||
.st6{fill:#ED1C24;stroke:#8C6239;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st7{fill:#A67C52;}
|
||||
.st8{fill:#ED1C24;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<path class="st1" d="M319.8,169.3c1.5-14.2,13.7-27.2,29.9-31.9c-13.1,1.5-27.3-1.7-36-10c-8.7-8.3-10-21.9-1.4-30.1
|
||||
c-12,6.7-28.1,8.1-41.4,3.4c-13.3-4.6-23.5-15.1-26.2-26.9c-2-8.8,0-17.9,2-26.7c-6.2,9.4-17.6,17.3-30.5,17.3
|
||||
c-12.9,0.1-25.7-10.2-22.9-20.7c-5.5,7.8-11.4,15.9-21,20.2c-9.5,4.3-23.7,2.7-28.2-5.5c-1.6,10.8-7.5,22-19.1,27
|
||||
c-9,3.9-21.5,2.2-28-3.8c5.7,11.4,4.3,25.3-4.1,35.6c-9.9,12.2-29.1,18.6-46.4,15.6c14.7,7.2,28.5,17.7,32.1,31.5
|
||||
c3.7,13.8-7.1,30.7-24.1,31.7c13.6,3.1,28,7.4,35.6,17.2c7.6,9.8,2.9,26.4-11.1,28c12.8-2.6,27.4,3.9,31.9,14.2
|
||||
c4.1,9.5-0.9,20.9-10.9,26.5c18.6-8.9,41-17.1,59.6-8.8c13.9,6.2,20.8,21.6,15.1,33.8c10.4-10.6,23-21.3,39.2-23.5
|
||||
c12.8-1.8,27.5,4.6,31.9,14.1c-0.3-12.7,6.1-25.5,17.5-34c13.8-10.3,34.4-14,52-9.2c-11.1-7.8-14.9-22-8.9-33
|
||||
c6-11,21.3-18,35.7-16.2C327.5,198.1,318.3,183.5,319.8,169.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M179.7,297.3c-10.1,3.2-20.3,6-30.6,8.4c-10.7,2.5-21.7,5-32.8,5.1C96,311.1,79.9,297.2,60,296.1
|
||||
c-5.8-0.3-5.8,8.7,0,9c9.9,0.5,18.9,5.1,27.9,8.8c9.8,4,19.6,6.3,30.2,5.9c21.5-0.8,43.5-7.4,64-13.8
|
||||
C187.6,304.3,185.2,295.6,179.7,297.3L179.7,297.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M322.2,194.8c17.9-8,36-18.5,44.3-37.2c4.2-9.3,6-19.2,7.2-29.3c1.5-11.7,2.5-23.4,3.7-35.2
|
||||
c0.6-5.8-8.4-5.7-9,0c-1.1,10.3-2.1,20.6-3.3,30.9c-1.1,9.7-2.5,19.7-6.4,28.7c-7.5,17.5-24.6,26.8-41.2,34.2
|
||||
C312.4,189.4,316.9,197.2,322.2,194.8L322.2,194.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<ellipse transform="matrix(0.5541 -0.8324 0.8324 0.5541 -219.4917 376.0051)" class="st2" cx="241.2" cy="392.9" rx="65.5" ry="33.7"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M224.1,442.5c22-11.5,38.7-31,47.1-54.3c2-5.5-6.7-7.8-8.7-2.4c-7.6,21.1-23.1,38.5-43,48.9
|
||||
C214.4,437.4,218.9,445.1,224.1,442.5L224.1,442.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<ellipse transform="matrix(0.9684 -0.2494 0.2494 0.9684 -66.4734 109.0276)" class="st2" cx="397" cy="316.8" rx="63.9" ry="32.9"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M363.8,341.5c28.3,7,58.7-0.8,80.2-20.5c4.3-3.9-2.1-10.3-6.4-6.4c-19.1,17.5-46.4,24.4-71.5,18.2
|
||||
C360.5,331.5,358.1,340.1,363.8,341.5L363.8,341.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st4" d="M156.9,96c-25.4,4.5-32.9,20.2-45,46.9c-20.2,44.4,2,90.3,5.6,97.5c18.4,36.5,42.3,36.8,60,80.6
|
||||
c8.6,21.2,4.6,25.2,13.1,37.5c20.4,29.2,63.7,36.1,91.9,33.8c40.3-3.3,91.5-28.8,108.8-82.5c17.1-53.2-6-112.1-41.2-131.2
|
||||
c-25.3-13.7-44.9-0.5-71.2-20.6c-21.6-16.5-18.4-33.1-37.5-48.8C227.9,98.1,203.7,87.7,156.9,96z"/>
|
||||
<ellipse transform="matrix(0.6622 -0.7494 0.7494 0.6622 65.2068 309.6339)" class="st2" cx="376" cy="82.5" rx="21" ry="15.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M379.8,75.3c0.8,0.2-0.6-0.4-0.1-0.1c0.2,0.1,0.3,0.2,0.5,0.3c0.4,0.2-0.6-0.7-0.1-0.1
|
||||
c0.1,0.1,0.7,0.8,0.2,0.2c-0.4-0.5,0,0,0.1,0.1c0.4,0.7,0,0.2,0-0.2c0,0.1,0.1,0.4,0.2,0.5c0.3,0.9-0.1-1,0-0.1
|
||||
c0.1,2.3,2,4.6,4.5,4.5c2.3-0.1,4.6-2,4.5-4.5c-0.3-4.4-3-8.1-7.3-9.4c-2.2-0.7-5,0.8-5.5,3.1C376.1,72.2,377.4,74.5,379.8,75.3
|
||||
L379.8,75.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<ellipse transform="matrix(0.9999 -1.433736e-02 1.433736e-02 0.9999 -4.303 0.8051)" class="st2" cx="54" cy="300.5" rx="21" ry="15.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M52.2,297.5c1.1-0.3,1.4-0.4,2.5,0c0.8,0.3,1.3,0.7,2,1.7c1.5,1.9,4.8,1.6,6.4,0c1.9-1.9,1.5-4.4,0-6.4
|
||||
c-3.1-3.9-8.6-5.4-13.3-4C44.3,290.5,46.7,299.2,52.2,297.5L52.2,297.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M149.3,108.8c4.9-10.8-1.3-24.2-12.9-26.9c-1.9-0.4-2.7,2.4-0.8,2.9c9.6,2.3,15.3,13.5,11.2,22.5
|
||||
C145.9,109,148.5,110.5,149.3,108.8L149.3,108.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M141.2,112.3c2.4-9.4-5.4-19.3-15.2-19c-1.9,0.1-1.9,3.1,0,3c7.8-0.2,14.2,7.6,12.3,15.2
|
||||
C137.8,113.4,140.7,114.2,141.2,112.3L141.2,112.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M132.6,118c-1.1-8.3-10.9-13.4-18.2-9.1c-1.7,1-0.2,3.6,1.5,2.6c5.2-3,12.9,0.4,13.7,6.5
|
||||
C129.8,119.9,132.8,119.9,132.6,118L132.6,118z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st5" d="M215.5,166.5l34-73c0,0,35,0,46,21c7.5,14.3,8,39,8,39L215.5,166.5z"/>
|
||||
<path class="st5" d="M208.2,170.5l-79.5-12.7c0,0-19.6,29-8.4,49.9c7.6,14.2,27.8,28.5,27.8,28.5L208.2,170.5z"/>
|
||||
<path class="st2" d="M210.5,164.5l33-74c0,0-2.5-5.5-8-7s-12,0-12,0L210.5,164.5z"/>
|
||||
<path class="st2" d="M207.4,165.3l-73.1-35c0,0-5.6,2.4-7.2,7.8c-1.6,5.5-0.3,12-0.3,12L207.4,165.3z"/>
|
||||
<path d="M215.5,166.5L234,127c0,0,17-6,25.5,7.5c8.6,13.6-3.5,25.5-3.5,25.5L215.5,166.5z"/>
|
||||
<path d="M206.7,170.9l-29.6,32c0,0-18,0.5-22-14.9c-4-15.6,11.1-23.2,11.1-23.2L206.7,170.9z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M243.4,139.1c-0.6,0.2-0.7,0.3-0.4,0.2c0.3-0.1,0.2-0.1-0.5,0.1c0.7,0-0.3,0-0.4-0.1c0.1,0,0.3,0.1,0.4,0.1
|
||||
c0.3,0.1,0.2,0-0.4-0.2c0,0,0.6,0.3,0.6,0.3c0.5,0.2-0.9-0.6-0.1-0.1c0.6,0.4-0.3-0.5-0.1-0.1c0.3,0.5-0.3-1-0.1-0.2
|
||||
c0.2,0.8,0-1,0-0.1c0,2.4,2.1,4.6,4.5,4.5c2.5-0.1,4.5-2,4.5-4.5c0-3-1.6-5.7-4.1-7.3c-2.6-1.7-5.6-1.6-8.4-0.4
|
||||
c-2.2,0.9-2.8,4.3-1.6,6.2C238.7,139.7,241,140.1,243.4,139.1L243.4,139.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M173.5,176.4c-0.5-0.3-0.1,0,0.2,0.1c-0.7-0.6,0.3,0.5,0.1,0c-0.3-0.5,0.4,0.8,0.1,0.2
|
||||
c-0.4-0.8,0.2,0.2,0,0.1c0,0,0-0.6,0-0.6c-0.1,0.1-0.1,1,0,0.3c-0.1,0.2-0.1,0.3-0.2,0.5c0.2-0.3,0.2-0.4,0-0.1
|
||||
c-0.2,0.2-0.2,0.3-0.1,0.1c0.2-0.2,0.1-0.2-0.3,0.2c1.9-1.4,3-4,1.6-6.2c-1.2-1.9-4.1-3.1-6.2-1.6c-2.4,1.7-4,4.3-3.9,7.4
|
||||
c0.1,3,1.6,5.7,4.1,7.3c2,1.2,5,0.5,6.2-1.6C176.3,180.4,175.7,177.7,173.5,176.4L173.5,176.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<ellipse transform="matrix(0.862 -0.5069 0.5069 0.862 -88.3186 186.5516)" class="st6" cx="298.5" cy="255.5" rx="79.5" ry="68.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M173.6,109.8c-2.1,2-3.9,4.6-3.6,7.6c0.3,3.5,2.8,6.6,6.6,6.7c6,0.2,11.5-7.7,8.2-13c-1-1.7-3.1-3.1-5.2-3
|
||||
c-1.7,0.1-3.1,0.8-4.4,1.9c-2,1.8-2.8,5.2-1.9,7.7c2.4,6.6,11.8,5.9,13.8-0.7c0.7-2.5-0.9-5.6-3.5-6.2c-2.7-0.6-5.4,0.8-6.2,3.5
|
||||
c0.6-2.1,3.1-2.6,4.6-1c0.8,0.9,1,1.8,0.8,2.8c0.2-0.5,0.1-0.4-0.1,0.3c-0.4,0.7-1,1.2-1.8,1.4c-0.9,0-1.8,0-2.7,0
|
||||
c-1.8-0.6-2.5-1.6-2.3-3.1c-0.1-0.4-0.1-0.7,0.1-1c0.2-0.3,0.1-0.3-0.1,0.1c0.1-0.1,0.2-0.2,0.3-0.4c-0.2,0.3-0.5,0.5-0.7,0.8
|
||||
c-0.1,0.1-0.2,0.2-0.3,0.3c-0.3,0.2-0.2,0.2,0.1-0.1c1.3,0.2,2.6,0.4,3.9,0.6c0.2,0.4,0.5,0.9,0.7,1.3c0.2,0.6-0.2,0.9-0.2,1.4
|
||||
c0,0.4,0.4-0.5-0.1,0.1c0.3-0.4,0.6-0.7,1-1c1.9-1.8,2-5.3,0-7.1C178.7,107.9,175.6,107.8,173.6,109.8L173.6,109.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M151.2,248.6c-5.7,7,1.7,16.9,10,13.3c3.4-1.5,6.3-5,6.3-8.9c0-4.2-2.7-7.6-7-7.8c-3.1-0.1-5.8,3.3-4.8,6.3
|
||||
c1.2,3.4,3.7,6.1,7.3,7c2.6,0.6,5.4-0.8,6.2-3.5c0.7-2.5-0.9-5.5-3.5-6.2c-1.7-0.4,0,0.1-0.2,0.1c-0.4,0-0.4-0.8-0.1-0.1
|
||||
c-1.6,2.1-3.2,4.2-4.8,6.3c-2.4-0.1-2.8-1.1-3-2.6c0.1,0.7-0.1,0.2,0.1-0.1c0.7-0.9-0.5,0.5,0,0c-0.5,0.5-0.3,0.1-0.2,0.2
|
||||
c0.1,0,0.6,0,0.7,0c0.4,0.1,0.5,0.4,0.8,0.6c0.2,0.3,0.2,0.2-0.1-0.2c0.1,0.1,0.1,0.3,0.2,0.4c0,1,0.1,1.1-0.7,2.1
|
||||
c1.7-2.1,2-5,0-7.1C156.5,246.8,152.9,246.5,151.2,248.6L151.2,248.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M204.1,205.7c0.8,4.8,5.3,8.6,10.1,8.6c5.1,0,9.5-3.9,10.3-8.9c0.7-4.4-0.2-12.1-5.3-13.6
|
||||
c-2.7-0.8-5.2,0.5-7,2.4c-1.1,1.2-1.5,1.7-3.1,1.2c0.7,2.8,1.5,5.6,2.2,8.4c0.2-0.2-0.5,0.2-0.5,0.2c6.3,1.4,8.9-8.2,2.7-9.6
|
||||
c-3.5-0.8-6.6,0-9.3,2.4c-3,2.6-1.1,7.2,2.2,8.4c2.6,0.9,5.5,0.8,8-0.2c1.3-0.5,2.4-1.2,3.4-2.1c0.4-0.3,0.7-0.6,1-1
|
||||
c0.2-0.3,0.4-0.5,0.6-0.7c0.4-0.4,0.3-0.4-0.5,0.3c-0.9,0-1.8,0-2.7,0c0.2,0.1,0.3,0.1,0.5,0.2c-0.7-0.4-1.5-0.9-2.2-1.3
|
||||
c0.1,0.2,0.3,0.3,0.4,0.5c-0.4-0.7-0.9-1.5-1.3-2.2c0.4,1.2,0.8,2.5,1,3.7c0,0.4,0,0.8,0,1.2c0,0.5-0.5,0.9,0,0.4
|
||||
c-0.8,0.6-0.9,0.2-1.1-0.9c-0.4-2.7-3.8-4.1-6.2-3.5C204.7,200.3,203.7,203,204.1,205.7L204.1,205.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M265.9,179.6c0.2,0.4,0.5,0.9,0.7,1.3c0.6,1.1,1.8,2,3,2.3c1.2,0.3,2.8,0.2,3.9-0.5c1.1-0.7,2-1.7,2.3-3
|
||||
c0.3-1.4,0.1-2.6-0.5-3.9c-0.2-0.4-0.5-0.9-0.7-1.3c-0.6-1.1-1.8-2-3-2.3c-1.2-0.3-2.8-0.2-3.9,0.5c-1.1,0.7-2,1.7-2.3,3
|
||||
C265.1,177.1,265.3,178.3,265.9,179.6L265.9,179.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M200.4,295.8c-6.1,1.6-8.1,8.6-5,13.7c2.8,4.7,9.1,7.2,14.3,5.4c4.9-1.7,7.8-7.1,6.3-12.2
|
||||
c-0.8-2.7-2.7-4.8-5.3-5.8c-1.4-0.5-2.8-0.7-4.2-0.8c-0.1,0-0.9-0.1-0.9-0.1c0.2-0.4,1.2,2.5,0.9,0.7c0,0.9,0,1.8,0,2.7
|
||||
c-0.1,0.1-0.1,0.1-0.2,0.2c3.1-5.6-5.5-10.7-8.6-5c-1.7,3-1.1,6.6,1.4,9c1.3,1.2,2.8,2,4.5,2.3c0.8,0.1,1.6,0.2,2.4,0.3
|
||||
c0.4,0,0.7,0,1.1,0.1c0.2,0.1,0.1,0.1-0.2-0.1c0,0.1-0.6-0.5-0.6-0.5c-0.1-0.1-0.1-0.2,0-0.3c0.1-0.3,0.1-0.1-0.1,0.5
|
||||
c-0.3-0.1,0.7-0.2-0.3-0.3c-0.9-0.1-1.1-0.6-1.8-0.9c0,0-0.2-0.3-0.3-0.3c0.3,0-0.8,1.2-0.8,1.2
|
||||
C209.3,303.8,206.6,294.2,200.4,295.8L200.4,295.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M244.8,355.3c-4-6.2-11.2-2.3-12,3.9c-0.8,5.9,1.8,12,6.5,15.6c4.5,3.5,11.5,4.9,16.7,2.1
|
||||
c6.4-3.3,5.4-9.8,4.9-15.9c-0.5-6.3-1.9-12-9.5-12.1c-5.1-0.1-13.1,0.2-14.5,6.4c-1.2,5.4,2.5,12.8,8.2,13.8
|
||||
c6.2,1.1,11.2-5.5,7.8-11c-2.2-3.5-8.1-3.1-9.1,1.2c-1.1,4.4,0.5,8,4.1,10.6c5.2,3.8,10.2-4.8,5-8.6c0.2,0.2,0.4,0.5,0.5,0.7
|
||||
c-3,0.4-6.1,0.8-9.1,1.2c-0.4-0.7,3.4-3.1,2.9-4.8c-0.8-2.6-1.7,1.4-1.9,1.1c0,0.1,5.2-0.1,5.6-0.4c0.7,0.1,0.8-0.1,0.2-0.6
|
||||
c-0.4-0.7-0.5-0.8-0.4-0.3c-0.2,0.3,0.2,1.9,0.2,2.3c0.2,2,0.3,4,0.5,5.9c0.1,1.6,0.4,1.7-1.1,2c-1.3,0.2-2.9-0.3-4-0.9
|
||||
c-1.4-0.8-2.5-2-3.1-3.5c-0.3-0.7-0.4-1.3-0.5-2c0-0.3-0.1-0.7,0-1c0.2-1.9-1.1-1.5-3.8,1.2c-1-0.8-2-1.5-3-2.3
|
||||
c0.1,0.2,0.2,0.4,0.4,0.6C239.6,365.7,248.3,360.7,244.8,355.3L244.8,355.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M336.5,337.4c-2.4-1.5-5.1-2.5-7.9-1.8c-2.7,0.7-4.9,3.2-5.3,6c-0.9,6.4,6.3,8.3,11.2,8.4
|
||||
c4.8,0.1,10.6-2.4,10.9-7.9c0.2-5.6-5.5-9.6-10.6-6.9c-5.7,3-0.7,11.6,5,8.6c-0.1,0.1-0.2,0.1-0.3,0.2c-0.9,0-1.8,0-2.7,0
|
||||
c-2.1-0.4-1.4-4.8-0.3-4.3c0,0-1.3,0.3-1.3,0.3c-0.6,0-1.2,0-1.8-0.1c-0.5-0.1-1-0.2-1.5-0.4c-1.2-0.5-1-0.2,0.6,0.7
|
||||
c0.2,0.8,0.5,1.7,0.7,2.5c-3.4,1.1-4.4,1.9-2.8,2.7c0.4,0.2,0.7,0.4,1.1,0.7C336.9,349.6,341.9,340.9,336.5,337.4L336.5,337.4z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st3" d="M224.3,256.5L252,273v-40l32,20v-38l28,17l4-28l23,12l-3-24c0,0-14-8-35.5-6.4c-11.6,0.9-24.3,6.8-33.5,11.4
|
||||
c-14,7-23.7,18.9-31.2,29.1C227,238,224.3,256.5,224.3,256.5z"/>
|
||||
<path class="st3" d="M372.9,248.9l-28.8-14.5l2.9,39.9l-33.3-17.7l2.7,37.9l-29.1-15l-2,28.2l-23.8-10.3l4.7,23.7
|
||||
c0,0,14.5,7,35.9,3.8c11.5-1.7,23.7-8.5,32.6-13.8c13.5-8,22.3-20.5,29-31.2C371.5,267.5,372.9,248.9,372.9,248.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M235.2,121.6c8.5-3.1,23.2-0.1,27.8,8.4c2.3,4.4,4.5,9.9,4.5,14.9c0.1,5.5-2.7,10.5-5.3,15.3
|
||||
c-1.5,2.8,2.8,5.4,4.3,2.5c3.1-5.8,6.3-11.9,6-18.7c-0.3-6-2.8-12.8-5.9-17.9c-6-9.5-22.6-13.1-32.7-9.4
|
||||
C230.9,117.8,232.2,122.7,235.2,121.6L235.2,121.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M241.1,110.5c11.6-2.3,25.6,2.3,32.2,12.4c6.6,10.2,6.1,22.8,3.1,34.2c-1.3,5,6.4,7.1,7.7,2.1
|
||||
c3.8-14.3,3.8-30.3-5.5-42.6c-8.9-11.7-25.5-16.6-39.6-13.8C233.9,103.8,236.1,111.5,241.1,110.5L241.1,110.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M245.4,97.5c7.8-1.8,15.5,0,22.9,2.8c7.2,2.7,15,6.1,20.3,11.8c10.7,11.7,9.5,29.3,8.7,44
|
||||
c-0.3,6.4,9.7,6.4,10,0c1-17.9,1.2-38.5-12.7-52.1c-6.4-6.3-15.3-10.2-23.6-13.3c-9.1-3.4-18.6-4.9-28.2-2.8
|
||||
C236.5,89.2,239.1,98.9,245.4,97.5L245.4,97.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M155.8,158.5c-13.1,4.8-14.2,21.6-10.1,33.1c4.3,12,15.2,20.6,28.2,20.5c3.2,0,3.2-5,0-5
|
||||
c-9.9,0.1-18.6-5.9-22.6-14.9c-3.9-8.6-5.2-24.8,5.8-28.9C160.2,162.3,158.9,157.4,155.8,158.5L155.8,158.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M164.1,216.5c-11.4-2.2-18.8-11.4-22.7-21.9c-3.6-9.6-7.7-25.3,1.2-33.1c3.9-3.4-1.8-9-5.7-5.7
|
||||
c-11.3,9.9-7.9,28.5-3.3,40.9c4.8,13,14.1,24.7,28.3,27.5C167,225.2,169.1,217.5,164.1,216.5L164.1,216.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M152,231.7c-27.3-13.3-38.1-46.5-23.3-73.2c3.1-5.6-5.5-10.7-8.6-5c-17.3,31.2-5.3,71.1,26.9,86.9
|
||||
C152.7,243.1,157.8,234.5,152,231.7L152,231.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
BIN
awx/ui/public/static/media/brand-logo192.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
awx/ui/public/static/media/favicon.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
232
awx/ui/public/static/media/favicon.svg
Normal file
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{display:none;}
|
||||
.st1{display:inline;fill:#ED1C24;}
|
||||
.st2{fill:#42210B;}
|
||||
.st3{fill:#FFFFFF;}
|
||||
.st4{fill:#C69C6D;stroke:#8C6239;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st5{fill:#FFFFFF;stroke:#42210B;stroke-width:3;stroke-miterlimit:10;}
|
||||
.st6{fill:#ED1C24;stroke:#8C6239;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st7{fill:#A67C52;}
|
||||
.st8{fill:#ED1C24;}
|
||||
</style>
|
||||
<g class="st0">
|
||||
<path class="st1" d="M319.8,169.3c1.5-14.2,13.7-27.2,29.9-31.9c-13.1,1.5-27.3-1.7-36-10c-8.7-8.3-10-21.9-1.4-30.1
|
||||
c-12,6.7-28.1,8.1-41.4,3.4c-13.3-4.6-23.5-15.1-26.2-26.9c-2-8.8,0-17.9,2-26.7c-6.2,9.4-17.6,17.3-30.5,17.3
|
||||
c-12.9,0.1-25.7-10.2-22.9-20.7c-5.5,7.8-11.4,15.9-21,20.2c-9.5,4.3-23.7,2.7-28.2-5.5c-1.6,10.8-7.5,22-19.1,27
|
||||
c-9,3.9-21.5,2.2-28-3.8c5.7,11.4,4.3,25.3-4.1,35.6c-9.9,12.2-29.1,18.6-46.4,15.6c14.7,7.2,28.5,17.7,32.1,31.5
|
||||
c3.7,13.8-7.1,30.7-24.1,31.7c13.6,3.1,28,7.4,35.6,17.2c7.6,9.8,2.9,26.4-11.1,28c12.8-2.6,27.4,3.9,31.9,14.2
|
||||
c4.1,9.5-0.9,20.9-10.9,26.5c18.6-8.9,41-17.1,59.6-8.8c13.9,6.2,20.8,21.6,15.1,33.8c10.4-10.6,23-21.3,39.2-23.5
|
||||
c12.8-1.8,27.5,4.6,31.9,14.1c-0.3-12.7,6.1-25.5,17.5-34c13.8-10.3,34.4-14,52-9.2c-11.1-7.8-14.9-22-8.9-33
|
||||
c6-11,21.3-18,35.7-16.2C327.5,198.1,318.3,183.5,319.8,169.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M179.7,297.3c-10.1,3.2-20.3,6-30.6,8.4c-10.7,2.5-21.7,5-32.8,5.1C96,311.1,79.9,297.2,60,296.1
|
||||
c-5.8-0.3-5.8,8.7,0,9c9.9,0.5,18.9,5.1,27.9,8.8c9.8,4,19.6,6.3,30.2,5.9c21.5-0.8,43.5-7.4,64-13.8
|
||||
C187.6,304.3,185.2,295.6,179.7,297.3L179.7,297.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M322.2,194.8c17.9-8,36-18.5,44.3-37.2c4.2-9.3,6-19.2,7.2-29.3c1.5-11.7,2.5-23.4,3.7-35.2
|
||||
c0.6-5.8-8.4-5.7-9,0c-1.1,10.3-2.1,20.6-3.3,30.9c-1.1,9.7-2.5,19.7-6.4,28.7c-7.5,17.5-24.6,26.8-41.2,34.2
|
||||
C312.4,189.4,316.9,197.2,322.2,194.8L322.2,194.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<ellipse transform="matrix(0.5541 -0.8324 0.8324 0.5541 -219.4917 376.0051)" class="st2" cx="241.2" cy="392.9" rx="65.5" ry="33.7"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M224.1,442.5c22-11.5,38.7-31,47.1-54.3c2-5.5-6.7-7.8-8.7-2.4c-7.6,21.1-23.1,38.5-43,48.9
|
||||
C214.4,437.4,218.9,445.1,224.1,442.5L224.1,442.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<ellipse transform="matrix(0.9684 -0.2494 0.2494 0.9684 -66.4734 109.0276)" class="st2" cx="397" cy="316.8" rx="63.9" ry="32.9"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M363.8,341.5c28.3,7,58.7-0.8,80.2-20.5c4.3-3.9-2.1-10.3-6.4-6.4c-19.1,17.5-46.4,24.4-71.5,18.2
|
||||
C360.5,331.5,358.1,340.1,363.8,341.5L363.8,341.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st4" d="M156.9,96c-25.4,4.5-32.9,20.2-45,46.9c-20.2,44.4,2,90.3,5.6,97.5c18.4,36.5,42.3,36.8,60,80.6
|
||||
c8.6,21.2,4.6,25.2,13.1,37.5c20.4,29.2,63.7,36.1,91.9,33.8c40.3-3.3,91.5-28.8,108.8-82.5c17.1-53.2-6-112.1-41.2-131.2
|
||||
c-25.3-13.7-44.9-0.5-71.2-20.6c-21.6-16.5-18.4-33.1-37.5-48.8C227.9,98.1,203.7,87.7,156.9,96z"/>
|
||||
<ellipse transform="matrix(0.6622 -0.7494 0.7494 0.6622 65.2068 309.6339)" class="st2" cx="376" cy="82.5" rx="21" ry="15.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M379.8,75.3c0.8,0.2-0.6-0.4-0.1-0.1c0.2,0.1,0.3,0.2,0.5,0.3c0.4,0.2-0.6-0.7-0.1-0.1
|
||||
c0.1,0.1,0.7,0.8,0.2,0.2c-0.4-0.5,0,0,0.1,0.1c0.4,0.7,0,0.2,0-0.2c0,0.1,0.1,0.4,0.2,0.5c0.3,0.9-0.1-1,0-0.1
|
||||
c0.1,2.3,2,4.6,4.5,4.5c2.3-0.1,4.6-2,4.5-4.5c-0.3-4.4-3-8.1-7.3-9.4c-2.2-0.7-5,0.8-5.5,3.1C376.1,72.2,377.4,74.5,379.8,75.3
|
||||
L379.8,75.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<ellipse transform="matrix(0.9999 -1.433736e-02 1.433736e-02 0.9999 -4.303 0.8051)" class="st2" cx="54" cy="300.5" rx="21" ry="15.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M52.2,297.5c1.1-0.3,1.4-0.4,2.5,0c0.8,0.3,1.3,0.7,2,1.7c1.5,1.9,4.8,1.6,6.4,0c1.9-1.9,1.5-4.4,0-6.4
|
||||
c-3.1-3.9-8.6-5.4-13.3-4C44.3,290.5,46.7,299.2,52.2,297.5L52.2,297.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M149.3,108.8c4.9-10.8-1.3-24.2-12.9-26.9c-1.9-0.4-2.7,2.4-0.8,2.9c9.6,2.3,15.3,13.5,11.2,22.5
|
||||
C145.9,109,148.5,110.5,149.3,108.8L149.3,108.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M141.2,112.3c2.4-9.4-5.4-19.3-15.2-19c-1.9,0.1-1.9,3.1,0,3c7.8-0.2,14.2,7.6,12.3,15.2
|
||||
C137.8,113.4,140.7,114.2,141.2,112.3L141.2,112.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st2" d="M132.6,118c-1.1-8.3-10.9-13.4-18.2-9.1c-1.7,1-0.2,3.6,1.5,2.6c5.2-3,12.9,0.4,13.7,6.5
|
||||
C129.8,119.9,132.8,119.9,132.6,118L132.6,118z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st5" d="M215.5,166.5l34-73c0,0,35,0,46,21c7.5,14.3,8,39,8,39L215.5,166.5z"/>
|
||||
<path class="st5" d="M208.2,170.5l-79.5-12.7c0,0-19.6,29-8.4,49.9c7.6,14.2,27.8,28.5,27.8,28.5L208.2,170.5z"/>
|
||||
<path class="st2" d="M210.5,164.5l33-74c0,0-2.5-5.5-8-7s-12,0-12,0L210.5,164.5z"/>
|
||||
<path class="st2" d="M207.4,165.3l-73.1-35c0,0-5.6,2.4-7.2,7.8c-1.6,5.5-0.3,12-0.3,12L207.4,165.3z"/>
|
||||
<path d="M215.5,166.5L234,127c0,0,17-6,25.5,7.5c8.6,13.6-3.5,25.5-3.5,25.5L215.5,166.5z"/>
|
||||
<path d="M206.7,170.9l-29.6,32c0,0-18,0.5-22-14.9c-4-15.6,11.1-23.2,11.1-23.2L206.7,170.9z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M243.4,139.1c-0.6,0.2-0.7,0.3-0.4,0.2c0.3-0.1,0.2-0.1-0.5,0.1c0.7,0-0.3,0-0.4-0.1c0.1,0,0.3,0.1,0.4,0.1
|
||||
c0.3,0.1,0.2,0-0.4-0.2c0,0,0.6,0.3,0.6,0.3c0.5,0.2-0.9-0.6-0.1-0.1c0.6,0.4-0.3-0.5-0.1-0.1c0.3,0.5-0.3-1-0.1-0.2
|
||||
c0.2,0.8,0-1,0-0.1c0,2.4,2.1,4.6,4.5,4.5c2.5-0.1,4.5-2,4.5-4.5c0-3-1.6-5.7-4.1-7.3c-2.6-1.7-5.6-1.6-8.4-0.4
|
||||
c-2.2,0.9-2.8,4.3-1.6,6.2C238.7,139.7,241,140.1,243.4,139.1L243.4,139.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M173.5,176.4c-0.5-0.3-0.1,0,0.2,0.1c-0.7-0.6,0.3,0.5,0.1,0c-0.3-0.5,0.4,0.8,0.1,0.2
|
||||
c-0.4-0.8,0.2,0.2,0,0.1c0,0,0-0.6,0-0.6c-0.1,0.1-0.1,1,0,0.3c-0.1,0.2-0.1,0.3-0.2,0.5c0.2-0.3,0.2-0.4,0-0.1
|
||||
c-0.2,0.2-0.2,0.3-0.1,0.1c0.2-0.2,0.1-0.2-0.3,0.2c1.9-1.4,3-4,1.6-6.2c-1.2-1.9-4.1-3.1-6.2-1.6c-2.4,1.7-4,4.3-3.9,7.4
|
||||
c0.1,3,1.6,5.7,4.1,7.3c2,1.2,5,0.5,6.2-1.6C176.3,180.4,175.7,177.7,173.5,176.4L173.5,176.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<ellipse transform="matrix(0.862 -0.5069 0.5069 0.862 -88.3186 186.5516)" class="st6" cx="298.5" cy="255.5" rx="79.5" ry="68.5"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M173.6,109.8c-2.1,2-3.9,4.6-3.6,7.6c0.3,3.5,2.8,6.6,6.6,6.7c6,0.2,11.5-7.7,8.2-13c-1-1.7-3.1-3.1-5.2-3
|
||||
c-1.7,0.1-3.1,0.8-4.4,1.9c-2,1.8-2.8,5.2-1.9,7.7c2.4,6.6,11.8,5.9,13.8-0.7c0.7-2.5-0.9-5.6-3.5-6.2c-2.7-0.6-5.4,0.8-6.2,3.5
|
||||
c0.6-2.1,3.1-2.6,4.6-1c0.8,0.9,1,1.8,0.8,2.8c0.2-0.5,0.1-0.4-0.1,0.3c-0.4,0.7-1,1.2-1.8,1.4c-0.9,0-1.8,0-2.7,0
|
||||
c-1.8-0.6-2.5-1.6-2.3-3.1c-0.1-0.4-0.1-0.7,0.1-1c0.2-0.3,0.1-0.3-0.1,0.1c0.1-0.1,0.2-0.2,0.3-0.4c-0.2,0.3-0.5,0.5-0.7,0.8
|
||||
c-0.1,0.1-0.2,0.2-0.3,0.3c-0.3,0.2-0.2,0.2,0.1-0.1c1.3,0.2,2.6,0.4,3.9,0.6c0.2,0.4,0.5,0.9,0.7,1.3c0.2,0.6-0.2,0.9-0.2,1.4
|
||||
c0,0.4,0.4-0.5-0.1,0.1c0.3-0.4,0.6-0.7,1-1c1.9-1.8,2-5.3,0-7.1C178.7,107.9,175.6,107.8,173.6,109.8L173.6,109.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M151.2,248.6c-5.7,7,1.7,16.9,10,13.3c3.4-1.5,6.3-5,6.3-8.9c0-4.2-2.7-7.6-7-7.8c-3.1-0.1-5.8,3.3-4.8,6.3
|
||||
c1.2,3.4,3.7,6.1,7.3,7c2.6,0.6,5.4-0.8,6.2-3.5c0.7-2.5-0.9-5.5-3.5-6.2c-1.7-0.4,0,0.1-0.2,0.1c-0.4,0-0.4-0.8-0.1-0.1
|
||||
c-1.6,2.1-3.2,4.2-4.8,6.3c-2.4-0.1-2.8-1.1-3-2.6c0.1,0.7-0.1,0.2,0.1-0.1c0.7-0.9-0.5,0.5,0,0c-0.5,0.5-0.3,0.1-0.2,0.2
|
||||
c0.1,0,0.6,0,0.7,0c0.4,0.1,0.5,0.4,0.8,0.6c0.2,0.3,0.2,0.2-0.1-0.2c0.1,0.1,0.1,0.3,0.2,0.4c0,1,0.1,1.1-0.7,2.1
|
||||
c1.7-2.1,2-5,0-7.1C156.5,246.8,152.9,246.5,151.2,248.6L151.2,248.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M204.1,205.7c0.8,4.8,5.3,8.6,10.1,8.6c5.1,0,9.5-3.9,10.3-8.9c0.7-4.4-0.2-12.1-5.3-13.6
|
||||
c-2.7-0.8-5.2,0.5-7,2.4c-1.1,1.2-1.5,1.7-3.1,1.2c0.7,2.8,1.5,5.6,2.2,8.4c0.2-0.2-0.5,0.2-0.5,0.2c6.3,1.4,8.9-8.2,2.7-9.6
|
||||
c-3.5-0.8-6.6,0-9.3,2.4c-3,2.6-1.1,7.2,2.2,8.4c2.6,0.9,5.5,0.8,8-0.2c1.3-0.5,2.4-1.2,3.4-2.1c0.4-0.3,0.7-0.6,1-1
|
||||
c0.2-0.3,0.4-0.5,0.6-0.7c0.4-0.4,0.3-0.4-0.5,0.3c-0.9,0-1.8,0-2.7,0c0.2,0.1,0.3,0.1,0.5,0.2c-0.7-0.4-1.5-0.9-2.2-1.3
|
||||
c0.1,0.2,0.3,0.3,0.4,0.5c-0.4-0.7-0.9-1.5-1.3-2.2c0.4,1.2,0.8,2.5,1,3.7c0,0.4,0,0.8,0,1.2c0,0.5-0.5,0.9,0,0.4
|
||||
c-0.8,0.6-0.9,0.2-1.1-0.9c-0.4-2.7-3.8-4.1-6.2-3.5C204.7,200.3,203.7,203,204.1,205.7L204.1,205.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M265.9,179.6c0.2,0.4,0.5,0.9,0.7,1.3c0.6,1.1,1.8,2,3,2.3c1.2,0.3,2.8,0.2,3.9-0.5c1.1-0.7,2-1.7,2.3-3
|
||||
c0.3-1.4,0.1-2.6-0.5-3.9c-0.2-0.4-0.5-0.9-0.7-1.3c-0.6-1.1-1.8-2-3-2.3c-1.2-0.3-2.8-0.2-3.9,0.5c-1.1,0.7-2,1.7-2.3,3
|
||||
C265.1,177.1,265.3,178.3,265.9,179.6L265.9,179.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M200.4,295.8c-6.1,1.6-8.1,8.6-5,13.7c2.8,4.7,9.1,7.2,14.3,5.4c4.9-1.7,7.8-7.1,6.3-12.2
|
||||
c-0.8-2.7-2.7-4.8-5.3-5.8c-1.4-0.5-2.8-0.7-4.2-0.8c-0.1,0-0.9-0.1-0.9-0.1c0.2-0.4,1.2,2.5,0.9,0.7c0,0.9,0,1.8,0,2.7
|
||||
c-0.1,0.1-0.1,0.1-0.2,0.2c3.1-5.6-5.5-10.7-8.6-5c-1.7,3-1.1,6.6,1.4,9c1.3,1.2,2.8,2,4.5,2.3c0.8,0.1,1.6,0.2,2.4,0.3
|
||||
c0.4,0,0.7,0,1.1,0.1c0.2,0.1,0.1,0.1-0.2-0.1c0,0.1-0.6-0.5-0.6-0.5c-0.1-0.1-0.1-0.2,0-0.3c0.1-0.3,0.1-0.1-0.1,0.5
|
||||
c-0.3-0.1,0.7-0.2-0.3-0.3c-0.9-0.1-1.1-0.6-1.8-0.9c0,0-0.2-0.3-0.3-0.3c0.3,0-0.8,1.2-0.8,1.2
|
||||
C209.3,303.8,206.6,294.2,200.4,295.8L200.4,295.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M244.8,355.3c-4-6.2-11.2-2.3-12,3.9c-0.8,5.9,1.8,12,6.5,15.6c4.5,3.5,11.5,4.9,16.7,2.1
|
||||
c6.4-3.3,5.4-9.8,4.9-15.9c-0.5-6.3-1.9-12-9.5-12.1c-5.1-0.1-13.1,0.2-14.5,6.4c-1.2,5.4,2.5,12.8,8.2,13.8
|
||||
c6.2,1.1,11.2-5.5,7.8-11c-2.2-3.5-8.1-3.1-9.1,1.2c-1.1,4.4,0.5,8,4.1,10.6c5.2,3.8,10.2-4.8,5-8.6c0.2,0.2,0.4,0.5,0.5,0.7
|
||||
c-3,0.4-6.1,0.8-9.1,1.2c-0.4-0.7,3.4-3.1,2.9-4.8c-0.8-2.6-1.7,1.4-1.9,1.1c0,0.1,5.2-0.1,5.6-0.4c0.7,0.1,0.8-0.1,0.2-0.6
|
||||
c-0.4-0.7-0.5-0.8-0.4-0.3c-0.2,0.3,0.2,1.9,0.2,2.3c0.2,2,0.3,4,0.5,5.9c0.1,1.6,0.4,1.7-1.1,2c-1.3,0.2-2.9-0.3-4-0.9
|
||||
c-1.4-0.8-2.5-2-3.1-3.5c-0.3-0.7-0.4-1.3-0.5-2c0-0.3-0.1-0.7,0-1c0.2-1.9-1.1-1.5-3.8,1.2c-1-0.8-2-1.5-3-2.3
|
||||
c0.1,0.2,0.2,0.4,0.4,0.6C239.6,365.7,248.3,360.7,244.8,355.3L244.8,355.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st7" d="M336.5,337.4c-2.4-1.5-5.1-2.5-7.9-1.8c-2.7,0.7-4.9,3.2-5.3,6c-0.9,6.4,6.3,8.3,11.2,8.4
|
||||
c4.8,0.1,10.6-2.4,10.9-7.9c0.2-5.6-5.5-9.6-10.6-6.9c-5.7,3-0.7,11.6,5,8.6c-0.1,0.1-0.2,0.1-0.3,0.2c-0.9,0-1.8,0-2.7,0
|
||||
c-2.1-0.4-1.4-4.8-0.3-4.3c0,0-1.3,0.3-1.3,0.3c-0.6,0-1.2,0-1.8-0.1c-0.5-0.1-1-0.2-1.5-0.4c-1.2-0.5-1-0.2,0.6,0.7
|
||||
c0.2,0.8,0.5,1.7,0.7,2.5c-3.4,1.1-4.4,1.9-2.8,2.7c0.4,0.2,0.7,0.4,1.1,0.7C336.9,349.6,341.9,340.9,336.5,337.4L336.5,337.4z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st3" d="M224.3,256.5L252,273v-40l32,20v-38l28,17l4-28l23,12l-3-24c0,0-14-8-35.5-6.4c-11.6,0.9-24.3,6.8-33.5,11.4
|
||||
c-14,7-23.7,18.9-31.2,29.1C227,238,224.3,256.5,224.3,256.5z"/>
|
||||
<path class="st3" d="M372.9,248.9l-28.8-14.5l2.9,39.9l-33.3-17.7l2.7,37.9l-29.1-15l-2,28.2l-23.8-10.3l4.7,23.7
|
||||
c0,0,14.5,7,35.9,3.8c11.5-1.7,23.7-8.5,32.6-13.8c13.5-8,22.3-20.5,29-31.2C371.5,267.5,372.9,248.9,372.9,248.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M235.2,121.6c8.5-3.1,23.2-0.1,27.8,8.4c2.3,4.4,4.5,9.9,4.5,14.9c0.1,5.5-2.7,10.5-5.3,15.3
|
||||
c-1.5,2.8,2.8,5.4,4.3,2.5c3.1-5.8,6.3-11.9,6-18.7c-0.3-6-2.8-12.8-5.9-17.9c-6-9.5-22.6-13.1-32.7-9.4
|
||||
C230.9,117.8,232.2,122.7,235.2,121.6L235.2,121.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M241.1,110.5c11.6-2.3,25.6,2.3,32.2,12.4c6.6,10.2,6.1,22.8,3.1,34.2c-1.3,5,6.4,7.1,7.7,2.1
|
||||
c3.8-14.3,3.8-30.3-5.5-42.6c-8.9-11.7-25.5-16.6-39.6-13.8C233.9,103.8,236.1,111.5,241.1,110.5L241.1,110.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M245.4,97.5c7.8-1.8,15.5,0,22.9,2.8c7.2,2.7,15,6.1,20.3,11.8c10.7,11.7,9.5,29.3,8.7,44
|
||||
c-0.3,6.4,9.7,6.4,10,0c1-17.9,1.2-38.5-12.7-52.1c-6.4-6.3-15.3-10.2-23.6-13.3c-9.1-3.4-18.6-4.9-28.2-2.8
|
||||
C236.5,89.2,239.1,98.9,245.4,97.5L245.4,97.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M155.8,158.5c-13.1,4.8-14.2,21.6-10.1,33.1c4.3,12,15.2,20.6,28.2,20.5c3.2,0,3.2-5,0-5
|
||||
c-9.9,0.1-18.6-5.9-22.6-14.9c-3.9-8.6-5.2-24.8,5.8-28.9C160.2,162.3,158.9,157.4,155.8,158.5L155.8,158.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M164.1,216.5c-11.4-2.2-18.8-11.4-22.7-21.9c-3.6-9.6-7.7-25.3,1.2-33.1c3.9-3.4-1.8-9-5.7-5.7
|
||||
c-11.3,9.9-7.9,28.5-3.3,40.9c4.8,13,14.1,24.7,28.3,27.5C167,225.2,169.1,217.5,164.1,216.5L164.1,216.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st8" d="M152,231.7c-27.3-13.3-38.1-46.5-23.3-73.2c3.1-5.6-5.5-10.7-8.6-5c-17.3,31.2-5.3,71.1,26.9,86.9
|
||||
C152.7,243.1,157.8,234.5,152,231.7L152,231.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -1,15 +1,19 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Trans } from '@lingui/macro';
|
||||
import {
|
||||
Banner,
|
||||
Card,
|
||||
PageSection,
|
||||
Tabs,
|
||||
Tab,
|
||||
TabTitleText,
|
||||
} from '@patternfly/react-core';
|
||||
import { InfoCircleIcon } from '@patternfly/react-icons';
|
||||
|
||||
import { useConfig } from 'contexts/Config';
|
||||
import useBrandName from 'hooks/useBrandName';
|
||||
import useRequest from 'hooks/useRequest';
|
||||
import { DashboardAPI } from 'api';
|
||||
import ScreenHeader from 'components/ScreenHeader';
|
||||
@@ -40,6 +44,8 @@ const MainPageSection = styled(PageSection)`
|
||||
`;
|
||||
|
||||
function Dashboard() {
|
||||
const config = useConfig();
|
||||
const brandName = useBrandName();
|
||||
const [activeTabId, setActiveTabId] = useState(0);
|
||||
|
||||
const {
|
||||
@@ -69,6 +75,16 @@ function Dashboard() {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{config?.ui_next && (
|
||||
<Banner variant="info">
|
||||
<Trans>
|
||||
<p>
|
||||
<InfoCircleIcon /> A tech preview of the new {brandName} user
|
||||
interface can be found <a href="/ui_next/dashboard">here</a>.
|
||||
</p>
|
||||
</Trans>
|
||||
</Banner>
|
||||
)}
|
||||
<ScreenHeader
|
||||
streamType="all"
|
||||
breadcrumbConfig={{ '/home': t`Dashboard` }}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import { DashboardAPI } from 'api';
|
||||
import { DashboardAPI, RootAPI } from 'api';
|
||||
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||
|
||||
import Dashboard from './Dashboard';
|
||||
|
||||
jest.mock('../../api');
|
||||
@@ -15,6 +13,11 @@ describe('<Dashboard />', () => {
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
DashboardAPI.read.mockResolvedValue({});
|
||||
RootAPI.readAssetVariables.mockResolvedValue({
|
||||
data: {
|
||||
BRAND_NAME: 'AWX',
|
||||
},
|
||||
});
|
||||
graphRequest = DashboardAPI.readJobGraph;
|
||||
graphRequest.mockResolvedValue({});
|
||||
pageWrapper = mountWithContexts(<Dashboard />);
|
||||
|
||||
@@ -40,6 +40,7 @@ describe('<MiscAuthenticationDetail />', () => {
|
||||
SOCIAL_AUTH_ORGANIZATION_MAP: {},
|
||||
SOCIAL_AUTH_TEAM_MAP: {},
|
||||
SOCIAL_AUTH_USER_FIELDS: [],
|
||||
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL: false,
|
||||
},
|
||||
});
|
||||
await act(async () => {
|
||||
@@ -79,6 +80,7 @@ describe('<MiscAuthenticationDetail />', () => {
|
||||
assertVariableDetail(wrapper, 'Social Auth Organization Map', '{}');
|
||||
assertVariableDetail(wrapper, 'Social Auth Team Map', '{}');
|
||||
assertVariableDetail(wrapper, 'Social Auth User Fields', '[]');
|
||||
assertDetail(wrapper, 'Use Email address for usernames', 'Off');
|
||||
assertDetail(
|
||||
wrapper,
|
||||
'Allow External Users to Create OAuth2 Tokens',
|
||||
|
||||
@@ -53,7 +53,8 @@ function MiscAuthenticationEdit() {
|
||||
'SESSION_COOKIE_AGE',
|
||||
'SOCIAL_AUTH_ORGANIZATION_MAP',
|
||||
'SOCIAL_AUTH_TEAM_MAP',
|
||||
'SOCIAL_AUTH_USER_FIELDS'
|
||||
'SOCIAL_AUTH_USER_FIELDS',
|
||||
'SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL'
|
||||
);
|
||||
|
||||
const authenticationData = {
|
||||
@@ -242,6 +243,10 @@ function MiscAuthenticationEdit() {
|
||||
name="SOCIAL_AUTH_USER_FIELDS"
|
||||
config={authentication.SOCIAL_AUTH_USER_FIELDS}
|
||||
/>
|
||||
<BooleanField
|
||||
name="SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL"
|
||||
config={authentication.SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL}
|
||||
/>
|
||||
{submitError && <FormSubmitError error={submitError} />}
|
||||
{revertError && <FormSubmitError error={revertError} />}
|
||||
</FormColumnLayout>
|
||||
|
||||
@@ -32,6 +32,7 @@ const authenticationData = {
|
||||
SOCIAL_AUTH_ORGANIZATION_MAP: null,
|
||||
SOCIAL_AUTH_TEAM_MAP: null,
|
||||
SOCIAL_AUTH_USER_FIELDS: null,
|
||||
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL: false,
|
||||
};
|
||||
|
||||
describe('<MiscAuthenticationEdit />', () => {
|
||||
|
||||
@@ -60,7 +60,8 @@ function MiscSystemDetail() {
|
||||
'DEFAULT_EXECUTION_ENVIRONMENT',
|
||||
'PROXY_IP_ALLOWED_LIST',
|
||||
'AUTOMATION_ANALYTICS_LAST_GATHER',
|
||||
'AUTOMATION_ANALYTICS_LAST_ENTRIES'
|
||||
'AUTOMATION_ANALYTICS_LAST_ENTRIES',
|
||||
'UI_NEXT'
|
||||
);
|
||||
|
||||
const mergedData = {};
|
||||
|
||||
@@ -43,6 +43,7 @@ describe('<MiscSystemDetail />', () => {
|
||||
AUTOMATION_ANALYTICS_LAST_ENTRIES:
|
||||
'{"foo": "2021-11-24R06:35:15.179Z"}',
|
||||
AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
|
||||
UI_NEXT: true,
|
||||
},
|
||||
});
|
||||
ExecutionEnvironmentsAPI.readDetail = jest.fn();
|
||||
@@ -113,6 +114,7 @@ describe('<MiscSystemDetail />', () => {
|
||||
assertVariableDetail(wrapper, 'Remote Host Headers', '[]');
|
||||
assertVariableDetail(wrapper, 'Proxy IP Allowed List', '[]');
|
||||
assertDetail(wrapper, 'Global default execution environment', 'Foo');
|
||||
assertDetail(wrapper, 'Enable Preview of New User Interface', 'On');
|
||||
});
|
||||
|
||||
test('should render execution environment as not configured', async () => {
|
||||
|
||||
@@ -52,7 +52,8 @@ function MiscSystemEdit() {
|
||||
'REMOTE_HOST_HEADERS',
|
||||
'TOWER_URL_BASE',
|
||||
'DEFAULT_EXECUTION_ENVIRONMENT',
|
||||
'PROXY_IP_ALLOWED_LIST'
|
||||
'PROXY_IP_ALLOWED_LIST',
|
||||
'UI_NEXT'
|
||||
);
|
||||
|
||||
const mergedData = {};
|
||||
@@ -222,6 +223,7 @@ function MiscSystemEdit() {
|
||||
type="number"
|
||||
isRequired
|
||||
/>
|
||||
<BooleanField name="UI_NEXT" config={system.UI_NEXT} />
|
||||
<ObjectField
|
||||
name="AUTOMATION_ANALYTICS_LAST_ENTRIES"
|
||||
config={system.AUTOMATION_ANALYTICS_LAST_ENTRIES}
|
||||
|
||||
@@ -39,6 +39,7 @@ const systemData = {
|
||||
REMOTE_HOST_HEADERS: ['REMOTE_ADDR', 'REMOTE_HOST'],
|
||||
TOWER_URL_BASE: 'https://localhost:3000',
|
||||
PROXY_IP_ALLOWED_LIST: [],
|
||||
UI_NEXT: false,
|
||||
};
|
||||
|
||||
describe('<MiscSystemEdit />', () => {
|
||||
|
||||
@@ -41,7 +41,7 @@ function AnalyticsStep() {
|
||||
component="a"
|
||||
href={`${getDocsBaseUrl(
|
||||
config
|
||||
)}/html/installandreference/user-data.html#index-0`}
|
||||
)}/html/administration/usability_data_collection.html#automation-analytics`}
|
||||
variant="link"
|
||||
isInline
|
||||
ouiaId="tower-documentation-link"
|
||||
|
||||
@@ -639,6 +639,15 @@
|
||||
"unit": "seconds",
|
||||
"default": 14400
|
||||
},
|
||||
"UI_NEXT": {
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"label": "Enable Preview of New User Interface",
|
||||
"help_text": "'Enable preview of new user interface.",
|
||||
"category": "System",
|
||||
"category_slug": "system",
|
||||
"default": true
|
||||
},
|
||||
"SESSION_COOKIE_AGE": {
|
||||
"type": "integer",
|
||||
"required": true,
|
||||
@@ -850,6 +859,15 @@
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL": {
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"label": "Use Email address for usernames",
|
||||
"help_text": "Enabling this setting will tell social auth to use the full Email as username instead of the full name",
|
||||
"category": "Authentication",
|
||||
"category_slug": "authentication",
|
||||
"default": false
|
||||
},
|
||||
"SOCIAL_AUTH_OIDC_KEY": {
|
||||
"type": "string",
|
||||
"label": "OIDC Key",
|
||||
@@ -4372,6 +4390,14 @@
|
||||
"defined_in_file": false,
|
||||
"unit": "seconds"
|
||||
},
|
||||
"UI_NEXT": {
|
||||
"type": "boolean",
|
||||
"label": "Enable Preview of New User Interface",
|
||||
"help_text": "Enable preview of new user interface.",
|
||||
"category": "System",
|
||||
"category_slug": "system",
|
||||
"defined_in_file": false
|
||||
},
|
||||
"SESSION_COOKIE_AGE": {
|
||||
"type": "integer",
|
||||
"label": "Idle Time Force Log Out",
|
||||
@@ -4537,6 +4563,14 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL": {
|
||||
"type": "boolean",
|
||||
"label": "Use Email address for usernames",
|
||||
"help_text": "Enabling this setting will tell social auth to use the full Email as username instead of the full name",
|
||||
"category": "Authentication",
|
||||
"category_slug": "authentication",
|
||||
"default": false
|
||||
},
|
||||
"SOCIAL_AUTH_OIDC_KEY": {
|
||||
"type": "string",
|
||||
"label": "OIDC Key",
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
"SOCIAL_AUTH_ORGANIZATION_MAP":null,
|
||||
"SOCIAL_AUTH_TEAM_MAP":null,
|
||||
"SOCIAL_AUTH_USER_FIELDS":null,
|
||||
"SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL":false,
|
||||
"AUTH_LDAP_SERVER_URI":"ldap://ldap.example.com",
|
||||
"AUTH_LDAP_BIND_DN":"cn=eng_user1",
|
||||
"AUTH_LDAP_BIND_PASSWORD":"$encrypted$",
|
||||
@@ -307,5 +308,6 @@
|
||||
"instances":{"fields":["hostname"],"adj_list":[]}
|
||||
},
|
||||
"DEFAULT_EXECUTION_ENVIRONMENT": 1,
|
||||
"AWX_MOUNT_ISOLATED_PATHS_ON_K8S": false
|
||||
"AWX_MOUNT_ISOLATED_PATHS_ON_K8S": false,
|
||||
"UI_NEXT": false
|
||||
}
|
||||
|
||||
@@ -66,7 +66,13 @@ const getNodeToEditDefaultValues = (
|
||||
// There is a case where the nodeToEdit convergence value will not align with the
|
||||
// original node object value. This allows the nodeToEdit value to take precedence over the
|
||||
// original node object.
|
||||
if (nodeToEdit) {
|
||||
if (
|
||||
nodeToEdit &&
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
nodeToEdit,
|
||||
'all_parents_must_converge'
|
||||
)
|
||||
) {
|
||||
return nodeToEdit.all_parents_must_converge ? 'all' : 'any';
|
||||
}
|
||||
return nodeToEdit?.originalNodeObject?.all_parents_must_converge
|
||||
|
||||
112
awx/ui_next/Makefile
Normal file
@@ -0,0 +1,112 @@
|
||||
## UI_NEXT_DIR: Relative path to the directory containing this Makefile
|
||||
UI_NEXT_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
## Path to your local clone of the UI_NEXT repo
|
||||
# NOTE: you will not be able to build within the docker-compose development environment if you use this option
|
||||
UI_NEXT_LOCAL ?=
|
||||
|
||||
# Git repo and branch to the UI_NEXT repo
|
||||
UI_NEXT_GIT_REPO ?= https://github.com/ansible/ansible-ui.git
|
||||
UI_NEXT_GIT_BRANCH ?= main
|
||||
|
||||
.PHONY: ui-next
|
||||
## Default build target of ui-next Makefile, builds ui-next/build
|
||||
ui-next: ui-next/build
|
||||
|
||||
.PHONY: ui-next/build
|
||||
## Build ui-next/build
|
||||
ui-next/build: $(UI_NEXT_DIR)/build
|
||||
|
||||
## True build target for ui-next.
|
||||
$(UI_NEXT_DIR)/build:
|
||||
@$(MAKE) $(UI_NEXT_DIR)/src/build/awx
|
||||
@echo "=== Copying $(UI_NEXT_DIR)/src/build to $(UI_NEXT_DIR)/build ==="
|
||||
@rm -rf $(UI_NEXT_DIR)/build
|
||||
@cp -r $(UI_NEXT_DIR)/src/build $(UI_NEXT_DIR)
|
||||
@echo "=== Done building $(UI_NEXT_DIR)/build ==="
|
||||
|
||||
.PHONY: ui-next/src/build
|
||||
## Build ui-next/src/build
|
||||
ui-next/src/build: $(UI_NEXT_DIR)/src/build/awx
|
||||
|
||||
## True target for ui-next/src/build. Build ui_next from source.
|
||||
$(UI_NEXT_DIR)/src/build/awx: $(UI_NEXT_DIR)/src $(UI_NEXT_DIR)/src/node_modules/webpack
|
||||
@echo "=== Building ui_next ==="
|
||||
@cd $(UI_NEXT_DIR)/src && npm run build:awx
|
||||
|
||||
.PHONY: ui-next/src
|
||||
## Clone or link src of UI_NEXT to ui-next/src, will re-clone/link/update if necessary.
|
||||
ui-next/src: $(UI_NEXT_DIR)/src
|
||||
|
||||
# TODO: Rewrite this big bash script in a more readable way.
|
||||
## True target for ui-next/src.
|
||||
$(UI_NEXT_DIR)/src:
|
||||
@echo "=== Setting up $(UI_NEXT_DIR)/src ==="
|
||||
@if [ ! -z "$(UI_NEXT_LOCAL)" ]; then \
|
||||
if [ -d $(UI_NEXT_DIR)/src ]; then \
|
||||
if [ "$$(readlink $(UI_NEXT_DIR)/src)" = "$(UI_NEXT_LOCAL)" ]; then \
|
||||
echo "SKIP: ui-next/src. $(UI_NEXT_DIR)/src already linked to $(UI_NEXT_LOCAL)."; \
|
||||
else \
|
||||
echo "=== Linking $(UI_NEXT_DIR)/src to $(UI_NEXT_LOCAL) ==="; \
|
||||
rm -rf $(UI_NEXT_DIR)/src; \
|
||||
ln -s $(UI_NEXT_LOCAL) $(UI_NEXT_DIR)/src; \
|
||||
fi; \
|
||||
else \
|
||||
echo "=== Linking $(UI_NEXT_DIR)/src to $(UI_NEXT_LOCAL) ==="; \
|
||||
ln -s $(UI_NEXT_LOCAL) $(UI_NEXT_DIR)/src; \
|
||||
fi; \
|
||||
elif [ ! -z "$(UI_NEXT_GIT_REPO)" ]; then \
|
||||
if [ -d $(UI_NEXT_DIR)/src ]; then \
|
||||
GIT_REMOTE_ORIGIN=$$(cd $(UI_NEXT_DIR)/src && git remote get-url origin); \
|
||||
GIT_REMOTE_BRANCH=$$(cd $(UI_NEXT_DIR)/src && git rev-parse --abbrev-ref HEAD); \
|
||||
if [ "$$GIT_REMOTE_ORIGIN" = "$(UI_NEXT_GIT_REPO)" ] && [ "$$GIT_REMOTE_BRANCH" = "$(UI_NEXT_GIT_BRANCH)" ]; then \
|
||||
echo "=== Updating $(UI_NEXT_DIR)/src from $(UI_NEXT_GIT_BRANCH) of $(UI_NEXT_GIT_REPO) ==="; \
|
||||
git fetch && git pull; \
|
||||
else \
|
||||
echo "=== Cloning $(UI_NEXT_DIR)/src from $(UI_NEXT_GIT_BRANCH) of $(UI_NEXT_GIT_REPO) ==="; \
|
||||
rm -rf $(UI_NEXT_DIR)/src; \
|
||||
git clone --depth 1 --branch $(UI_NEXT_GIT_BRANCH) $(UI_NEXT_GIT_REPO) $(UI_NEXT_DIR)/src || true; \
|
||||
fi; \
|
||||
else \
|
||||
echo "=== Cloning $(UI_NEXT_DIR)/src from $(UI_NEXT_GIT_BRANCH) of $(UI_NEXT_GIT_REPO) ==="; \
|
||||
git clone --depth 1 --branch $(UI_NEXT_GIT_BRANCH) $(UI_NEXT_GIT_REPO) $(UI_NEXT_DIR)/src || true; \
|
||||
fi; \
|
||||
else \
|
||||
echo "FAILED: ui-next/src. UI_NEXT_LOCAL and UI_NEXT_GIT_REPO are not set."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: ui-next/src/webpack
|
||||
## Install webpack.
|
||||
ui-next/src/webpack: $(UI_NEXT_DIR)/src/node_modules/webpack
|
||||
|
||||
## True target for ui-next/src/webpack.
|
||||
$(UI_NEXT_DIR)/src/node_modules/webpack:
|
||||
@echo "=== Installing webpack ==="
|
||||
@cd $(UI_NEXT_DIR)/src && npm install webpack
|
||||
|
||||
.PHONY: clean/ui-next
|
||||
## Clean ui_next
|
||||
clean/ui-next: clean/ui-next/build clean/ui-next/src
|
||||
|
||||
.PHONY: clean/ui-next/src
|
||||
## Clean ui_next src
|
||||
clean/ui-next/src:
|
||||
rm -rf $(UI_NEXT_DIR)/src
|
||||
|
||||
.PHONY: clean/ui-next/build
|
||||
## Clean ui_next build
|
||||
clean/ui-next/build:
|
||||
rm -rf $(UI_NEXT_DIR)/build
|
||||
|
||||
.PHONY: $(UI_NEXT_DIR)/clean
|
||||
## Alias for clean/ui-next, so we can run `make clean` directly in ui_next
|
||||
$(UI_NEXT_DIR)/clean: clean/ui-next
|
||||
|
||||
.PHONY: $(UI_NEXT_DIR)/clean/src
|
||||
## Alias for clean/ui-next/src, so we can run `make clean/src` directly in ui_next
|
||||
$(UI_NEXT_DIR)/clean/src: clean/ui-next/src
|
||||
|
||||
.PHONY: $(UI_NEXT_DIR)/clean/build
|
||||
## Alias for clean/ui-next/build, so we can run `make clean/build` directly in ui_next
|
||||
$(UI_NEXT_DIR)/clean/build: clean/ui-next/build
|
||||
47
awx/ui_next/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Instruction to build ui_next directly from this directory
|
||||
|
||||
## Set src of the ui_next repo
|
||||
|
||||
### Via GIT
|
||||
|
||||
```bash
|
||||
export UI_NEXT_GIT_REPO=https://<git repo>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
export UI_NEXT_GIT_REPO=git@<git repo>
|
||||
```
|
||||
|
||||
optionally set branch (default is main)
|
||||
|
||||
```bash
|
||||
export UI_NEXT_GIT_BRANCH=main
|
||||
```
|
||||
|
||||
### Via symlink to existing clone
|
||||
|
||||
NOTE: UI_NEXT_LOCAL have higher precedence than UI_NEXT_GIT_REPO, if UI_NEXT_LOCAL is set, UI_NEXT_GIT_REPO will be ignored.
|
||||
|
||||
```bash
|
||||
export UI_NEXT_LOCAL = /path/to/your/ui_next
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
make ui-next
|
||||
```
|
||||
|
||||
## Rebuild
|
||||
|
||||
```bash
|
||||
make -B ui-next
|
||||
```
|
||||
|
||||
## Clean
|
||||
|
||||
```bash
|
||||
make clean/ui-next
|
||||
```
|
||||
8
awx/ui_next/placeholder_index_awx.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head><title>UI Next Missing</title></head>
|
||||
<body style="background-color: black; color: white;">
|
||||
<div style="display: flex; justify-content: center; align-items: center; text-align: center; min-height: 100vh;">
|
||||
<h1>Oops... Looks like the UI Next wasn't properly built</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
19
awx/ui_next/urls.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from django.urls import re_path
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
|
||||
class IndexView(TemplateView):
|
||||
template_name = 'index_awx.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if settings.UI_NEXT is False:
|
||||
raise Http404()
|
||||
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
app_name = 'ui_next'
|
||||
|
||||
urlpatterns = [re_path(r'^$', IndexView.as_view(), name='index')]
|
||||
@@ -9,6 +9,7 @@ from awx.main.views import handle_400, handle_403, handle_404, handle_500, handl
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'', include('awx.ui.urls', namespace='ui')),
|
||||
re_path(r'^ui_next/.*', include('awx.ui_next.urls', namespace='ui_next')),
|
||||
re_path(r'^api/', include('awx.api.urls', namespace='api')),
|
||||
re_path(r'^sso/', include('awx.sso.urls', namespace='sso')),
|
||||
re_path(r'^sso/', include('social_django.urls', namespace='social')),
|
||||
|
||||
@@ -284,13 +284,15 @@ def main():
|
||||
argument_spec=argument_spec,
|
||||
)
|
||||
|
||||
# Alias for manual projects
|
||||
if module.params.get('scm_type') == "manual":
|
||||
module.params['scm_type'] = ''
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
new_name = module.params.get("new_name")
|
||||
copy_from = module.params.get('copy_from')
|
||||
scm_type = module.params.get('scm_type')
|
||||
if scm_type == "manual":
|
||||
scm_type = ""
|
||||
local_path = module.params.get('local_path')
|
||||
credential = module.params.get('credential')
|
||||
scm_update_on_launch = module.params.get('scm_update_on_launch')
|
||||
@@ -387,7 +389,8 @@ def main():
|
||||
# this is resolved earlier, so save an API call and don't do it again in the loop above
|
||||
project_fields['organization'] = org_id
|
||||
|
||||
if scm_type == '' and local_path is not None:
|
||||
# Respect local_path if scm_type is manual type or not specified
|
||||
if scm_type in ('', None) and local_path is not None:
|
||||
project_fields['local_path'] = local_path
|
||||
|
||||
if scm_update_cache_timeout not in (0, None) and scm_update_on_launch is not True:
|
||||
|
||||
@@ -26,6 +26,24 @@ def test_create_project(run_module, admin_user, organization, silence_warning):
|
||||
assert result == {'name': 'foo', 'id': proj.id}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_manual_project(run_module, admin_user, organization, mocker):
|
||||
mocker.patch('awx.main.models.projects.Project.get_local_path_choices', return_value=['foo_folder/'])
|
||||
result = run_module(
|
||||
'project',
|
||||
dict(name='foo', organization=organization.name, scm_type='manual', local_path='foo_folder/', wait=False),
|
||||
admin_user,
|
||||
)
|
||||
assert result.pop('changed', None), result
|
||||
|
||||
proj = Project.objects.get(name='foo')
|
||||
assert proj.local_path == 'foo_folder/'
|
||||
assert proj.organization == organization
|
||||
|
||||
result.pop('invocation')
|
||||
assert result == {'name': 'foo', 'id': proj.id}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_project_copy_from(run_module, admin_user, organization, silence_warning):
|
||||
'''Test the copy_from functionality'''
|
||||
|
||||
@@ -146,7 +146,7 @@ There is an important side effect to this. Because the manager `schedule()` runs
|
||||
|
||||
### Node Affinity Decider
|
||||
|
||||
The Task Manager decides which exact node a job will run on. It does so by considering user-configured group execution policy and user-configured capacity. First, the set of groups on which a job _can_ run on is constructed (see the AWX document on [Clustering](https://github.com/ansible/awx/blob/devel/docs/clustering.md)). The groups are traversed until a node within that group is found. The node with the largest remaining capacity that is idle is chosen first. If there are no idle nodes, then the node with the largest remaining capacity greater than or equal to the job capacity requirements is chosen.
|
||||
The Task Manager decides which exact node a job will run on. It does so by considering user-configured group execution policy and user-configured capacity. First, the set of groups on which a job _can_ run on is constructed (see the AWX document on [Clustering](https://github.com/ansible/awx/blob/devel/docs/clustering.md)). The groups are traversed until a node within that group is found. The node with the largest remaining capacity (after accounting for the job's task impact) is chosen first. If there are no instances that can fit the job, then the largest *idle* node is chosen, regardless whether the job fits within its capacity limits. In this second case, it is possible for the instance to exceed its capacity in order to run the job.
|
||||
|
||||
|
||||
## Managers are short-lived
|
||||
|
||||
@@ -208,8 +208,8 @@ ADD tools/docker-compose/start_tests.sh /start_tests.sh
|
||||
ADD tools/docker-compose/bootstrap_development.sh /usr/bin/bootstrap_development.sh
|
||||
ADD tools/docker-compose/entrypoint.sh /entrypoint.sh
|
||||
ADD tools/scripts/config-watcher /usr/bin/config-watcher
|
||||
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
|
||||
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /var/lib/awx/.config/containers/containers.conf
|
||||
ADD tools/docker-compose/containers.conf /etc/containers/containers.conf
|
||||
ADD tools/docker-compose/podman-containers.conf /var/lib/awx/.config/containers/containers.conf
|
||||
{% else %}
|
||||
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
|
||||
|
||||
@@ -26,6 +26,12 @@ fi
|
||||
# Make sure that the UI static file directory exists, Django complains otherwise.
|
||||
mkdir -p /awx_devel/awx/ui/build/static
|
||||
|
||||
# Make sure that the UI_NEXT statifc file directory exists, if UI_NEXT is not built yet put a placeholder file in it.
|
||||
if [ ! -d "/awx_devel/awx/ui_next/build/awx" ]; then
|
||||
mkdir -p /awx_devel/awx/ui_next/build/awx
|
||||
cp /awx_devel/awx/ui_next/placeholder_index_awx.html /awx_devel/awx/ui_next/build/awx/index_awx.html
|
||||
fi
|
||||
|
||||
if output=$(awx-manage createsuperuser --noinput --username=admin --email=admin@localhost 2> /dev/null); then
|
||||
echo $output
|
||||
fi
|
||||
|
||||
12
tools/docker-compose/containers.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
[containers]
|
||||
netns="host"
|
||||
userns="host"
|
||||
ipcns="host"
|
||||
utsns="host"
|
||||
cgroupns="host"
|
||||
cgroups="disabled"
|
||||
log_driver = "k8s-file"
|
||||
[engine]
|
||||
cgroup_manager = "cgroupfs"
|
||||
events_logger="file"
|
||||
runtime="crun"
|
||||
5
tools/docker-compose/podman-containers.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
[containers]
|
||||
volumes = [
|
||||
"/proc:/proc",
|
||||
]
|
||||
default_sysctls = []
|
||||