summaryrefslogtreecommitdiff
path: root/azurelinuxagent/common/osutil
diff options
context:
space:
mode:
authorƁukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com>2017-05-18 19:58:02 +0200
committerusd-importer <ubuntu-server@lists.ubuntu.com>2017-05-31 09:53:12 +0000
commit4fb0b5a09b26135ade285844da5d7dfe582a8d4c (patch)
tree09b1e5867d6e7501118cdd0af0012b51fc216530 /azurelinuxagent/common/osutil
parent473ad6fbfe0b9c3b362b530492928303f2b4c7f3 (diff)
downloadvyos-walinuxagent-4fb0b5a09b26135ade285844da5d7dfe582a8d4c.tar.gz
vyos-walinuxagent-4fb0b5a09b26135ade285844da5d7dfe582a8d4c.zip
Import patches-unapplied version 2.2.12-0ubuntu1 to ubuntu/artful-proposed
Imported using git-ubuntu import. Changelog parent: 473ad6fbfe0b9c3b362b530492928303f2b4c7f3 New changelog entries: * New upstream release (LP: #1690854). - Refreshed debian/patches/disable_import_test.patch.
Diffstat (limited to 'azurelinuxagent/common/osutil')
-rw-r--r--azurelinuxagent/common/osutil/arch.py55
-rw-r--r--azurelinuxagent/common/osutil/default.py99
-rw-r--r--azurelinuxagent/common/osutil/factory.py8
-rw-r--r--azurelinuxagent/common/osutil/freebsd.py4
-rw-r--r--azurelinuxagent/common/osutil/gaia.py151
-rw-r--r--azurelinuxagent/common/osutil/redhat.py2
6 files changed, 290 insertions, 29 deletions
diff --git a/azurelinuxagent/common/osutil/arch.py b/azurelinuxagent/common/osutil/arch.py
new file mode 100644
index 0000000..83d3b47
--- /dev/null
+++ b/azurelinuxagent/common/osutil/arch.py
@@ -0,0 +1,55 @@
+#
+# Copyright 2014 Microsoft Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Requires Python 2.4+ and Openssl 1.0+
+#
+
+import os
+import azurelinuxagent.common.utils.shellutil as shellutil
+from azurelinuxagent.common.osutil.default import DefaultOSUtil
+
+class ArchUtil(DefaultOSUtil):
+ def is_dhcp_enabled(self):
+ return True
+
+ def start_network(self):
+ return shellutil.run("systemctl start systemd-networkd", chk_err=False)
+
+ def restart_if(self, iface):
+ shellutil.run("systemctl restart systemd-networkd")
+
+ def restart_ssh_service(self):
+ # SSH is socket activated on CoreOS. No need to restart it.
+ pass
+
+ def stop_dhcp_service(self):
+ return shellutil.run("systemctl stop systemd-networkd", chk_err=False)
+
+ def start_dhcp_service(self):
+ return shellutil.run("systemctl start systemd-networkd", chk_err=False)
+
+ def start_agent_service(self):
+ return shellutil.run("systemctl start waagent", chk_err=False)
+
+ def stop_agent_service(self):
+ return shellutil.run("systemctl stop waagent", chk_err=False)
+
+ def get_dhcp_pid(self):
+ ret= shellutil.run_get_output("pidof systemd-networkd")
+ return ret[1] if ret[0] == 0 else None
+
+ def conf_sshd(self, disable_password):
+ # Don't whack the system default sshd conf
+ pass \ No newline at end of file
diff --git a/azurelinuxagent/common/osutil/default.py b/azurelinuxagent/common/osutil/default.py
index 59d5985..20dc1f3 100644
--- a/azurelinuxagent/common/osutil/default.py
+++ b/azurelinuxagent/common/osutil/default.py
@@ -30,13 +30,15 @@ import fcntl
import base64
import glob
import datetime
+
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
-from azurelinuxagent.common.exception import OSUtilError
-from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
+
+from azurelinuxagent.common.exception import OSUtilError
+from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.utils.cryptutil import CryptUtil
__RULES_FILES__ = [ "/lib/udev/rules.d/75-persistent-net-generator.rules",
@@ -48,6 +50,12 @@ for all distros. Each concrete distro classes could overwrite default behavior
if needed.
"""
+DMIDECODE_CMD = 'dmidecode --string system-uuid'
+PRODUCT_ID_FILE = '/sys/class/dmi/id/product_uuid'
+UUID_PATTERN = re.compile(
+ '^\s*[A-F0-9]{8}(?:\-[A-F0-9]{4}){3}\-[A-F0-9]{12}\s*$',
+ re.IGNORECASE)
+
class DefaultOSUtil(object):
def __init__(self):
@@ -58,6 +66,22 @@ class DefaultOSUtil(object):
def get_agent_conf_file_path(self):
return self.agent_conf_file_path
+ def get_instance_id(self):
+ '''
+ Azure records a UUID as the instance ID
+ First check /sys/class/dmi/id/product_uuid.
+ If that is missing, then extracts from dmidecode
+ If nothing works (for old VMs), return the empty string
+ '''
+ if os.path.isfile(PRODUCT_ID_FILE):
+ return fileutil.read_file(PRODUCT_ID_FILE).strip()
+
+ rc, s = shellutil.run_get_output(DMIDECODE_CMD)
+ if rc != 0 or UUID_PATTERN.match(s) is None:
+ return ""
+
+ return s.strip()
+
def get_userentry(self, username):
try:
return pwd.getpwnam(username)
@@ -110,8 +134,8 @@ class DefaultOSUtil(object):
def chpasswd(self, username, password, crypt_id=6, salt_len=10):
if self.is_sys_user(username):
- raise OSUtilError(("User {0} is a system user. "
- "Will not set passwd.").format(username))
+ raise OSUtilError(("User {0} is a system user, "
+ "will not set password.").format(username))
passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len)
cmd = "usermod -p '{0}' {1}".format(passwd_hash, username)
ret, output = shellutil.run_get_output(cmd, log_cmd=False)
@@ -273,46 +297,65 @@ class DefaultOSUtil(object):
.format("Disabled" if disable_password else "Enabled"))
logger.info("Configured SSH client probing to keep connections alive.")
-
def get_dvd_device(self, dev_dir='/dev'):
- pattern=r'(sr[0-9]|hd[c-z]|cdrom[0-9]|cd[0-9])'
- for dvd in [re.match(pattern, dev) for dev in os.listdir(dev_dir)]:
+ pattern = r'(sr[0-9]|hd[c-z]|cdrom[0-9]|cd[0-9])'
+ device_list = os.listdir(dev_dir)
+ for dvd in [re.match(pattern, dev) for dev in device_list]:
if dvd is not None:
return "/dev/{0}".format(dvd.group(0))
- raise OSUtilError("Failed to get dvd device")
-
- def mount_dvd(self, max_retry=6, chk_err=True, dvd_device=None, mount_point=None):
+ inner_detail = "The following devices were found, but none matched " \
+ "the pattern [{0}]: {1}\n".format(pattern, device_list)
+ raise OSUtilError(msg="Failed to get dvd device from {0}".format(dev_dir),
+ inner=inner_detail)
+
+ def mount_dvd(self,
+ max_retry=6,
+ chk_err=True,
+ dvd_device=None,
+ mount_point=None,
+ sleep_time=5):
if dvd_device is None:
dvd_device = self.get_dvd_device()
if mount_point is None:
mount_point = conf.get_dvd_mount_point()
- mountlist = shellutil.run_get_output("mount")[1]
- existing = self.get_mount_point(mountlist, dvd_device)
- if existing is not None: #Already mounted
+ mount_list = shellutil.run_get_output("mount")[1]
+ existing = self.get_mount_point(mount_list, dvd_device)
+
+ if existing is not None:
+ # already mounted
logger.info("{0} is already mounted at {1}", dvd_device, existing)
return
+
if not os.path.isdir(mount_point):
os.makedirs(mount_point)
- for retry in range(0, max_retry):
- retcode = self.mount(dvd_device, mount_point, option="-o ro -t udf,iso9660",
- chk_err=chk_err)
- if retcode == 0:
+ err = ''
+ for retry in range(1, max_retry):
+ return_code, err = self.mount(dvd_device,
+ mount_point,
+ option="-o ro -t udf,iso9660",
+ chk_err=chk_err)
+ if return_code == 0:
logger.info("Successfully mounted dvd")
return
- if retry < max_retry - 1:
- logger.warn("Mount dvd failed: retry={0}, ret={1}", retry,
- retcode)
- time.sleep(5)
+ else:
+ logger.warn(
+ "Mounting dvd failed [retry {0}/{1}, sleeping {2} sec]",
+ retry,
+ max_retry - 1,
+ sleep_time)
+ if retry < max_retry:
+ time.sleep(sleep_time)
if chk_err:
- raise OSUtilError("Failed to mount dvd.")
+ raise OSUtilError("Failed to mount dvd device", inner=err)
def umount_dvd(self, chk_err=True, mount_point=None):
if mount_point is None:
mount_point = conf.get_dvd_mount_point()
- retcode = self.umount(mount_point, chk_err=chk_err)
- if chk_err and retcode != 0:
- raise OSUtilError("Failed to umount dvd.")
+ return_code = self.umount(mount_point, chk_err=chk_err)
+ if chk_err and return_code != 0:
+ raise OSUtilError("Failed to unmount dvd device at {0}",
+ mount_point)
def eject_dvd(self, chk_err=True):
dvd = self.get_dvd_device()
@@ -356,7 +399,11 @@ class DefaultOSUtil(object):
def mount(self, dvd, mount_point, option="", chk_err=True):
cmd = "mount {0} {1} {2}".format(option, dvd, mount_point)
- return shellutil.run_get_output(cmd, chk_err)[0]
+ retcode, err = shellutil.run_get_output(cmd, chk_err)
+ if retcode != 0:
+ detail = "[{0}] returned {1}: {2}".format(cmd, retcode, err)
+ err = detail
+ return retcode, err
def umount(self, mount_point, chk_err=True):
return shellutil.run("umount {0}".format(mount_point), chk_err=chk_err)
diff --git a/azurelinuxagent/common/osutil/factory.py b/azurelinuxagent/common/osutil/factory.py
index eee9f97..3447651 100644
--- a/azurelinuxagent/common/osutil/factory.py
+++ b/azurelinuxagent/common/osutil/factory.py
@@ -19,6 +19,7 @@ import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.utils.textutil import Version
from azurelinuxagent.common.version import *
from .default import DefaultOSUtil
+from .arch import ArchUtil
from .clearlinux import ClearLinuxUtil
from .coreos import CoreOSUtil
from .debian import DebianOSUtil
@@ -28,6 +29,7 @@ from .suse import SUSEOSUtil, SUSE11OSUtil
from .ubuntu import UbuntuOSUtil, Ubuntu12OSUtil, Ubuntu14OSUtil, UbuntuSnappyOSUtil
from .alpine import AlpineOSUtil
from .bigip import BigIpOSUtil
+from .gaia import GaiaOSUtil
def get_osutil(distro_name=DISTRO_NAME,
@@ -35,6 +37,9 @@ def get_osutil(distro_name=DISTRO_NAME,
distro_version=DISTRO_VERSION,
distro_full_name=DISTRO_FULL_NAME):
+ if distro_name == "arch":
+ return ArchUtil()
+
if distro_name == "clear linux software for intel architecture":
return ClearLinuxUtil()
@@ -85,6 +90,9 @@ def get_osutil(distro_name=DISTRO_NAME,
elif distro_name == "bigip":
return BigIpOSUtil()
+ elif distro_name == "gaia":
+ return GaiaOSUtil()
+
else:
logger.warn("Unable to load distro implementation for {0}. Using "
"default distro implementation instead.",
diff --git a/azurelinuxagent/common/osutil/freebsd.py b/azurelinuxagent/common/osutil/freebsd.py
index d0c40b9..0f465a9 100644
--- a/azurelinuxagent/common/osutil/freebsd.py
+++ b/azurelinuxagent/common/osutil/freebsd.py
@@ -67,8 +67,8 @@ class FreeBSDOSUtil(DefaultOSUtil):
def chpasswd(self, username, password, crypt_id=6, salt_len=10):
if self.is_sys_user(username):
- raise OSUtilError(("User {0} is a system user. "
- "Will not set passwd.").format(username))
+ raise OSUtilError(("User {0} is a system user, "
+ "will not set password.").format(username))
passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len)
cmd = "echo '{0}'|pw usermod {1} -H 0 ".format(passwd_hash, username)
ret, output = shellutil.run_get_output(cmd, log_cmd=False)
diff --git a/azurelinuxagent/common/osutil/gaia.py b/azurelinuxagent/common/osutil/gaia.py
new file mode 100644
index 0000000..a1069d3
--- /dev/null
+++ b/azurelinuxagent/common/osutil/gaia.py
@@ -0,0 +1,151 @@
+#
+# Copyright 2017 Check Point Software Technologies
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Requires Python 2.4+ and Openssl 1.0+
+#
+
+import socket
+import struct
+import time
+
+import azurelinuxagent.common.logger as logger
+from azurelinuxagent.common.exception import OSUtilError
+import azurelinuxagent.common.utils.shellutil as shellutil
+import azurelinuxagent.common.utils.textutil as textutil
+from azurelinuxagent.common.osutil.default import DefaultOSUtil
+
+
+class GaiaOSUtil(DefaultOSUtil):
+ def __init__(self):
+ super(GaiaOSUtil, self).__init__()
+
+ def _run_clish(self, cmd, log_cmd=True):
+ for i in xrange(10):
+ ret, out = shellutil.run_get_output(
+ "/bin/clish -s -c '" + cmd + "'", log_cmd=log_cmd)
+ if not ret:
+ break
+ if 'NMSHST0025' in out: # Entry for [hostname] already present
+ ret = 0
+ break
+ time.sleep(2)
+ return ret, out
+
+ def useradd(self, username, expiration=None):
+ logger.warn('useradd is not supported on GAiA')
+
+ def chpasswd(self, username, password, crypt_id=6, salt_len=10):
+ logger.info('chpasswd')
+ passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len)
+ ret, out = self._run_clish(
+ 'set user admin password-hash ' + passwd_hash, log_cmd=False)
+ if ret != 0:
+ raise OSUtilError(("Failed to set password for {0}: {1}"
+ "").format('admin', out))
+
+ def conf_sudoer(self, username, nopasswd=False, remove=False):
+ logger.info('conf_sudoer is not supported on GAiA')
+
+ def del_root_password(self):
+ logger.info('del_root_password')
+ ret, out = self._run_clish('set user admin password-hash *LOCK*')
+ if ret != 0:
+ raise OSUtilError("Failed to delete root password")
+
+ def _replace_user(path, username):
+ parts = path.split('/')
+ for i in xrange(len(parts)):
+ if parts[i] == '$HOME':
+ parts[i + 1] = username
+ break
+ return '/'.join(parts)
+
+ def deploy_ssh_keypair(self, username, keypair):
+ logger.info('deploy_ssh_keypair')
+ username = 'admin'
+ path, thumbprint = keypair
+ path = self._replace_user(path, username)
+ super(GaiaOSUtil, self).deploy_ssh_keypair(
+ username, (path, thumbprint))
+
+ def deploy_ssh_pubkey(self, username, pubkey):
+ logger.info('deploy_ssh_pubkey')
+ username = 'admin'
+ path, thumbprint, value = pubkey
+ path = self._replace_user(path, username)
+ super(GaiaOSUtil, self).deploy_ssh_pubkey(
+ 'admin', (path, thumbprint, value))
+
+ def eject_dvd(self, chk_err=True):
+ logger.warn('eject is not supported on GAiA')
+
+ def mount(self, dvd, mount_point, option="", chk_err=True):
+ logger.info('mount {0} {1} {2}', dvd, mount_point, option)
+ if 'udf,iso9660' in option:
+ ret, out = super(GaiaOSUtil, self).mount(
+ dvd, mount_point, option=option.replace('udf,iso9660', 'udf'),
+ chk_err=chk_err)
+ if not ret:
+ return ret, out
+ return super(GaiaOSUtil, self).mount(
+ dvd, mount_point, option=option, chk_err=chk_err)
+
+ def allow_dhcp_broadcast(self):
+ logger.info('allow_dhcp_broadcast is ignored on GAiA')
+
+ def remove_rules_files(self, rules_files=''):
+ pass
+
+ def restore_rules_files(self, rules_files=''):
+ logger.info('restore_rules_files is ignored on GAiA')
+
+ def restart_ssh_service(self):
+ return shellutil.run('/sbin/service sshd condrestart', chk_err=False)
+
+ def _address_to_string(addr):
+ return socket.inet_ntoa(struct.pack("!I", addr))
+
+ def _get_prefix(self, mask):
+ return str(sum([bin(int(x)).count('1') for x in mask.split('.')]))
+
+ def route_add(self, net, mask, gateway):
+ logger.info('route_add {0} {1} {2}', net, mask, gateway)
+
+ if net == 0 and mask == 0:
+ cidr = 'default'
+ else:
+ cidr = self._address_to_string(net) + '/' + self._get_prefix(
+ self._address_to_string(mask))
+
+ ret, out = self._run_clish(
+ 'set static-route ' + cidr +
+ ' nexthop gateway address ' +
+ self._address_to_string(gateway) + ' on')
+ return ret
+
+ def set_hostname(self, hostname):
+ logger.warn('set_hostname is ignored on GAiA')
+
+ def set_dhcp_hostname(self, hostname):
+ logger.warn('set_dhcp_hostname is ignored on GAiA')
+
+ def publish_hostname(self, hostname):
+ logger.warn('publish_hostname is ignored on GAiA')
+
+ def del_account(self, username):
+ logger.warn('del_account is ignored on GAiA')
+
+ def set_admin_access_to_ip(self, dest_ip):
+ logger.warn('set_admin_access_to_ip is ignored on GAiA')
diff --git a/azurelinuxagent/common/osutil/redhat.py b/azurelinuxagent/common/osutil/redhat.py
index 5254ea5..b94610c 100644
--- a/azurelinuxagent/common/osutil/redhat.py
+++ b/azurelinuxagent/common/osutil/redhat.py
@@ -103,7 +103,7 @@ class RedhatOSUtil(Redhat6xOSUtil):
Due to a bug in systemd in Centos-7.0, if this call fails, fallback
to hostname.
"""
- hostnamectl_cmd = "hostnamectl set-hostname {0}".format(hostname)
+ hostnamectl_cmd = "hostnamectl set-hostname {0} --static".format(hostname)
if shellutil.run(hostnamectl_cmd, chk_err=False) != 0:
logger.warn("[{0}] failed, attempting fallback".format(hostnamectl_cmd))
DefaultOSUtil.set_hostname(self, hostname)