text: 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,
          }
  