【问题标题】:How to reliably determine which PaaS is my project running on?如何可靠地确定我的项目在哪个 PaaS 上运行?
【发布时间】:2012-06-18 23:01:48
【问题描述】:

我有一个小项目,我想同时部署到 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 不是这样。

如何使用环境变量可靠地检测平台?

【问题讨论】:

    标签: configuration heroku environment-variables paas openshift


    【解决方案1】:

    我建议设置我自己的 ENV 配置设置。这可以使用 heroku 轻松完成。

    heroku config:add MY_DEPLOYMENT_PLATFORM=heroku
    

    然后,在您的初始化程序(或任何您需要的地方)中,您可以像这样访问该值:

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

    【讨论】:

    • OpenShift 不允许您设置自定义环境变量(目前),这就是我寻找“启发式”方法的原因。
    • 您仍然可以检查变量是否存在(或缺少)。
    • len([k for k in os.environ.keys() if k.startswith('OPENSHIFT_')]) &gt; 0 # Test for OpenShift, len([k for k in os.environ.values() if k.find('heroku') &gt; -1]) &gt; 0 # Test for 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
    

    【讨论】:

      【解决方案3】:

      这就是我检测我的应用当前使用的 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')
      

      【讨论】:

        猜你喜欢
        • 2014-10-22
        • 2020-11-17
        • 1970-01-01
        • 1970-01-01
        • 2017-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多