Skip to content

Commit

Permalink
Merge branch 'devel' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-m-sullivan authored Jan 8, 2025
2 parents 20c0867 + 5607961 commit e0fc085
Show file tree
Hide file tree
Showing 74 changed files with 1,184 additions and 1,177 deletions.
4 changes: 3 additions & 1 deletion .github/actions/run_awx_devel/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ runs:
run: |
DEV_DOCKER_OWNER=${{ github.repository_owner }} \
COMPOSE_TAG=${{ github.base_ref || github.ref_name }} \
COMPOSE_UP_OPTS="-d" \
DJANGO_COLORS=nocolor \
SUPERVISOR_ARGS="-n -t" \
COMPOSE_UP_OPTS="-d --no-color" \
make docker-compose
- name: Update default AWX password
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ jobs:
- name: Run live dev env tests
run: docker exec tools_awx_1 /bin/bash -c "make live_test"

- uses: ./.github/actions/upload_awx_devel_logs
if: always()
with:
log-filename: live-tests.log

awx-operator:
runs-on: ubuntu-latest
timeout-minutes: 60
Expand Down
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,6 @@ migrate:
dbchange:
$(MANAGEMENT_COMMAND) makemigrations

supervisor:
@if [ "$(VENV_BASE)" ]; then \
. $(VENV_BASE)/awx/bin/activate; \
fi; \
supervisord --pidfile=/tmp/supervisor_pid -n

collectstatic:
@if [ "$(VENV_BASE)" ]; then \
. $(VENV_BASE)/awx/bin/activate; \
Expand Down
4 changes: 2 additions & 2 deletions awx/api/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ def get_view_description(view, html=False):

def get_default_schema():
if settings.SETTINGS_MODULE == 'awx.settings.development':
from awx.api.swagger import AutoSchema
from awx.api.swagger import schema_view

return AutoSchema()
return schema_view
else:
return views.APIView.schema

Expand Down
64 changes: 28 additions & 36 deletions awx/api/swagger.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,54 @@
import warnings

from rest_framework.permissions import AllowAny
from rest_framework.schemas import SchemaGenerator, AutoSchema as DRFAuthSchema

from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from drf_yasg.inspectors import SwaggerAutoSchema
from drf_yasg.views import get_schema_view


class SuperUserSchemaGenerator(SchemaGenerator):
def has_view_permissions(self, path, method, view):
#
# Generate the Swagger schema as if you were a superuser and
# permissions didn't matter; this short-circuits the schema path
# discovery to include _all_ potential paths in the API.
#
return True

class CustomSwaggerAutoSchema(SwaggerAutoSchema):
"""Custom SwaggerAutoSchema to add swagger_topic to tags."""

class AutoSchema(DRFAuthSchema):
def get_link(self, path, method, base_url):
link = super(AutoSchema, self).get_link(path, method, base_url)
def get_tags(self, operation_keys=None):
tags = []
try:
serializer = self.view.get_serializer()
if hasattr(self.view, 'get_serializer'):
serializer = self.view.get_serializer()
else:
serializer = None
except Exception:
serializer = None
warnings.warn(
'{}.get_serializer() raised an exception during '
'schema generation. Serializer fields will not be '
'generated for {} {}.'.format(self.view.__class__.__name__, method, path)
'generated for {}.'.format(self.view.__class__.__name__, operation_keys)
)

link.__dict__['deprecated'] = getattr(self.view, 'deprecated', False)

# auto-generate a topic/tag for the serializer based on its model
if hasattr(self.view, 'swagger_topic'):
link.__dict__['topic'] = str(self.view.swagger_topic).title()
tags.append(str(self.view.swagger_topic).title())
elif serializer and hasattr(serializer, 'Meta'):
link.__dict__['topic'] = str(serializer.Meta.model._meta.verbose_name_plural).title()
tags.append(str(serializer.Meta.model._meta.verbose_name_plural).title())
elif hasattr(self.view, 'model'):
link.__dict__['topic'] = str(self.view.model._meta.verbose_name_plural).title()
tags.append(str(self.view.model._meta.verbose_name_plural).title())
else:
warnings.warn('Could not determine a Swagger tag for path {}'.format(path))
return link
tags = ['api'] # Fallback to default value

if not tags:
warnings.warn(f'Could not determine tags for {self.view.__class__.__name__}')
return tags

def get_description(self, path, method):
setattr(self.view.request, 'swagger_method', method)
description = super(AutoSchema, self).get_description(path, method)
return description
def is_deprecated(self):
"""Return `True` if this operation is to be marked as deprecated."""
return getattr(self.view, 'deprecated', False)


schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="[email protected]"),
license=openapi.License(name="BSD License"),
title='AWX API',
default_version='v2',
description='AWX API Documentation',
terms_of_service='https://www.google.com/policies/terms/',
contact=openapi.Contact(email='[email protected]'),
license=openapi.License(name='Apache License'),
),
public=True,
permission_classes=[AllowAny],
Expand Down
16 changes: 15 additions & 1 deletion awx/main/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
from awx.main.utils.common import bypass_in_test
from awx.main.utils.common import bypass_in_test, load_all_entry_points_for
from awx.main.utils.migration import is_database_synchronized
from awx.main.utils.named_url_graph import _customize_graph, generate_graph
from awx.conf import register, fields

