سؤال

لدي مشروع صغير أريد نشره على كل من Heroku وOpenShift، لتجربة الأشياء على كلا النظامين الأساسيين.أنا أستخدم Python/Django لذا أريد الاستفادة من ميزة الاستيراد الديناميكي لتحديد الإعدادات لكل بيئة، والحفاظ على وحدة الإعدادات لتلك الأنظمة الأساسية التي أرغب في النشر عليها، مثل:

my_project/
    settings/
        __init__.py  <-- This is what's being imported during app init, here is where I want to detect which platform specific settings module to load
        dev_settings.py
        heroku_settings.py
        openshift_settings.py

حتى الآن أستخدم هذا الرمز:

ENVIRONMENT = the_function_or_code_that_returns_the_environment() # Defaults to "dev"
from django.utils.importlib import import_module

try:
    # Import any symbols that begin with A-Z. Append to lists any symbols that
    # begin with "EXTRA_".
    local_settings_module_name = '%s_settings' % ENVIRONMENT
    local_settings = import_module(local_settings_module_name)
    import re
    for attr in dir(local_settings):
        match = re.search('^EXTRA_(\w+)', attr)
        if match:
            name = match.group(1)
            value = getattr(local_settings, attr)
            try:
                globals()[name] += value
            except KeyError:
                globals()[name] = value
        elif re.search('^[A-Z]', attr):
            globals()[attr] = getattr(local_settings, attr)
except ImportError:
    pass

سيكون من المفضل اكتشاف ذلك عبر متغيرات البيئة الافتراضية (التي لم يتم تعيينها بواسطتي/المطور).يكشف Heroku عن عدد قليل فقط:

DATABASE_URL
ENVIRONMENT
LANG
LD_LIBRARY_PATH
LIBRARY_PATH
PATH
PYTHONHASHSEED
PYTHONHOME
PYTHONPATH
PYTHONUNBUFFERED
SHARED_DATABASE_URL

و OpenShift:

OPENSHIFT_DB_HOST
OPENSHIFT_LOG_DIR
OPENSHIFT_TMP_DIR
OPENSHIFT_DB_CTL_SCRIPT
OPENSHIFT_REPO_DIR
OPENSHIFT_HOMEDIR
OPENSHIFT_GEAR_NAME
OPENSHIFT_PHPMYADMIN_IP
OPENSHIFT_RUNTIME_DIR
OPENSHIFT_INTERNAL_PORT
OPENSHIFT_PHPMYADMIN_CTL_SCRIPT
OPENSHIFT_DB_MYSQL_51_RESTORE
OPENSHIFT_DB_MYSQL_51_DUMP
OPENSHIFT_DB_PASSWORD
OPENSHIFT_DB_USERNAME
OPENSHIFT_PHPMYADMIN_GEAR_DIR
OPENSHIFT_RUN_DIR
OPENSHIFT_INTERNAL_IP
OPENSHIFT_GEAR_DIR
OPENSHIFT_GEAR_CTL_SCRIPT
OPENSHIFT_APP_DNS
OPENSHIFT_GEAR_TYPE
OPENSHIFT_GEAR_DNS
OPENSHIFT_DB_MYSQL_51_EMBEDDED_TYPE
OPENSHIFT_DB_URL
OPENSHIFT_APP_NAME
OPENSHIFT_DATA_DIR
OPENSHIFT_DB_SOCKET
OPENSHIFT_GEAR_UUID
OPENSHIFT_APP_UUID
OPENSHIFT_DB_TYPE
OPENSHIFT_DB_MYSQL_51_DUMP_CLEANUP
OPENSHIFT_DB_PORT

متغيرات OpenShift مسبوقة بـ OPENSHIFT_ لذلك هناك بداية، ولكن هذا ليس هو الحال مع Heroku.

كيف يمكنني اكتشاف النظام الأساسي بشكل موثوق باستخدام متغيرات البيئة؟

هل كانت مفيدة؟

المحلول 2

@Kevin، أقوم بنشر تعليقي كإجابة، حتى يتمكن الأشخاص من رؤيته بسرعة (أو تحسينه!):

if len([k for k in os.environ.keys() if k.startswith('OPENSHIFT_')]):
    ENVIRONMENT = 'openshift'
elif len([k for k in os.environ.values() if k.find('heroku') > -1]):
    ENVIRONMENT = 'heroku'

local_settings_module_name = '%s_settings' % ENVIRONMENT
local_settings = import_module(local_settings_module_name)
# do the magic with the `local_settings` module

نصائح أخرى

أوصي بتعيين إعداد تكوين ENV الخاص بي.يمكن القيام بذلك بسهولة باستخدام Heroku.

heroku config:add MY_DEPLOYMENT_PLATFORM=heroku

بعد ذلك، في المُهيئ (أو أينما تريد) يمكنك الوصول إلى هذه القيمة كما يلي:

if ENV["MY_DEPLOYMENT_PLATFORM"] == "heroku"
 // perform heroku config
else 
 // perform other PAAS config
end

هذه هي الطريقة التي أكتشف بها PaaS الذي يعمل عليه تطبيقي حاليًا.طريقة overide_settings ليست ملكي.

def override_settings(dottedpath):
    """Imports uppercase modules from an string based module.
    Example:
        override_settings('my.module.settings')
    """
    try:
        _m = import_module(dottedpath)
    except ImportError:
        warnings.warn("Failed to import %s" % dottedpath) # <-- will show up in your error log
    else:
        _thismodule = sys.modules[__name__]
        for _k in dir(_m): # <-- moved the block inside else
            if _k.isupper() and not _k.startswith('__'): setattr(_thismodule,
                _k, getattr(_m, _k))

ON_OPENSHIFT = False
if os.environ.has_key('OPENSHIFT_REPO_DIR'):
    ON_OPENSHIFT = True

ON_HEROKU = False
if os.environ.get('LD_LIBRARY_PATH', None) == '/app/.heroku/vendor/lib':
    ON_HEROKU = True

if ON_OPENSHIFT:
    override_settings('settings.openshift')

if ON_HEROKU:
    override_settings('settings.heroku')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top