我尝试设置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]
我当然可以在get_instance_metadata上使用超时,但是现在有一段时间的紧张关系让开发人员等待,而不是在生产中不发送错误电子邮件的可能性。
有人能想到一个很好的解决方案吗?
答案 0 :(得分:3)
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
这只是一个刺 - 有可能更好的检查,但这一个会让你感觉它,你可以在你认为合适的情况下改进它。如果您在本地使用OpenStack或其他云服务,您当然会得到元数据响应,因此您必须相应地调整支票...
(如果您正在使用某种启动工具或管理员,如厨师,木偶,本土等,您也可以使用cloud-init的东西。如果在AWS中将/ ec2文件放在文件系统中,或者更好但如果本地放弃盒子上的/ DEV)
答案 1 :(得分:1)
我认为这不是一个真正的问题。 EC2(反过来又是boto)不关心或了解您在服务器上运行的脚本。
如果您的脚本有特定的签名 - 例如听一个端口 - 这将是最好的检查方式,但不好意思,你可以在操作系统中寻找它的签名 - 它的过程。
使用子流程模块和您的preferred bash magic to check if it's running:
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
答案 2 :(得分:1)
与@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
答案 3 :(得分:1)
或者,您可以检查您的环境是否包含任何AWS environmental variables:
is_aws = True if os.environ.get("AWS_DEFAULT_REGION") else False
我选择检查我的用户名是否为ec2实例:(不是一个很好的解决方案,但是可以工作)
my_user = os.environ.get("USER")
is_aws = True if "ec2" in my_user else False