136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
import decimal
|
|
import textwrap
|
|
|
|
from orchestra.contrib.orchestration import ServiceController
|
|
from orchestra.contrib.resources import ServiceMonitor
|
|
|
|
from . import settings
|
|
|
|
|
|
class ProxmoxOVZ(ServiceController):
|
|
model = 'vps.VPS'
|
|
|
|
RESOURCES = (
|
|
('memory', 'mem'),
|
|
('swap', 'swap'),
|
|
('disk', 'disk')
|
|
)
|
|
GET_PROXMOX_INFO = textwrap.dedent("""
|
|
function get_vz_info () {
|
|
hostname=$1
|
|
version=$(pveversion | cut -d '/' -f2 | cut -d'.' -f1)
|
|
if [[ $version -lt 2 ]]; then
|
|
conf=$(grep "CID\\|:$hostname:" /var/lib/pve-manager/vzlist | grep -B1 ":$hostname:")
|
|
CID=$(echo "$conf" | head -n1 | cut -d':' -f2)
|
|
CTID=$(echo "$conf" | tail -n1 | cut -d':' -f1)
|
|
node=$(pveca -l | grep "^\\s*$CID\\s*:" | awk {'print $3'})
|
|
else
|
|
conf=$(grep -r "HOSTNAME=\\"$hostname\\"" /etc/pve/nodes/*/openvz/*.conf)
|
|
node=$(echo "${conf}" | cut -d"/" -f5)
|
|
CTID=$(echo "${conf}" | cut -d"/" -f7 | cut -d"\\." -f1)
|
|
fi
|
|
echo $CTID $node
|
|
}""")
|
|
|
|
def prepare(self):
|
|
super(ProxmoxOVZ, self).prepare()
|
|
self.append(self.GET_PROXMOX_INFO)
|
|
|
|
def get_vzset_args(self, context):
|
|
args = list(settings.VPS_DEFAULT_VZSET_ARGS)
|
|
for resource, arg_name in self.RESOURCES:
|
|
try:
|
|
allocation = context[resource]
|
|
except KeyError:
|
|
pass
|
|
else:
|
|
args.append('--%s %i' % (arg_name, allocation))
|
|
return ' '.join(args)
|
|
|
|
def run_ssh_commands(self, ssh_commands):
|
|
commands = '\n '.join(ssh_commands)
|
|
self.append(textwrap.dedent("""\
|
|
cat << EOF | ssh root@${info[1]}
|
|
%s
|
|
EOF""") % commands
|
|
)
|
|
|
|
def save(self, vps):
|
|
# TODO create the container
|
|
context = self.get_context(vps)
|
|
self.append(textwrap.dedent("""
|
|
info=( $(get_vz_info %(hostname)s) )
|
|
echo "Managing ${info[@]}"\
|
|
""") % context
|
|
)
|
|
ssh_commands = []
|
|
vzset_args = self.get_vzset_args(context)
|
|
if vzset_args:
|
|
context['vzset_args'] = vzset_args
|
|
ssh_commands.append("pvectl vzset ${info[0]} %(vzset_args)s" % context)
|
|
if hasattr(vps, 'password'):
|
|
context['password'] = vps.password.replace('$', '\\$')
|
|
ssh_commands.append(textwrap.dedent("""\
|
|
echo 'root:%(password)s' \\
|
|
| chroot /var/lib/vz/private/${info[0]} chpasswd -e""") % context
|
|
)
|
|
self.run_ssh_commands(ssh_commands)
|
|
|
|
def get_context(self, vps):
|
|
context = {
|
|
'hostname': vps.hostname,
|
|
}
|
|
for resource, __ in self.RESOURCES:
|
|
try:
|
|
allocation = getattr(vps.resources, resource).allocated
|
|
except AttributeError:
|
|
pass
|
|
else:
|
|
context[resource] = allocation
|
|
return context
|
|
|
|
|
|
class ProxmoxOpenVZTraffic(ServiceMonitor):
|
|
model = 'vps.VPS'
|
|
resource = ServiceMonitor.TRAFFIC
|
|
monthly_sum_old_values = True
|
|
GET_PROXMOX_INFO = ProxmoxOVZ.GET_PROXMOX_INFO
|
|
|
|
def prepare(self):
|
|
super(ProxmoxOpenVZTraffic, self).prepare()
|
|
self.append(self.GET_PROXMOX_INFO)
|
|
self.append(textwrap.dedent("""
|
|
function monitor () {
|
|
object_id=$1
|
|
hostname=$2
|
|
info=( $(get_vz_info $hostname) )
|
|
cat << EOF | ssh root@${info[1]}
|
|
vzctl exec ${info[0]} cat /proc/net/dev \\
|
|
| grep venet0 \\
|
|
| tr ':' ' ' \\
|
|
| awk '{sum=\\$2+\\$10} END {printf ("$object_id %0.0f\\n", sum)}'
|
|
EOF
|
|
}
|
|
""")
|
|
)
|
|
|
|
def process(self, line):
|
|
""" diff with last stored state """
|
|
object_id, value, state = super(ProxmoxOpenVZTraffic, self).process(line)
|
|
value = decimal.Decimal(value)
|
|
last = self.get_last_data(object_id)
|
|
if not last or last.state > value:
|
|
return object_id, value, value
|
|
return object_id, value-last.state, value
|
|
|
|
def monitor(self, vps):
|
|
""" Get OpenVZ container traffic on a Proxmox cluster """
|
|
context = self.get_context(vps)
|
|
self.append('monitor %(object_id)s %(hostname)s' % context)
|
|
|
|
def get_context(self, vps):
|
|
return {
|
|
'object_id': vps.id,
|
|
'hostname': vps.hostname,
|
|
}
|