Tri*_*ews 7 python boto amazon-web-services
我正在尝试设置一个python记录器,以便在实例已设置标签的情况下记录错误时发送错误电子邮件。然后,我很快遇到了不在AWS上的本地开发计算机的问题。有没有简便快捷的方法来检查脚本是否在AWS上运行?
我正在使用以下方式加载实例数据:
import boto.utils
from boto.ec2.connection import EC2Connection
metadata = boto.utils.get_instance_metadata()
conn = EC2Connection()
instance = conn.get_only_instances(instance_ids=metadata['instance-id'])[0]
Run Code Online (Sandbox Code Playgroud)
我当然可以在get_instance_metadata上使用超时,但是现在要让开发人员等待很长时间与在生产中不发送错误电子邮件的可能性之间存在压力。
谁能想到一个好的解决方案?
与@cgseller类似,假设使用python3,可以执行以下操作:
from urllib.request import urlopen
def is_ec2_instance():
"""Check if an instance is running on AWS."""
result = False
meta = 'http://169.254.169.254/latest/meta-data/public-ipv4'
try:
result = urlopen(meta).status == 200
except ConnectionError:
return result
return result
Run Code Online (Sandbox Code Playgroud)
或者,您可以检查您的环境是否包含任何 AWS环境变量:
is_aws = True if os.environ.get("AWS_DEFAULT_REGION") else False
Run Code Online (Sandbox Code Playgroud)
我选择检查我的用户名是否是 ec2 实例:(不是一个很好的解决方案,但它有效)
my_user = os.environ.get("USER")
is_aws = True if "ec2" in my_user else False
Run Code Online (Sandbox Code Playgroud)
AWS实例具有元数据,因此您可以调用元数据服务并获得响应,如果响应有效,则您是@AWS,否则您不是。
例如:
import urllib2
meta = 'http://169.254.169.254/latest/meta-data/ami-id'
req = urllib2.Request(meta)
try:
response = urllib2.urlopen(req).read()
if 'ami' in response:
_msg = 'I am in AWS running on {}'.format(response)
else:
_msg = 'I am in dev - no AWS AMI'
except Exception as nometa:
_msg = 'no metadata, not in AWS'
print _msg
Run Code Online (Sandbox Code Playgroud)
这只是一个尝试 - 可能有更好的检查,但是这个会让您感受到它,并且您可以根据需要对其进行改进。如果您在本地使用 OpenStack 或其他云服务,您当然会收到元数据响应,因此您必须相应地调整您的检查...
(如果您使用某种启动工具或管理器(如 Chef、puppet、homegrown 等),您也可以使用 cloud-init 来执行此操作。如果 /ec2 文件位于 AWS 中,则将其放入文件系统中,或者如果是本地的则更好在盒子上放一个 /DEV)
我不认为这真的是一个 boto 问题。EC2(以及 boto)不关心也不知道您在服务器上运行的脚本。
如果您的脚本具有特定的签名(例如侦听端口),那么这将是最好的检查方法,但如果无法做到这一点,您可以在操作系统(其进程)中查找其签名。
使用 subprocess 模块和您喜欢的 bash 魔法来检查它是否正在运行:
command = ["ssh", "{user}@{server}", "pgrep", "-fl", "{scriptname}"]
try:
is_running = bool(subprocess.check_output(command))
except subprocess.CalledProcessError:
log.exception("Checking for script failed")
is_running = False
Run Code Online (Sandbox Code Playgroud)