Skip to content
Snippets Groups Projects
Commit 0d82cea3 authored by Seblu's avatar Seblu
Browse files

Rome was not built in one day

parent 5fc6d7fa
No related branches found
No related tags found
No related merge requests found
*.pyc
*~
v1
- Initial release
## Makefile
.PHONY: deb debclean
all:
deb:
dpkg-buildpackage
===========
New release
===========
Update version in debian/control
Update version in debian/changelog
Update version in setup.py
Update version in cccli/__init__.py
......@@ -40,48 +40,55 @@ try:
settings["debug"] = "True"
# Parse line argument
oparser = optparse.OptionParser(usage="usage: %prog [options] [server[:port]]",
oparser = optparse.OptionParser(usage="usage: %prog [options] [commands]",
version=cccli.version)
oparser.add_option("-d", "--debug",
action="store_true",
dest="debug",
default=False,
default="",
help="debug mode")
oparser.add_option("-l", "--login",
action="store",
dest="login",
default="",
help="server login")
oparser.add_option("-s", "--server",
action="store",
dest="server",
default="",
help="server address")
oparser.add_option("-p", "--port",
action="store",
dest="port",
default="1984",
help="server port")
(options, args) = oparser.parse_args()
# options handling
for i in ("debug", "login", "server", "port"):
if hasattr(options, i):
o = getattr(options, i)
if o != "":
settings[i] = o
# show usage if no default conf and no server given
if len(settings) == 0 and len(args) == 0:
if "login" not in settings or "server" not in settings:
oparser.print_help()
sys.exit(1)
# debug option handling
if options.debug or "debug" in settings:
cccli.debug = True
# args handling
if len(args) == 1:
sargs = args[0].split(":", 1)
if len(sargs) > 1:
settings["port"] = sargs[1]
if not sargs[0] == "":
settings["host"] = sargs[0]
# remove password to prevent it showing
# remove pass to prevent stupid guy
if "pass" in settings:
del settings["pass"]
# debug stuff
if cccli.debug:
printer.err("Debugging on")
printer.err("Settings: %s"%settings)
printer.err("Alias: %s"%alias)
if "debug" in settings:
cccli.debug = bool(settings["debug"])
else:
warnings.filterwarnings("ignore")
printer.debug("Debugging on")
printer.debug("Settings: %s"%settings)
printer.debug("Alias: %s"%alias)
# checking needs
if settings["server"] == "":
......@@ -99,8 +106,8 @@ try:
settings["pass"] = getpass.getpass("Password: ")
# start cli
cli = cli.Cli(settings, alias)
cli.run()
cli = cli.Cli(settings, alias, args)
cli.start()
except KeyboardInterrupt:
exit(1)
except Exception, e:
......
......@@ -9,5 +9,6 @@ version = "1~dev"
debug = False
import printer
import parser
import cli
import clierror
import command
......@@ -10,38 +10,107 @@ import sys
import socket
import ssl
import threading
import cccli
from cccli import printer, command
from cccli.clierror import *
from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure, threadless, ConnectionProxy
import re
import readline
class Cli(object):
_settings = {}
_alias = {}
def __init__(self, settings, alias):
def __init__(self, settings, alias, args):
self._settings = settings
self._alias = alias
self._interactive = sys.stderr.isatty() and sys.stdin.isatty()
self._prompt = "> "
self._commands = args
self._rpc = None
def run(self):
# try to connect
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock = ssl.wrap_socket(sock, certfile=None,
cert_reqs=ssl.CERT_NONE,
ssl_version=ssl.PROTOCOL_TLSv1)
sock.connect((self._settings["server"], self._settings["port"]))
client = SimpleRpcClient(sock)
print "sucks"
prox = ConnectionProxy(client)
print "sucks1"
t = threading.Thread(target=client.run)
t.daemon = True
t.start()
print "sucks2"
prox.authentify(self._settings["login"], self._settings["pass"])
print "sucks3"
# run parsing
#cparser = parser.Parser(main, alias)
#cparser.parse()
def start(self):
'''Start a CLI'''
# Connecting
self._connect()
# authentifications
self._auth()
# run parsing args
if len(self._commands) > 0:
for c in self._commands:
self._parse(c)
elif self._interactive:
self._interactive_parser()
else:
self._parser()
def _connect(self):
printer.debug("Connecting...")
rpcc = SimpleRpcClient.from_addr(self._settings["server"],
self._settings["port"],
enable_ssl=True
)
# FIXME: wait sjrpc v5 with on_disconnect usable
rpcc.start(daemonize=True)
self._rpc = ConnectionProxy(rpcc)
def _auth(self):
printer.debug("Authenticating...")
if self._rpc.authentify(self._settings["login"], self._settings["pass"]):
printer.debug("Authenticated.")
else:
printer.fatal("Autentification failed!")
def _interactive_parser(self):
'''Interactive shell parser'''
# init readline
while True:
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
except SystemExit:
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"])
except IOError:
pass
printer.out("Tcho!")
def _parser(self):
'''Non interactive parser'''
while True:
line = raw_input(self._prompt)
self._parse_line(line)
def _parse_line(self, line):
'''Parse a line (more than one command)'''
for cmd in line.split(";"):
if (cmd.strip() == "" or cmd[0] == "#"):
continue
elif (cmd[0] == "!"):
p = subprocess.Popen(cmd[1:], close_fds=True, shell=True)
p.wait()
ret = p.returncode
elif (cmd[0] == "?"):
command.Command("help").call()
else:
argv = self._lex_argv(cmd)
command.Command(argv, self._rpc).call()
def _lex_argv(self, string):
return string.split(" ")
......@@ -8,3 +8,6 @@ CloudControl CLI Errors
################################################################################
class cliError(Exception):
pass
class BadCommand(cliError):
pass
import re
from sjrpc.client import SimpleRpcClient
from cccli import printer
from cccli.clierror import *
class Command(object):
def __init__(self, argv, rpc):
if len(argv) < 1:
raise Exception("Empty command")
self._argv = argv
self._rpc = rpc
def call(self):
'''Run command'''
if re.match("^[a-zA-Z0-9]+$", self._argv[0]):
name = "cmd_%s"%self._argv[0]
if hasattr(self, name):
cmd = getattr(self, name)
return cmd(self._argv)
raise BadCommand(self._argv[0])
def usage(self, cmdname, printf=None):
'''Return usage of a command'''
fname = "cmd_%s"%cmdname
if hasattr(self, fname):
if hasattr(getattr(self, fname), "usage"):
s = getattr(getattr(self, fname), "usage")
if printf != None:
printf(s)
return s
else:
return "No usage"
else:
raise myError("No such command: %s"%cmdname)
def cmd_exit(self, argv):
'''Quit application with respect'''
raise SystemExit()
def cmd_list(self, argv):
'''List something'''
if len(argv) == 1:
argv.append("hv")
items = self._rpc.list(str.join("", argv[1:]))
for item in items:
for key, val in item.items():
printer.out("%s: %s "%(key, val))
printer.out("*"*80)
def cmd_export(self, argv):
'''List server exported methods'''
for cmds in self._rpc.list_commands():
printer.out("%s"%cmds["name"])
......@@ -31,6 +31,7 @@ class Parser(object):
def _prompt(self):
'''Show a parser prompt'''
return "> "
bang = "#" if Keyring().has_unlocked_key() else "$"
try:
cwd = re.sub(self.rootpath, '~', os.getcwd())
......
......@@ -6,6 +6,8 @@ CloudControl CLI Printers
'''
import sys
import os
import cccli
###############################################################################
color = {
......@@ -37,38 +39,42 @@ color = {
}
###############################################################################
def out(message, fd=sys.stdout, nl="\n"):
def out(message, fd=sys.stdout, nl=os.linesep):
'''Print a message in fd ended by nl'''
fd.write("%s%s"%(message,nl))
fd.write("%s%s"%(message, nl))
fd.flush()
###############################################################################
def err(message, fd=sys.stderr, nl="\n"):
def err(message, fd=sys.stderr, nl=os.linesep):
out(message, fd, nl)
###############################################################################
def fatal(message, exitcode=42, fd=sys.stderr, nl="\n"):
out("%sFatal Error:%s %s.%s"%(color["lred"],
color["red"],
message,
color["reset"])
,fd,nl)
def fatal(message, exitcode=42, fd=sys.stderr, nl=os.linesep):
out("%sFatal%s: %s%s"%(color["lred"],
color["red"],
message,
color["reset"])
, fd, nl)
if exitcode >= 0:
sys.exit(exitcode)
exit(exitcode)
###############################################################################
def error(message, fd=sys.stderr, nl="\n"):
out("%sError:%s %s.%s"%(color["lred"],
color["red"],
message,
color["reset"])
def error(message, fd=sys.stderr, nl=os.linesep):
out("%sError%s: %s.%s"%(color["lred"],
color["red"],
message,
color["reset"])
,fd,nl)
###############################################################################
def warn(message, fd=sys.stderr, nl="\n"):
out("%sWarning:%s %s.%s"%(color["lyellow"],
def warn(message, fd=sys.stderr, nl=os.linesep):
out("%sWarning%s: %s.%s"%(color["lyellow"],
color["yellow"],
message,
color["reset"])
,fd,nl)
###############################################################################
def debug(message, fd=sys.stderr, nl=os.linesep):
if cccli.debug:
out(message, fd, nl)
......@@ -3,13 +3,13 @@ Section: python
Priority: optional
Maintainer: Sebastien Luttringer <sebastien.luttringer@smartjog.com>
Uploaders: Sebastien Luttringer <sebastien.luttringer@smartjog.com>
Build-Depends: debhelper (>= 7), python-central (>= 0.6), cdbs (>= 0.4.50), python-setuptools, python
Build-Depends: debhelper (>= 7), python-central (>= 0.6), cdbs (>= 0.4.50), python-setuptools, python (<< 3.0)
XS-Python-Version: >= 2.6
Standards-Version: 3.8.0
Package: cc-cli
Architecture: all
Depends: ${misc:Depends}, ${python:Depends}
Depends: ${misc:Depends}, ${python:Depends}, python (<< 3), python-sjrpc (>= 4)
XB-Python-Version: ${python:Versions}
Description: CloudControl CLI
This package provides the Command Line Interface to CloudControl.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment