|
Packit |
bc9a3a |
# Copyright (C) 2014 CloudSigma
|
|
Packit |
bc9a3a |
#
|
|
Packit |
bc9a3a |
# Author: Kiril Vladimiroff <kiril.vladimiroff@cloudsigma.com>
|
|
Packit |
bc9a3a |
#
|
|
Packit |
bc9a3a |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
cepko implements easy-to-use communication with CloudSigma's VMs through
|
|
Packit |
bc9a3a |
a virtual serial port without bothering with formatting the messages
|
|
Packit |
bc9a3a |
properly nor parsing the output with the specific and sometimes
|
|
Packit |
bc9a3a |
confusing shell tools for that purpose.
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
Having the server definition accessible by the VM can ve useful in various
|
|
Packit |
bc9a3a |
ways. For example it is possible to easily determine from within the VM,
|
|
Packit |
bc9a3a |
which network interfaces are connected to public and which to private network.
|
|
Packit |
bc9a3a |
Another use is to pass some data to initial VM setup scripts, like setting the
|
|
Packit |
bc9a3a |
hostname to the VM name or passing ssh public keys through server meta.
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
For more information take a look at the Server Context section of CloudSigma
|
|
Packit |
bc9a3a |
API Docs: http://cloudsigma-docs.readthedocs.org/en/latest/server_context.html
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
import json
|
|
Packit |
bc9a3a |
import platform
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
from cloudinit import serial
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
# these high timeouts are necessary as read may read a lot of data.
|
|
Packit |
bc9a3a |
READ_TIMEOUT = 60
|
|
Packit |
bc9a3a |
WRITE_TIMEOUT = 10
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
SERIAL_PORT = '/dev/ttyS1'
|
|
Packit |
bc9a3a |
if platform.system() == 'Windows':
|
|
Packit |
bc9a3a |
SERIAL_PORT = 'COM2'
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
class Cepko(object):
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
One instance of that object could be use for one or more
|
|
Packit |
bc9a3a |
queries to the serial port.
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
request_pattern = "<\n{}\n>"
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def get(self, key="", request_pattern=None):
|
|
Packit |
bc9a3a |
if request_pattern is None:
|
|
Packit |
bc9a3a |
request_pattern = self.request_pattern
|
|
Packit |
bc9a3a |
return CepkoResult(request_pattern.format(key))
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def all(self):
|
|
Packit |
bc9a3a |
return self.get()
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def meta(self, key=""):
|
|
Packit |
bc9a3a |
request_pattern = self.request_pattern.format("/meta/{}")
|
|
Packit |
bc9a3a |
return self.get(key, request_pattern)
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def global_context(self, key=""):
|
|
Packit |
bc9a3a |
request_pattern = self.request_pattern.format("/global_context/{}")
|
|
Packit |
bc9a3a |
return self.get(key, request_pattern)
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
class CepkoResult(object):
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
CepkoResult executes the request to the virtual serial port as soon
|
|
Packit |
bc9a3a |
as the instance is initialized and stores the result in both raw and
|
|
Packit |
bc9a3a |
marshalled format.
|
|
Packit |
bc9a3a |
"""
|
|
Packit |
bc9a3a |
def __init__(self, request):
|
|
Packit |
bc9a3a |
self.request = request
|
|
Packit |
bc9a3a |
self.raw_result = self._execute()
|
|
Packit |
bc9a3a |
self.result = self._marshal(self.raw_result)
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def _execute(self):
|
|
Packit |
bc9a3a |
connection = serial.Serial(port=SERIAL_PORT,
|
|
Packit |
bc9a3a |
timeout=READ_TIMEOUT,
|
|
Packit |
bc9a3a |
writeTimeout=WRITE_TIMEOUT)
|
|
Packit |
bc9a3a |
connection.write(self.request.encode('ascii'))
|
|
Packit |
bc9a3a |
return connection.readline().strip(b'\x04\n').decode('ascii')
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def _marshal(self, raw_result):
|
|
Packit |
bc9a3a |
try:
|
|
Packit |
bc9a3a |
return json.loads(raw_result)
|
|
Packit |
bc9a3a |
except ValueError:
|
|
Packit |
bc9a3a |
return raw_result
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def __len__(self):
|
|
Packit |
bc9a3a |
return self.result.__len__()
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def __getitem__(self, key):
|
|
Packit |
bc9a3a |
return self.result.__getitem__(key)
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def __contains__(self, item):
|
|
Packit |
bc9a3a |
return self.result.__contains__(item)
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
def __iter__(self):
|
|
Packit |
bc9a3a |
return self.result.__iter__()
|
|
Packit |
bc9a3a |
|
|
Packit |
bc9a3a |
# vi: ts=4 expandtab
|