Commit b9cf7271 authored by Seblu's avatar Seblu
Browse files

Live free or die hard

parent 0d82cea3
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
==================
Tag Query Language
==================
== by examples ==
# list accounts
> list a

# list hypervisor
> list hv

# list vm
> list vm

# list vm of hypervisor toto
> list hv=toto&vm

# list vm chiche of hypervisor toto
> list hv=toto&vm=chiche

#list vm with 2 cpu
> list vm&cpu=2

#list vm with 2 cpu and mem > 10g
> list vm&cpu=2&mem>10g

#list hypervistor with 2cpu and vm with 2cpu
> list hv&cpu=2&vm&cpu=2

#list hypervistor at least 2cpu and show tags pop and alloc
> list hv&cpu>=2$pop$alloc

== Basics ==
- TQL build a list of objects from left to right
- Every tag can add or remove objects
- Separators create link between tag
- Operators apply only on one tag

== separators of tags ==
& and between tags
$ show a tag

== operators on tags ==
= strict equality
!= not strict equlity
: globing matching
!:not globing matching
~ regex matching
!~ not regex matching
> superior strict
>= superior
< inferior
<= inferior strict

== number facility ==
10k = 1000
10ki = 1024
1m = 1000 ^ 2
1mi = 1024 ^ 2
1g = 1000 ^ 3
1gi = 1024 ^ 3

== well known tags ==
a: account name
hv: hypervisor name
vm: virtual machine name
id: a.hv.vm
h: hostname
role: (hypersivor/host/cli/vm)
hvtype: hypervistor type (xen/kvm)
libvirtver: Libvirt version
status: online/offline
vmstatus: Running/Paused/Stoped
pop: Point of Presence
cpu: cpu count
mem: memory size
usedmem: memory used
freemem: memory free
arch: (x86/x64)
uname: uname of host
uptime: uptime of hostname
load: load average
hvm: hardware virtualisation enabled
alloc: host is allowed to be selected to a migration
nvm: vm count on an hypervisor
version: account version
sto: total available storage
freesto: free storage
usedsto: used storage


===========
New release
===========
@@ -5,3 +95,5 @@ Update version in debian/control
Update version in debian/changelog
Update version in setup.py
Update version in cccli/__init__.py

+10 −9
Original line number Diff line number Diff line
@@ -17,17 +17,15 @@ import warnings
import getpass

settings = {}
alias = {}

try:
    # parse rc file
    if "HOME" in os.environ and  os.access("%s/.cc-cli.conf"%os.environ["HOME"], os.R_OK):
        fparser = ConfigParser.SafeConfigParser()
        fparser.read("%s/.cc-cli.conf"%os.environ["HOME"])
        settings["alias"] = "%s/.cc-cli.conf"%os.environ["HOME"]
        if fparser.has_section("cli"):
            settings = dict(fparser.items("cli"))
        if fparser.has_section("alias"):
            alias = dict(fparser.items("alias"))
            settings.update(fparser.items("cli"))

    # parse env
    if "CC_SERVER" in os.environ:
@@ -36,6 +34,8 @@ try:
        settings["port"] = os.environ["CC_PORT"]
    if "CC_LOGIN" in os.environ:
        settings["login"] = os.environ["CC_LOGIN"]
    if "CC_PASS" in os.environ:
        settings["pass"] = os.environ["CC_PASS"]
    if "CC_DEBUG" in os.environ:
        settings["debug"] = "True"

@@ -78,8 +78,8 @@ try:
        sys.exit(1)

    # remove pass to prevent stupid guy
    if "pass" in settings:
        del settings["pass"]
    #if "pass" in settings:
    #    del settings["pass"]

    # debug stuff
    if "debug" in settings:
@@ -88,7 +88,6 @@ try:
        warnings.filterwarnings("ignore")
    printer.debug("Debugging on")
    printer.debug("Settings: %s"%settings)
    printer.debug("Alias: %s"%alias)

    # checking needs
    if settings["server"] == "":
@@ -103,15 +102,17 @@ try:
        settings["login"] = raw_input("Login: ")

    # asking for password
    if settings["pass"] == "":
        settings["pass"] = getpass.getpass("Password: ")

    # start cli
    cli = cli.Cli(settings, alias, args)
    cli = cli.Cli(settings, args)
    cli.start()
except KeyboardInterrupt:
    exit(1)
except Exception, e:
    if cccli.debug:
        printer.fatal(str(e), exitcode=-1)
        printer.warn("This is a not expected error, please report it!")
        raise
    printer.fatal(str(e))
+0 −5
Original line number Diff line number Diff line
@@ -7,8 +7,3 @@ CloudControl CLI