from awx_plugins.interfaces._temporary_private_licensing_api import detect_server_product_name


class MainConfig(AppConfig):
name = 'awx.main'
Expand Down Expand Up @@ -60,6 +62,17 @@ def _load_credential_types_feature(self):
def load_credential_types_feature(self):
return self._load_credential_types_feature()

def load_inventory_plugins(self):
from awx.main.models.inventory import InventorySourceOptions

is_awx = detect_server_product_name() == 'AWX'
extra_entry_point_groups = () if is_awx else ('inventory.supported',)
entry_points = load_all_entry_points_for(['inventory', *extra_entry_point_groups])

for entry_point_name, entry_point in entry_points.items():
cls = entry_point.load()
InventorySourceOptions.injectors[entry_point_name] = cls

def ready(self):
super().ready()

Expand All @@ -71,3 +84,4 @@ def ready(self):
if not os.environ.get('AWX_SKIP_CREDENTIAL_TYPES_DISCOVER', None):
self.load_credential_types_feature()
self.load_named_url_feature()
self.load_inventory_plugins()
3 changes: 2 additions & 1 deletion awx/main/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@
register(
'LOG_AGGREGATOR_LOGGERS',
field_class=fields.StringListField,
default=['awx', 'activity_stream', 'job_events', 'system_tracking', 'broadcast_websocket'],
default=['awx', 'activity_stream', 'job_events', 'system_tracking', 'broadcast_websocket', 'job_lifecycle'],
label=_('Loggers Sending Data to Log Aggregator Form'),
help_text=_(
'List of loggers that will send HTTP logs to the collector, these can '
Expand All @@ -602,6 +602,7 @@
'job_events - callback data from Ansible job events\n'
'system_tracking - facts gathered from scan jobs\n'
'broadcast_websocket - errors pertaining to websockets broadcast metrics\n'
'job_lifecycle - logs related to processing of a job\n'
),
category=_('Logging'),
category_slug='logging',
Expand Down
2 changes: 1 addition & 1 deletion awx/main/dispatch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def current_notifies(conn):
ns = conn.wait(psycopg.generators.notifies(conn.pgconn))
except psycopg.errors._NO_TRACEBACK as ex:
raise ex.with_traceback(None)
enc = psycopg._encodings.pgconn_encoding(conn.pgconn)
for pgn in ns:
enc = conn.pgconn._encoding
n = psycopg.connection.Notify(pgn.relname.decode(enc), pgn.extra.decode(enc), pgn.be_pid)
yield n

Expand Down
6 changes: 4 additions & 2 deletions awx/main/dispatch/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
from jinja2 import Template
import psutil

from ansible_base.lib.logging.runtime import log_excess_runtime

from awx.main.models import UnifiedJob
from awx.main.dispatch import reaper
from awx.main.utils.common import convert_mem_str_to_bytes, get_mem_effective_capacity, log_excess_runtime
from awx.main.utils.common import convert_mem_str_to_bytes, get_mem_effective_capacity

if 'run_callback_receiver' in sys.argv:
logger = logging.getLogger('awx.main.commands.run_callback_receiver')
Expand Down Expand Up @@ -366,7 +368,7 @@ def full(self):
def debug_meta(self):
return 'min={} max={}'.format(self.min_workers, self.max_workers)

@log_excess_runtime(logger)
@log_excess_runtime(logger, debug_cutoff=0.05, cutoff=0.2)
def cleanup(self):
"""
Perform some internal account and cleanup. This is run on
Expand Down
6 changes: 4 additions & 2 deletions awx/main/dispatch/worker/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
from django import db
from django.conf import settings

from ansible_base.lib.logging.runtime import log_excess_runtime

from awx.main.dispatch.pool import WorkerPool
from awx.main.dispatch.periodic import Scheduler
from awx.main.dispatch import pg_bus_conn
from awx.main.utils.common import log_excess_runtime
from awx.main.utils.db import set_connection_name
import awx.main.analytics.subsystem_metrics as s_metrics

Expand Down Expand Up @@ -126,7 +127,7 @@ def process_task(self, body):
return
self.dispatch_task(body)

@log_excess_runtime(logger)
@log_excess_runtime(logger, debug_cutoff=0.05, cutoff=0.2)
def record_statistics(self):
if time.time() - self.last_stats > 1: # buffer stat recording to once per second
try:
Expand Down Expand Up @@ -183,6 +184,7 @@ def __init__(self, *args, schedule=None, **kwargs):
schedule['metrics_gather'] = {'control': self.record_metrics, 'schedule': timedelta(seconds=20)}
self.scheduler = Scheduler(schedule)

@log_excess_runtime(logger, debug_cutoff=0.05, cutoff=0.2)
def record_metrics(self):
current_time = time.time()
self.pool.produce_subsystem_metrics(self.subsystem_metrics)
Expand Down
Loading

0 comments on commit e0fc085

Please sign in to comment.