CloudSigma: only poll on serial device after dmidecode check.

On systems with a ttyS1 and nothing attached, the read attempts
that the cloud sigma datasource would do would block.

Also, Add timeouts for reading/writting from/to the serial console
This commit is contained in:
Kiril Vladimiroff 2014-05-30 14:50:57 -04:00 committed by Scott Moser
commit 9674d8c008
4 changed files with 40 additions and 1 deletions

View File

@ -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

View File

@ -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')

View File

@ -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']

View File

@ -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()