
* do not run dmidecode on arm. * line length * comment that 60 second time out is expected
106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
# vi: ts=4 expandtab
|
|
#
|
|
# Copyright (C) 2014 CloudSigma
|
|
#
|
|
# Author: Kiril Vladimiroff <kiril.vladimiroff@cloudsigma.com>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License version 3, as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
cepko implements easy-to-use communication with CloudSigma's VMs through
|
|
a virtual serial port without bothering with formatting the messages
|
|
properly nor parsing the output with the specific and sometimes
|
|
confusing shell tools for that purpose.
|
|
|
|
Having the server definition accessible by the VM can ve useful in various
|
|
ways. For example it is possible to easily determine from within the VM,
|
|
which network interfaces are connected to public and which to private network.
|
|
Another use is to pass some data to initial VM setup scripts, like setting the
|
|
hostname to the VM name or passing ssh public keys through server meta.
|
|
|
|
For more information take a look at the Server Context section of CloudSigma
|
|
API Docs: http://cloudsigma-docs.readthedocs.org/en/latest/server_context.html
|
|
"""
|
|
import json
|
|
import platform
|
|
|
|
import serial
|
|
|
|
# these high timeouts are necessary as read may read a lot of data.
|
|
READ_TIMEOUT = 60
|
|
WRITE_TIMEOUT = 10
|
|
|
|
SERIAL_PORT = '/dev/ttyS1'
|
|
if platform.system() == 'Windows':
|
|
SERIAL_PORT = 'COM2'
|
|
|
|
|
|
class Cepko(object):
|
|
"""
|
|
One instance of that object could be use for one or more
|
|
queries to the serial port.
|
|
"""
|
|
request_pattern = "<\n{}\n>"
|
|
|
|
def get(self, key="", request_pattern=None):
|
|
if request_pattern is None:
|
|
request_pattern = self.request_pattern
|
|
return CepkoResult(request_pattern.format(key))
|
|
|
|
def all(self):
|
|
return self.get()
|
|
|
|
def meta(self, key=""):
|
|
request_pattern = self.request_pattern.format("/meta/{}")
|
|
return self.get(key, request_pattern)
|
|
|
|
def global_context(self, key=""):
|
|
request_pattern = self.request_pattern.format("/global_context/{}")
|
|
return self.get(key, request_pattern)
|
|
|
|
|
|
class CepkoResult(object):
|
|
"""
|
|
CepkoResult executes the request to the virtual serial port as soon
|
|
as the instance is initialized and stores the result in both raw and
|
|
marshalled format.
|
|
"""
|
|
def __init__(self, request):
|
|
self.request = request
|
|
self.raw_result = self._execute()
|
|
self.result = self._marshal(self.raw_result)
|
|
|
|
def _execute(self):
|
|
connection = serial.Serial(port=SERIAL_PORT,
|
|
timeout=READ_TIMEOUT,
|
|
writeTimeout=WRITE_TIMEOUT)
|
|
connection.write(self.request)
|
|
return connection.readline().strip('\x04\n')
|
|
|
|
def _marshal(self, raw_result):
|
|
try:
|
|
return json.loads(raw_result)
|
|
except ValueError:
|
|
return raw_result
|
|
|
|
def __len__(self):
|
|
return self.result.__len__()
|
|
|
|
def __getitem__(self, key):
|
|
return self.result.__getitem__(key)
|
|
|
|
def __contains__(self, item):
|
|
return self.result.__contains__(item)
|
|
|
|
def __iter__(self):
|
|
return self.result.__iter__()
|