您的位置:首页 > 运维架构

openstack 调用API 实现云主机的IO 控制,CGroup 策略

2014-05-15 18:47 525 查看
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0 #
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#    Single virtual machine io limit , reader 70/MB , writer 50/MB
"""
curl -d '{"auth": {"tenantName": "admin", "passwordCredentials": {"username": "admin", "password": "admin"}}}' -H "Content-type: application/json" http://127.0.0.1:35357/v2.0/tokens | python -m json.tool
curl -v -d '{"ioctlAction": {"instance_name":"instance-0000000c","limit_reader":"40MB","limit_writer":"60MB"}}' -i http://127.0.0.1:8774/v2/ba5a6a86a8224a70ba0ffde747d8a724/servers/e6b9cae7-8732-405d-9aaf-575643b4bbef/action -X POST -H "X-Auth-Project-Id: ba5a6a86a8224a70ba0ffde747d8a724" -H "Accept: application/json" -H "X-Auth-Token: 6f0c37595f384fd4a18766825cf49013" -H "Content-Type: application/json"
"""
import time,sys,os,libvirt,traceback,re,subprocess,json
from nova import log as logging
from nova import flags
from nova.periodic.blkio  import config
from nova import utils
from nova.periodic.blkio import utils as blkio_utils
FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)
class ActionIoctl(object):
def __init__(self,instance_name,limit_reader,limit_writer):
self.conn = libvirt.open(None)
self.limitReader = int(limit_reader[0:-2])
self.limitWriter = int(limit_writer[0:-2])
self.name = instance_name
self.path = FLAGS.instances_path
def diskDeviceNum(self,disk):
""" Func info:  Returns the number of hard disk,other is 8:0 """
if disk == '/dev/sda1' or disk == '/dev/hda1' or disk[:-1] == '/dev/sda' or disk[:-1] == '/dev/hda':
return '8:0'
elif disk == '/dev/sdb1' or disk == '/dev/hdb1' or disk[:-1] == '/dev/sdb' or disk[:-1] == '/dev/hdb':
return '8:16'
elif disk == '/dev/sdc1' or disk == '/dev/hdc1' or disk[:-1] == '/dev/sdc' or disk[:-1] == '/dev/hdc':
return '8:32'
elif disk == '/dev/sdd1' or disk == '/dev/hdd1' or disk[:-1] == '/dev/sdd' or disk[:-1] == '/dev/hdd':
return '8:48'
else:
return '8:16'
def vmsPIDall(self):
""" Getting all vm port, return to """
pid = list()
try:
cmds = """ps -ef |grep uuid|grep -v grep |awk '{print $2}'"""
pid=os.popen(cmds).readlines()
return pid
except Exception,e:
LOG.error(_('[-william-] Error %s'%e))
return
def cgroupPath(self):
'''
Func info : Return Cgroup path ,Because the system is not the same,
the Cgroup path is different also.
By default, have RedHat, Centos, Ubuntu  linux  ...
osType : The current system version , And return to ...
Cpath  : Cgroup path
'''
osType = open('/etc/issue').readlines()
for i in osType:
if re.match('Ubuntu',i):
Cpath = '/sys/fs/cgroup/'
return Cpath
elif re.match('CentOS',i):
Cpath = '/cgroup/'
return Cpath
elif re.match('Red Hat',i):
Cpath = '/cgroup/'
return Cpath
else:
return '/sys/fs/cgroup/'
def exeCmd(self,cmds):
''' Perform system command '''
LOG.info(_('exeCmd  %s'%cmds))
try:
exec_process = subprocess.Popen(cmds,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell = True)
exec_process.wait()
rest = exec_process.stdout.read()
err = exec_process.stderr.read()
if err == '':
return rest
else:
LOG.error(_('[-william-] return values is null'))
except Exception,e:
LOG.error(_('[-william-] Error %s') %e)
return
''' Geting vmName name  and pid '''
def get_vm_pid(self,name):
pid = self.conn.listDomainsID()
try:
pid = os.popen("""ps -ef |grep %s |grep -v grep |awk '{print $2}'""" %name).readlines()
return int(pid[0])
except:
LOG.error(_('[-william-] Error %s' \
%traceback.format_exc()))
return
def _vm_pids(self):
try:
return os.popen('pidof kvm').read().split()
except:
return
def work(self):
"""
Func info :  working func ................
Cpath : is _Cpath function return values ...
path :  The current virtual machine IMG file path
vm_count: All of the current node number of virtual machines
size :  Limit size
mountInfo : mounting point
"""
Cpath = self.cgroupPath()
vm_pid = self.get_vm_pid(self.name)
LOG.info(_('[- william -] %s , %s' %(self.name,vm_pid)))
r_size = self.limitReader * 1000 * 1000
w_size = self.limitWriter * 1000 * 1000
device = blkio_utils.instance_path(self.path)
diskDeviceNum = self.diskDeviceNum(device)
vmTaskPath = "%s/blkio/%s"%(Cpath,self.name)
utils.execute("mkdir","-p",vmTaskPath,run_as_root=True)
utils.execute("tee" , "%s/blkio.throttle.read_bps_device"%vmTaskPath,\
process_input = "%s %s"%(diskDeviceNum,r_size),\
run_as_root=True)
utils.execute("tee" , "%s/blkio.throttle.write_bps_device"%vmTaskPath, \
process_input = "%s %s"%(diskDeviceNum,w_size) ,\
run_as_root=True)
LOG.info(_(""" [-william-] echo  '%s, %s, %s , %s , %s ' write oK """
%(self.path , device, diskDeviceNum, w_size, r_size)))
utils.execute('tee', '%s/tasks'%vmTaskPath,\
process_input= str(vm_pid) ,\
run_as_root=True)
LOG.info(_('[- william-] append pid %s in task' %vm_pid))
if __name__ == "__main__":
sc = ActionIoctl('instance-0000000c','40MB','30MB')
sc.work()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息