Blame cloudinit/cs_utils.py

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