version = "1~dev"
debug = False

import printer
import cli
import clierror
import command
+71 −18
Original line number Diff line number Diff line
@@ -10,24 +10,30 @@ import sys
import socket
import ssl
import threading
import subprocess
import ConfigParser
import cccli
from cccli import printer, command
from cccli.clierror import *
from cccli.command import Command
from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure, threadless, ConnectionProxy
import sjrpc.core.exceptions

import re
import readline

class Cli(object):

    def __init__(self, settings, alias, args):
    def __init__(self, settings, args):
        self._settings = settings
        self._alias = alias
        if "alias" in settings:
            self.alias = Alias(settings["alias"])
            self.alias.load()
        self._interactive = sys.stderr.isatty() and sys.stdin.isatty()
        self._prompt = "> "
        self._commands = args
        self._rpc = None
        self.rpc = None

    def start(self):
        '''Start a CLI'''
@@ -48,15 +54,18 @@ class Cli(object):
        printer.debug("Connecting...")
        rpcc = SimpleRpcClient.from_addr(self._settings["server"],
                                        self._settings["port"],
                                        enable_ssl=True
                                        enable_ssl=True,
                                        on_disconnect=self._on_disconnect
                                        )
        # FIXME: wait sjrpc v5 with on_disconnect usable
        rpcc.start(daemonize=True)
        self._rpc = ConnectionProxy(rpcc)
        self.rpc = ConnectionProxy(rpcc)

    def _on_disconnect(self, rpc):
        printer.fatal("Disconnected from server!")

    def _auth(self):
        printer.debug("Authenticating...")
        if self._rpc.authentify(self._settings["login"], self._settings["pass"]):
        if self.rpc.authentify(self._settings["login"], self._settings["pass"]):
            printer.debug("Authenticated.")
        else:
            printer.fatal("Autentification failed!")
@@ -69,8 +78,6 @@ class Cli(object):
            try:
                line = raw_input(self._prompt)
                self._parse_line(line)
            except BadCommand, e:
                printer.error("No such command: %s"%e[0])
            except EOFError:
                printer.out("")
                break
@@ -78,12 +85,6 @@ class Cli(object):
                break
            except KeyboardInterrupt:
                printer.out("")
            except Exception, e:
                printer.error(e)
                if cccli.debug:
                    raise
                else:
                    printer.error("This is a not expected error, please report it!")
        try:
            pass
            #readline.write_history_file(self._settings["histfile"])
@@ -107,10 +108,62 @@ class Cli(object):
                p.wait()
                ret = p.returncode
            elif (cmd[0] == "?"):
                command.Command("help").call()
                Command("help").call()
            else:
                self._parse_command(cmd)

    def _parse_command(self, cmd):
        try:
            # lex command
            argv = self._lex_argv(cmd)
                command.Command(argv, self._rpc).call()
            # alias subs
            if argv[0] in self.alias:
                argv[0] = self.alias[argv[0]]
            # execute command
            Command(argv, self).call()
        except BadArgument, e:
            if str(e) != "":
                printer.error("Bad argument: %s."%str(e))
            else:
                printer.error("Bad argument.")
            usage = Command.usage(argv[0])
            if usage != "":
                printer.out("usage: %s."%usage)
        except BadCommand:
            printer.error("No command: %s."%argv[0])
        except sjrpc.core.exceptions.RpcError, e:
            if cccli.debug: raise
            printer.error("sjRPC: %s"%str(e))
        except Exception, e:
            if cccli.debug: raise
            printer.error("%s: %s."%(argv[0], str(e)))

    def _lex_argv(self, string):
        '''Lex command argument'''
        return string.split(" ")


class Alias(dict):
    ''' Alias wrapper'''
    def __init__(self, filename):
        self._filename = filename

    def load(self):
        '''load alias from file'''
        if os.access(self._filename, os.R_OK):
            fparser = ConfigParser.SafeConfigParser()
            fparser.read(self._filename)
            if fparser.has_section("alias"):
                self.clear()
                self.update(fparser.items("alias"))

    def save(self):
        '''save alias on file'''
        if os.access(self._filename, os.R_OK or os.W_OK):
            fparser = ConfigParser.SafeConfigParser()
            fparser.read(self._filename)
            fparser.remove_section("alias")
            fparser.add_section("alias")
            for n,v in self.items():
                fparser.set("alias", n, v)
            fparser.write(open(self._filename, "w"))
+3 −0
Original line number Diff line number Diff line
@@ -11,3 +11,6 @@ class cliError(Exception):

class BadCommand(cliError):
    pass

class BadArgument(cliError):
    pass
Loading