From e97e60bd301b609fb75103e34f079c301748a5fc Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Tue, 15 Dec 2015 15:14:16 -0500 Subject: [PATCH] Update settings location for certain values * PROJECTS_ROOT * JOBOUTPUT_ROOT * SCHEDULE_MAX_JOBS * STDOUT_MAX_BYTES_DISPLAY --- awx/api/serializers.py | 11 +++++++---- awx/api/views.py | 11 ++++++----- awx/main/models/configuration.py | 2 ++ awx/main/models/jobs.py | 5 +++-- awx/main/models/projects.py | 9 +++++---- awx/main/tasks.py | 9 +++++---- awx/main/tests/ad_hoc.py | 9 +++++---- awx/main/tests/base.py | 7 ++++--- awx/main/tests/projects.py | 5 +++-- awx/main/tests/tasks.py | 5 +++-- awx/main/utils.py | 14 +++++++------- 11 files changed, 50 insertions(+), 37 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index e460fe7789..e14362c36d 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -38,6 +38,7 @@ from awx.main.constants import SCHEDULEABLE_PROVIDERS from awx.main.models import * # noqa from awx.main.utils import get_type_for_model, get_model_for_type, build_url, timestamp_apiformat from awx.main.redact import REPLACE_STR +from awx.main.conf import tower_settings from awx.api.license import feature_enabled @@ -521,8 +522,9 @@ class UnifiedJobSerializer(BaseSerializer): def get_result_stdout(self, obj): obj_size = obj.result_stdout_size - if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: - return "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, settings.STDOUT_MAX_BYTES_DISPLAY) + if obj_size > tower_settings.STDOUT_MAX_BYTES_DISPLAY: + return "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, + tower_settings.STDOUT_MAX_BYTES_DISPLAY) return obj.result_stdout class UnifiedJobListSerializer(UnifiedJobSerializer): @@ -569,8 +571,9 @@ class UnifiedJobStdoutSerializer(UnifiedJobSerializer): def get_result_stdout(self, obj): obj_size = obj.result_stdout_size - if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: - return "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, settings.STDOUT_MAX_BYTES_DISPLAY) + if obj_size > tower_settings.STDOUT_MAX_BYTES_DISPLAY: + return "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, + tower_settings.STDOUT_MAX_BYTES_DISPLAY) return obj.result_stdout def get_types(self): diff --git a/awx/api/views.py b/awx/api/views.py index dd07c57c0a..a307144ed4 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -70,7 +70,7 @@ from awx.api.renderers import * # noqa from awx.api.serializers import * # noqa from awx.fact.models import * # noqa from awx.main.utils import emit_websocket_notification -from awx.main.conf import TowerConfiguration +from awx.main.conf import tower_settings def api_exception_handler(exc): ''' @@ -216,7 +216,7 @@ class ApiV1ConfigView(APIView): if request.user.is_superuser or request.user.admin_of_organizations.filter(active=True).count(): data.update(dict( - project_base_dir = settings.PROJECTS_ROOT, + project_base_dir = tower_settings.PROJECTS_ROOT, project_local_paths = Project.get_local_path_choices(), )) @@ -2862,8 +2862,9 @@ class UnifiedJobStdout(RetrieveAPIView): def retrieve(self, request, *args, **kwargs): unified_job = self.get_object() obj_size = unified_job.result_stdout_size - if request.accepted_renderer.format != 'txt_download' and obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: - response_message = "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, settings.STDOUT_MAX_BYTES_DISPLAY) + if request.accepted_renderer.format != 'txt_download' and obj_size > tower_settings.STDOUT_MAX_BYTES_DISPLAY: + response_message = "Standard Output too large to display (%d bytes), only download supported for sizes over %d bytes" % (obj_size, + tower_settings.STDOUT_MAX_BYTES_DISPLAY) if request.accepted_renderer.format == 'json': return Response({'range': {'start': 0, 'end': 1, 'absolute_end': 1}, 'content': response_message}) else: @@ -2971,7 +2972,7 @@ class SettingsList(ListCreateAPIView): def get_queryset(self): # TODO: docs - if not request.user.is_superuser: + if not self.request.user.is_superuser: # NOTE: Shortcutting the rbac class due to the merging of the settings manifest and the database # we'll need to extend this more in the future when we have user settings return [] diff --git a/awx/main/models/configuration.py b/awx/main/models/configuration.py index b53d45dc63..c7e8d07f68 100644 --- a/awx/main/models/configuration.py +++ b/awx/main/models/configuration.py @@ -52,6 +52,8 @@ class TowerSettings(CreatedModifiedModel): converted_type = self.value elif self.value_type == 'list': converted_type = [x.strip() for x in self.value.split(',')] + elif self.value_type == 'bool': + converted_type = self.value in [True, "true", "True", 1, "1", "yes"] else: t = __builtins__[self.value_type] converted_type = t(self.value) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index dddd91dfc8..fdc7b74241 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -24,6 +24,7 @@ from awx.main.models.unified_jobs import * # noqa from awx.main.utils import decrypt_field, ignore_inventory_computed_fields from awx.main.utils import emit_websocket_notification from awx.main.redact import PlainTextCleaner +from awx.main.conf import tower_settings logger = logging.getLogger('awx.main.models.jobs') @@ -318,9 +319,9 @@ class JobTemplate(UnifiedJobTemplate, JobOptions): @property def cache_timeout_blocked(self): - if Job.objects.filter(job_template=self, status__in=['pending', 'waiting', 'running']).count() > getattr(settings, 'SCHEDULE_MAX_JOBS', 10): + if Job.objects.filter(job_template=self, status__in=['pending', 'waiting', 'running']).count() > getattr(tower_settings, 'SCHEDULE_MAX_JOBS', 10): logger.error("Job template %s could not be started because there are more than %s other jobs from that template waiting to run" % - (self.name, getattr(settings, 'SCHEDULE_MAX_JOBS', 10))) + (self.name, getattr(tower_settings, 'SCHEDULE_MAX_JOBS', 10))) return True return False diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index b90e29cd85..30c6c9d9d1 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -22,6 +22,7 @@ from awx.main.models.base import * # noqa from awx.main.models.jobs import Job from awx.main.models.unified_jobs import * # noqa from awx.main.utils import update_scm_url +from awx.main.conf import tower_settings __all__ = ['Project', 'ProjectUpdate'] @@ -45,9 +46,9 @@ class ProjectOptions(models.Model): @classmethod def get_local_path_choices(cls): - if os.path.exists(settings.PROJECTS_ROOT): - paths = [x.decode('utf-8') for x in os.listdir(settings.PROJECTS_ROOT) - if (os.path.isdir(os.path.join(settings.PROJECTS_ROOT, x)) and + if os.path.exists(tower_settings.PROJECTS_ROOT): + paths = [x.decode('utf-8') for x in os.listdir(tower_settings.PROJECTS_ROOT) + if (os.path.isdir(os.path.join(tower_settings.PROJECTS_ROOT, x)) and not x.startswith('.') and not x.startswith('_'))] qs = Project.objects.filter(active=True) used_paths = qs.values_list('local_path', flat=True) @@ -143,7 +144,7 @@ class ProjectOptions(models.Model): def get_project_path(self, check_if_exists=True): local_path = os.path.basename(self.local_path) if local_path and not local_path.startswith('.'): - proj_path = os.path.join(settings.PROJECTS_ROOT, local_path) + proj_path = os.path.join(tower_settings.PROJECTS_ROOT, local_path) if not check_if_exists or os.path.exists(smart_str(proj_path)): return proj_path diff --git a/awx/main/tasks.py b/awx/main/tasks.py index eef1590d1a..3c6e18ba0f 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -44,6 +44,7 @@ from django.utils.timezone import now from awx.main.constants import CLOUD_PROVIDERS from awx.main.models import * # noqa from awx.main.queue import FifoQueue +from awx.main.conf import tower_settings from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url, ignore_inventory_computed_fields, emit_websocket_notification, check_proot_installed, build_proot_temp_dir, wrap_args_with_proot) @@ -536,9 +537,9 @@ class BaseTask(Task): cwd = self.build_cwd(instance, **kwargs) env = self.build_env(instance, **kwargs) safe_env = self.build_safe_env(instance, **kwargs) - if not os.path.exists(settings.JOBOUTPUT_ROOT): - os.makedirs(settings.JOBOUTPUT_ROOT) - stdout_filename = os.path.join(settings.JOBOUTPUT_ROOT, "%d-%s.out" % (pk, str(uuid.uuid1()))) + if not os.path.exists(tower_settings.JOBOUTPUT_ROOT): + os.makedirs(tower_settings.JOBOUTPUT_ROOT) + stdout_filename = os.path.join(tower_settings.JOBOUTPUT_ROOT, "%d-%s.out" % (pk, str(uuid.uuid1()))) stdout_handle = codecs.open(stdout_filename, 'w', encoding='utf-8') if self.should_use_proot(instance, **kwargs): if not check_proot_installed(): @@ -813,7 +814,7 @@ class RunJob(BaseTask): return self.get_path_to('..', 'playbooks') cwd = job.project.get_project_path() if not cwd: - root = settings.PROJECTS_ROOT + root = tower_settings.PROJECTS_ROOT raise RuntimeError('project local_path %s cannot be found in %s' % (job.project.local_path, root)) return cwd diff --git a/awx/main/tests/ad_hoc.py b/awx/main/tests/ad_hoc.py index 957cd7c084..b5ca386c1b 100644 --- a/awx/main/tests/ad_hoc.py +++ b/awx/main/tests/ad_hoc.py @@ -20,6 +20,7 @@ from awx.main.utils import * # noqa from awx.main.models import * # noqa from awx.main.tests.base import BaseJobExecutionTest from awx.main.tests.tasks import TEST_SSH_KEY_DATA, TEST_SSH_KEY_DATA_LOCKED, TEST_SSH_KEY_DATA_UNLOCK +from awx.main.conf import tower_settings __all__ = ['RunAdHocCommandTest', 'AdHocCommandApiTest'] @@ -325,13 +326,13 @@ class RunAdHocCommandTest(BaseAdHocCommandTest): if not has_proot: self.skipTest('proot is not installed') # Enable proot for this test. - settings.AWX_PROOT_ENABLED = True + tower_settings.AWX_PROOT_ENABLED = True # Hide local settings path. - settings.AWX_PROOT_HIDE_PATHS = [os.path.join(settings.BASE_DIR, 'settings')] + tower_settings.AWX_PROOT_HIDE_PATHS = [os.path.join(settings.BASE_DIR, 'settings')] # Create list of paths that should not be visible to the command. hidden_paths = [ - os.path.join(settings.PROJECTS_ROOT, '*'), - os.path.join(settings.JOBOUTPUT_ROOT, '*'), + os.path.join(tower_settings.PROJECTS_ROOT, '*'), + os.path.join(tower_settings.JOBOUTPUT_ROOT, '*'), ] # Create a temp directory that should not be visible to the command. temp_path = tempfile.mkdtemp() diff --git a/awx/main/tests/base.py b/awx/main/tests/base.py index bdea0523a8..027b19e850 100644 --- a/awx/main/tests/base.py +++ b/awx/main/tests/base.py @@ -31,6 +31,7 @@ from awx.main.models import * # noqa from awx.main.management.commands.run_callback_receiver import CallbackReceiver from awx.main.management.commands.run_task_system import run_taskmanager from awx.main.utils import get_ansible_version +from awx.main.conf import tower_settings from awx.main.task_engine import TaskEngager as LicenseWriter from awx.sso.backends import LDAPSettings @@ -263,14 +264,14 @@ class BaseTestMixin(QueueTestMixin, MockCommonlySlowTestMixin): if not name: name = self.unique_name('Project') - if not os.path.exists(settings.PROJECTS_ROOT): - os.makedirs(settings.PROJECTS_ROOT) + if not os.path.exists(tower_settings.PROJECTS_ROOT): + os.makedirs(tower_settings.PROJECTS_ROOT) # Create temp project directory. if unicode_prefix: tmp_prefix = u'\u2620tmp' else: tmp_prefix = 'tmp' - project_dir = tempfile.mkdtemp(prefix=tmp_prefix, dir=settings.PROJECTS_ROOT) + project_dir = tempfile.mkdtemp(prefix=tmp_prefix, dir=tower_settings.PROJECTS_ROOT) self._temp_paths.append(project_dir) # Create temp playbook in project (if playbook content is given). if playbook_content: diff --git a/awx/main/tests/projects.py b/awx/main/tests/projects.py index f698267a0c..e0cab8f03c 100644 --- a/awx/main/tests/projects.py +++ b/awx/main/tests/projects.py @@ -20,6 +20,7 @@ from django.utils.timezone import now # AWX from awx.main.models import * # noqa +from awx.main.conf import tower_settings from awx.main.tests.base import BaseTransactionTest from awx.main.tests.tasks import TEST_SSH_KEY_DATA, TEST_SSH_KEY_DATA_LOCKED, TEST_SSH_KEY_DATA_UNLOCK, TEST_OPENSSH_KEY_DATA, TEST_OPENSSH_KEY_DATA_LOCKED from awx.main.utils import decrypt_field, update_scm_url @@ -150,7 +151,7 @@ class ProjectsTest(BaseTransactionTest): url = reverse('api:api_v1_config_view') response = self.get(url, expect=200, auth=self.get_super_credentials()) self.assertTrue('project_base_dir' in response) - self.assertEqual(response['project_base_dir'], settings.PROJECTS_ROOT) + self.assertEqual(response['project_base_dir'], tower_settings.PROJECTS_ROOT) self.assertTrue('project_local_paths' in response) self.assertEqual(set(response['project_local_paths']), set(Project.get_local_path_choices())) @@ -218,7 +219,7 @@ class ProjectsTest(BaseTransactionTest): self.assertEquals(results['count'], 0) # can add projects (super user) - project_dir = tempfile.mkdtemp(dir=settings.PROJECTS_ROOT) + project_dir = tempfile.mkdtemp(dir=tower_settings.PROJECTS_ROOT) self._temp_paths.append(project_dir) project_data = { 'name': 'My Test Project', diff --git a/awx/main/tests/tasks.py b/awx/main/tests/tasks.py index acdff99e29..81ee968b21 100644 --- a/awx/main/tests/tasks.py +++ b/awx/main/tests/tasks.py @@ -21,6 +21,7 @@ from crum import impersonate # AWX from awx.main.utils import * # noqa from awx.main.models import * # noqa +from awx.main.conf import tower_settings from awx.main.tests.base import BaseJobExecutionTest TEST_PLAYBOOK = u''' @@ -1412,8 +1413,8 @@ class RunJobTest(BaseJobExecutionTest): project_path = self.project.local_path job_template = self.create_test_job_template() extra_vars = { - 'projects_root': settings.PROJECTS_ROOT, - 'joboutput_root': settings.JOBOUTPUT_ROOT, + 'projects_root': tower_settings.PROJECTS_ROOT, + 'joboutput_root': tower_settings.JOBOUTPUT_ROOT, 'project_path': project_path, 'other_project_path': other_project_path, 'temp_path': temp_path, diff --git a/awx/main/utils.py b/awx/main/utils.py index 9e6a005dc1..ef19e42d8c 100644 --- a/awx/main/utils.py +++ b/awx/main/utils.py @@ -448,8 +448,8 @@ def build_proot_temp_dir(): ''' Create a temporary directory for proot to use. ''' - from django.conf import settings - path = tempfile.mkdtemp(prefix='ansible_tower_proot_', dir=settings.AWX_PROOT_BASE_PATH) + from awx.main.conf import tower_settings + path = tempfile.mkdtemp(prefix='ansible_tower_proot_', dir=tower_settings.AWX_PROOT_BASE_PATH) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) return path @@ -462,13 +462,13 @@ def wrap_args_with_proot(args, cwd, **kwargs): - /var/log/supervisor - /tmp (except for own tmp files) ''' - from django.conf import settings + from awx.main.conf import tower_settings new_args = [getattr(settings, 'AWX_PROOT_CMD', 'proot'), '-v', str(getattr(settings, 'AWX_PROOT_VERBOSITY', '0')), '-r', '/'] hide_paths = ['/etc/tower', '/var/lib/awx', '/var/log', - tempfile.gettempdir(), settings.PROJECTS_ROOT, - settings.JOBOUTPUT_ROOT] - hide_paths.extend(getattr(settings, 'AWX_PROOT_HIDE_PATHS', None) or []) + tempfile.gettempdir(), tower_settings.PROJECTS_ROOT, + tower_settings.JOBOUTPUT_ROOT] + hide_paths.extend(getattr(tower_settings, 'AWX_PROOT_HIDE_PATHS', None) or []) for path in sorted(set(hide_paths)): if not os.path.exists(path): continue @@ -484,7 +484,7 @@ def wrap_args_with_proot(args, cwd, **kwargs): show_paths = [cwd, kwargs['private_data_dir']] else: show_paths = [cwd] - show_paths.extend(getattr(settings, 'AWX_PROOT_SHOW_PATHS', None) or []) + show_paths.extend(getattr(tower_settings, 'AWX_PROOT_SHOW_PATHS', None) or []) for path in sorted(set(show_paths)): if not os.path.exists(path): continue