Skip to content

Commit 66558c2

Browse files
committed
add imageoper
1 parent b5868f9 commit 66558c2

6 files changed

Lines changed: 213 additions & 0 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,8 @@ blog:[RDS物理备份自动恢复至IDC线下服务器实践](#)
4444
> Python实现端口检测
4545
4646
blog:[Python实现端口检测](http://blog.51cto.com/kaliarch/2149228)
47+
48+
## Python实现ECS自动镜像创建&镜像复制至其他地域(imageoper)
49+
> Python实现ECS自动镜像创建&镜像复制至其他地域
50+
51+
blog:[Python实现ECS自动镜像创建&镜像复制至其他地域](http://blog.51cto.com/kaliarch/2150076)
1.58 KB
Binary file not shown.

imageoper/config.cfg

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# 阿里云ak配置,建议采用子账户只授权ecs镜像操作
2+
[common]
3+
# 阿里云acccesskeyid
4+
accessKeyId = LTAIhfXlcxxxxxxxxx
5+
# 阿里云accesssecret
6+
accessSecret = GwfAMvR4K2ELmtxxxxxxxxxxxxxx
7+
# log目录名称
8+
logdir_name = logdir
9+
# log文件名称
10+
logfile_name = ecsoperlog.log
11+
12+
# ecs源地域配置信息段
13+
#支持在华北 1、华北 2、华北 3、华北 5、华东 1、华东 2 和华南 1 地域之间复制镜像。涉及其他国家和地区地域时,可以 提交工单 申请
14+
[source]
15+
# 源地域实例regionid,可以参考:https://help.aliyun.com/document_detail/40654.html?spm=a2c1g.8271268.10000.5.5f98df25B98bhJ
16+
s_RegionId = cn-shanghai
17+
18+
# 源实例id
19+
s_InstanceId = i-uf6er9hxb1vt0bxgjctw
20+
21+
# 源端制作镜像name
22+
s_ImageName = api-source-image
23+
24+
# 源镜像描述信息
25+
s_Description = api-source-image源镜像描述信息
26+
27+
# 镜像复制目的地域配置信息段
28+
[destination]
29+
# 目的地域实例regionid,
30+
d_DestinationRegionId = cn-qingdao
31+
32+
# 复制过来的镜像名称
33+
d_DestinationImageName = api-destination-image
34+
35+
# 复制过来的镜像描述信息
36+
d_DestinationDescription = api-destination-image目的镜像描述信息
37+
38+

imageoper/create_cop_image.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/bin/env python
2+
# -*- coding:utf-8 -*-
3+
# _auth:kaliarch
4+
5+
import configparser
6+
import time
7+
import json
8+
from aliyunsdkcore import client
9+
from aliyunsdkecs.request.v20140526 import CreateImageRequest
10+
from aliyunsdkecs.request.v20140526 import CopyImageRequest
11+
from aliyunsdkecs.request.v20140526 import DescribeImagesRequest
12+
import logger
13+
14+
15+
class EcsOper():
16+
def __init__(self,logger):
17+
"""
18+
初始化获取系config信息,配置日志
19+
:param logger:
20+
"""
21+
config = configparser.ConfigParser()
22+
config.read('config.cfg',encoding='utf-8')
23+
accessKeyId = config['common']['accessKeyId']
24+
accessSecret = config['common']['accessSecret']
25+
self.s_RegionId = config['source']['s_RegionId']
26+
self.s_InstanceId = config['source']['s_InstanceId']
27+
28+
self.s_ImageName = config['source']['s_ImageName']
29+
self.s_Description = config['source']['s_Description']
30+
31+
self.d_DestinationRegionId = config['destination']['d_DestinationRegionId']
32+
self.d_DestinationImageName = config['destination']['d_DestinationImageName']
33+
self.d_DestinationDescription = config['destination']['d_DestinationDescription']
34+
self.ecshelper = client.AcsClient(accessKeyId,accessSecret,self.s_RegionId)
35+
36+
logger = logger.LogHelper()
37+
logname = logger.create_dir()
38+
self.logoper = logger.create_logger(logname)
39+
40+
# 镜像制作
41+
def _create_image(self):
42+
"""
43+
创建镜像
44+
:return:返回镜像id
45+
"""
46+
s_timer = time.strftime("%Y-%m-%d-%H:%M", time.localtime(time.time()))
47+
request = CreateImageRequest.CreateImageRequest()
48+
request.set_accept_format('json')
49+
request.add_query_param('RegionId', self.s_RegionId)
50+
request.add_query_param('InstanceId', self.s_InstanceId)
51+
request.add_query_param('ImageName', self.s_ImageName + s_timer)
52+
request.add_query_param('Description', self.s_Description + s_timer)
53+
response = self.ecshelper.do_action_with_exception(request)
54+
self.logoper.info('创建镜像任务已提交,镜像id:%s' % json.loads(response)["ImageId"])
55+
print('创建镜像任务已提交,镜像id:%s' % json.loads(response)["ImageId"])
56+
return json.loads(response)["ImageId"]
57+
58+
# 查询镜像状态
59+
def _describe_image(self,imageid):
60+
"""
61+
查询image状态
62+
:param imageid:
63+
:return:
64+
"""
65+
request = DescribeImagesRequest.DescribeImagesRequest()
66+
request.set_accept_format('json')
67+
request.add_query_param('RegionId', self.s_RegionId)
68+
request.add_query_param('ImageId', imageid)
69+
response = self.ecshelper.do_action_with_exception(request)
70+
# 进度 json.loads(response)['Images']['Image'][0]['Progress']
71+
self.logoper.info('镜像创建进度:%s' %json.loads(response)['Images']['Image'][0]['Progress'])
72+
# 镜像状态
73+
return json.loads(response)['Images']['Image'][0]['Status']
74+
75+
76+
#镜像复制
77+
def _copy_image(self,imageid):
78+
"""
79+
镜像复制
80+
:param imageid:源镜像id
81+
:return: 复制成功后的镜像id
82+
"""
83+
flag = True
84+
while flag:
85+
try:
86+
if self._describe_image(imageid) == 'Available':
87+
flag = False
88+
else:
89+
time.sleep(300)
90+
except Exception as e:
91+
pass
92+
print('镜像已经创建完成')
93+
d_timer = time.strftime("%Y-%m-%d-%H:%M", time.localtime(time.time()))
94+
request = CopyImageRequest.CopyImageRequest()
95+
request.set_accept_format('json')
96+
request.add_query_param('RegionId', self.s_RegionId)
97+
request.add_query_param('DestinationRegionId', self.d_DestinationRegionId)
98+
request.add_query_param('DestinationImageName', self.d_DestinationImageName + d_timer)
99+
request.add_query_param('DestinationDescription', self.d_DestinationDescription + d_timer)
100+
request.add_query_param('ImageId', imageid)
101+
response = self.ecshelper.do_action_with_exception(request)
102+
self.logoper.info('复制镜像任务已提交,镜像id:%s' % json.loads(response)['ImageId'])
103+
print('复制镜像任务已提交,镜像id:%s' % json.loads(response)['ImageId'])
104+
return json.loads(response)['ImageId']
105+
106+
107+
def run(self):
108+
s_imageid = self._create_image()
109+
self._copy_image(s_imageid)
110+
111+
112+
if __name__ == '__main__':
113+
ecsoper = EcsOper(logger)
114+
ecsoper.run()
115+
116+
117+
118+
119+
120+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2018-07-25 16:13:07,098 - root - INFO - ���������������ύ,����id:m-uf6eby4dmp9llm9dgz50
2+
2018-07-25 16:18:09,721 - root - INFO - ���񴴽�����:100%
3+
2018-07-25 16:18:10,067 - root - INFO - ���ƾ����������ύ,����id:m-m5eb53zrph7pic6zuejq

imageoper/logger.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/env python
2+
# -*- coding:utf-8 -*-
3+
# _auth:kaliarch
4+
5+
6+
import os
7+
import time
8+
import logging
9+
import configparser
10+
11+
class LogHelper():
12+
"""
13+
初始化logger,读取目录及文件名称
14+
"""
15+
def __init__(self):
16+
configoper = configparser.ConfigParser()
17+
configoper.read('config.cfg',encoding='utf-8')
18+
self.logdir_name = configoper['common']['logdir_name']
19+
self.logfile_name = configoper['common']['logfile_name']
20+
21+
def create_dir(self):
22+
"""
23+
创建目录
24+
:return: 文件名称
25+
"""
26+
_LOGDIR = os.path.join(os.path.dirname(__file__), self.logdir_name)
27+
_TIME = time.strftime('%Y-%m-%d', time.gmtime()) + '-'
28+
_LOGNAME = _TIME + self.logfile_name
29+
LOGFILENAME = os.path.join(_LOGDIR, _LOGNAME)
30+
if not os.path.exists(_LOGDIR):
31+
os.mkdir(_LOGDIR)
32+
return LOGFILENAME
33+
34+
def create_logger(self, logfilename):
35+
"""
36+
创建logger对象
37+
:param logfilename:
38+
:return: logger对象
39+
"""
40+
logger = logging.getLogger()
41+
logger.setLevel(logging.INFO)
42+
handler = logging.FileHandler(logfilename)
43+
handler.setLevel(logging.INFO)
44+
formater = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
45+
handler.setFormatter(formater)
46+
logger.addHandler(handler)
47+
return logger

0 commit comments

Comments
 (0)