diff options
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | cloudinit/cs_utils.py | 8 | ||||
-rw-r--r-- | cloudinit/sources/DataSourceCloudSigma.py | 30 | ||||
-rw-r--r-- | tests/unittests/test_datasource/test_cloudsigma.py | 1 |
4 files changed, 40 insertions, 1 deletions
@@ -1,6 +1,8 @@ 0.7.6: - open 0.7.6 - Enable vendordata on CloudSigma datasource (LP: #1303986) + - Poll on /dev/ttyS1 in CloudSigma datasource only if dmidecode says + we're running on cloudsigma (LP: #1316475) [Kiril Vladimiroff] 0.7.5: - open 0.7.5 - Add a debug log message around import failures diff --git a/cloudinit/cs_utils.py b/cloudinit/cs_utils.py index 4e53c31a..dcf56431 100644 --- a/cloudinit/cs_utils.py +++ b/cloudinit/cs_utils.py @@ -35,6 +35,10 @@ 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' @@ -76,7 +80,9 @@ class CepkoResult(object): self.result = self._marshal(self.raw_result) def _execute(self): - connection = serial.Serial(SERIAL_PORT) + connection = serial.Serial(port=SERIAL_PORT, + timeout=READ_TIMEOUT, + writeTimeout=WRITE_TIMEOUT) connection.write(self.request) return connection.readline().strip('\x04\n') diff --git a/cloudinit/sources/DataSourceCloudSigma.py b/cloudinit/sources/DataSourceCloudSigma.py index ad2a044a..707cd0ce 100644 --- a/cloudinit/sources/DataSourceCloudSigma.py +++ b/cloudinit/sources/DataSourceCloudSigma.py @@ -16,10 +16,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from base64 import b64decode +import os import re from cloudinit import log as logging from cloudinit import sources +from cloudinit import util from cloudinit.cs_utils import Cepko LOG = logging.getLogger(__name__) @@ -40,12 +42,40 @@ class DataSourceCloudSigma(sources.DataSource): self.ssh_public_key = '' sources.DataSource.__init__(self, sys_cfg, distro, paths) + def is_running_in_cloudsigma(self): + """ + Uses dmidecode to detect if this instance of cloud-init is running + in the CloudSigma's infrastructure. + """ + uname_arch = os.uname()[4] + if uname_arch.startswith("arm") or uname_arch == "aarch64": + # Disabling because dmidecode in CMD_DMI_SYSTEM crashes kvm process + LOG.debug("Disabling CloudSigma datasource on arm (LP: #1243287)") + return False + + dmidecode_path = util.which('dmidecode') + if not dmidecode_path: + return False + + LOG.debug("Determining hypervisor product name via dmidecode") + try: + cmd = [dmidecode_path, "--string", "system-product-name"] + system_product_name, _ = util.subp(cmd) + return 'cloudsigma' in system_product_name.lower() + except: + LOG.warn("Failed to get hypervisor product name via dmidecode") + + return False + def get_data(self): """ Metadata is the whole server context and /meta/cloud-config is used as userdata. """ dsmode = None + if not self.is_running_in_cloudsigma(): + return False + try: server_context = self.cepko.all().result server_meta = server_context['meta'] diff --git a/tests/unittests/test_datasource/test_cloudsigma.py b/tests/unittests/test_datasource/test_cloudsigma.py index a1342a86..f92e07b7 100644 --- a/tests/unittests/test_datasource/test_cloudsigma.py +++ b/tests/unittests/test_datasource/test_cloudsigma.py @@ -39,6 +39,7 @@ class CepkoMock(Cepko): class DataSourceCloudSigmaTest(TestCase): def setUp(self): self.datasource = DataSourceCloudSigma.DataSourceCloudSigma("", "", "") + self.datasource.is_running_in_cloudsigma = lambda: True self.datasource.cepko = CepkoMock(SERVER_CONTEXT) self.datasource.get_data() |