From 5afe5de520632d1cd67626e0ef04264fa7a95d40 Mon Sep 17 00:00:00 2001 From: Chenyang Yan Date: Fri, 1 Oct 2021 11:15:24 +0800 Subject: [PATCH] Feature: Support check BK_IAM_MIGRATION_APP_NAME settings Since pip installation need `BK_IAM_MIGRATION_APP_NAME` according to docs/usage.md -> IAM Migration -> Django Migration. If not finding `BK_IAM_MIGRATION_APP_NAME`, will fail for `apps.get_app_config` since `MIGRATION_APP_NAME = getattr(settings, "BK_IAM_MIGRATION_APP_NAME", APP_NAME)` in `iam/contrib/iam_migration/conf.py` It's required to pay attention to different sitepackages directory in different Debian/... Distro: ``` >>> import site >>> site.getsitepackages() ['/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.6/dist-packages'] >>> import iam >>> iam.__file__ '/usr/local/lib/python3.6/dist-packages/iam/__init__.py' $ python3 -m venv /tmp/venv >>> import site >>> site.getsitepackages() ['/tmp/venv/lib/python3.6/site-packages', '/tmp/venv/local/lib/python3.6/dist-packages', '/tmp/venv/lib/python3/dist-packages', '/tmp/venv/lib/python3.6/dist-packages'] >>> import iam >>> iam.__file__ '/tmp/venv/lib/python3.6/site-packages/iam/__init__.py' ``` Signed-off-by: Chenyang Yan --- iam/contrib/iam_migration/__init__.py | 2 ++ iam/contrib/iam_migration/apps.py | 29 ++++++++++++++++++- iam/contrib/iam_migration/conf.py | 4 +-- iam/contrib/iam_migration/constants.py | 3 +- .../management/commands/iam_makemigrations.py | 14 +++++---- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/iam/contrib/iam_migration/__init__.py b/iam/contrib/iam_migration/__init__.py index 0bb6b21..965284e 100644 --- a/iam/contrib/iam_migration/__init__.py +++ b/iam/contrib/iam_migration/__init__.py @@ -9,3 +9,5 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ + +default_app_config = "iam.contrib.iam_migration.apps.IAMMigrationConfig" diff --git a/iam/contrib/iam_migration/apps.py b/iam/contrib/iam_migration/apps.py index b21232e..17e1ad0 100644 --- a/iam/contrib/iam_migration/apps.py +++ b/iam/contrib/iam_migration/apps.py @@ -10,12 +10,39 @@ specific language governing permissions and limitations under the License. """ +import os +import sys +import six from django.apps import AppConfig +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured -from iam.contrib.iam_migration.constants import APP_NAME, APP_VERBOSE_NAME +from iam.contrib.iam_migration.constants import APP_NAME, APP_VERBOSE_NAME, BK_IAM_MIGRATION_APP_NAME class IAMMigrationConfig(AppConfig): name = APP_NAME + label = name.rpartition(".")[2] + default = True verbose_name = APP_VERBOSE_NAME + + def ready(self): + # dist-packages: Debian distributions modify upstream Python + for site_or_dist in ("site-packages", "dist-packages"): + module_package_path = os.path.join("lib", "python%d.%d" % sys.version_info[:2], site_or_dist, "iam") + if module_package_path in self.path: + break + else: + return + # Checking must be set `BK_IAM_MIGRATION_APP_NAME` for pip installation + if not getattr(settings, BK_IAM_MIGRATION_APP_NAME, None): + raise ImproperlyConfigured( + "The %r setting must not be empty for iam with pip installation package" % BK_IAM_MIGRATION_APP_NAME + ) + if not isinstance(settings.BK_IAM_MIGRATION_APP_NAME, six.string_types): + raise ImproperlyConfigured( + "The %r setting must be instance of %s" % (BK_IAM_MIGRATION_APP_NAME, six.string_types) + ) + if settings.BK_IAM_MIGRATION_APP_NAME not in settings.INSTALLED_APPS: + raise ImproperlyConfigured("The %r setting not in installed apps" % BK_IAM_MIGRATION_APP_NAME) diff --git a/iam/contrib/iam_migration/conf.py b/iam/contrib/iam_migration/conf.py index c4cbff1..622b875 100644 --- a/iam/contrib/iam_migration/conf.py +++ b/iam/contrib/iam_migration/conf.py @@ -13,6 +13,6 @@ from django.conf import settings -from iam.contrib.iam_migration.constants import APP_NAME +from iam.contrib.iam_migration.constants import APP_NAME, BK_IAM_MIGRATION_APP_NAME -MIGRATION_APP_NAME = getattr(settings, "BK_IAM_MIGRATION_APP_NAME", APP_NAME) +MIGRATION_APP_NAME = getattr(settings, BK_IAM_MIGRATION_APP_NAME, APP_NAME) diff --git a/iam/contrib/iam_migration/constants.py b/iam/contrib/iam_migration/constants.py index 1b28538..d94416a 100644 --- a/iam/contrib/iam_migration/constants.py +++ b/iam/contrib/iam_migration/constants.py @@ -11,5 +11,6 @@ """ -APP_NAME = "iam_migration" +APP_NAME = "iam.contrib.iam_migration" APP_VERBOSE_NAME = "IAM Migration" +BK_IAM_MIGRATION_APP_NAME = "BK_IAM_MIGRATION_APP_NAME" diff --git a/iam/contrib/iam_migration/management/commands/iam_makemigrations.py b/iam/contrib/iam_migration/management/commands/iam_makemigrations.py index 5c4cc9e..81e9022 100644 --- a/iam/contrib/iam_migration/management/commands/iam_makemigrations.py +++ b/iam/contrib/iam_migration/management/commands/iam_makemigrations.py @@ -38,15 +38,16 @@ def handle(self, *args, **options): json_file = options["migration_json"] if not json_file: sys.stderr.write("please provide a migration json file name\n") - exit(1) + sys.exit(1) json_path = getattr(settings, "BK_IAM_MIGRATION_JSON_PATH", "support-files/iam/") file_path = os.path.join(settings.BASE_DIR, json_path, json_file) - if not os.path.exists(file_path): sys.stderr.write("{} is not exist.\n".format(file_path)) - exit(1) + sys.exit(1) + iam_migration_app_instance = apps.get_app_config(IAMMigrationConfig.label) + iam_migration_app_instance.ready() loader = MigrationLoader(None, ignore_no_migrations=False) migration_leaf = loader.graph.leaf_nodes(conf.MIGRATION_APP_NAME) @@ -62,8 +63,11 @@ def handle(self, *args, **options): migration_name = self.migration_name(last_migration_name) migration_file = "{}.py".format( - os.path.join(apps.get_app_config(conf.MIGRATION_APP_NAME).path, "migrations", migration_name) + os.path.join( + apps.get_app_config(conf.MIGRATION_APP_NAME.rpartition(".")[2]).path, "migrations", migration_name + ) ) + sys.stdout.write("write migrations file: {}\n".format(migration_file)) with codecs.open(migration_file, mode="w", encoding="utf-8") as fp: template = Engine.get_default().from_string(migration_template) @@ -86,7 +90,7 @@ def migration_name(self, last_migration_name): if not system_id: self.stderr.write("You must set BK_IAM_SYSTEM_ID in django settings before make migrations") - exit(1) + sys.exit(1) if not last_migration_name: return "0001_initial"