mirror of
https://github.com/clearlinux/WALinuxAgent.git
synced 2026-10-03 23:38:24 +00:00
Merge pull request #153 from Azure/2.1_freebsd
freebsd support for v2.1
This commit is contained in:
@@ -104,6 +104,9 @@ def get_home_dir(conf=__conf__):
|
||||
def get_passwd_file_path(conf=__conf__):
|
||||
return conf.get("OS.PasswordPath", "/etc/shadow")
|
||||
|
||||
def get_sudoers_dir(conf=__conf__):
|
||||
return conf.get("OS.SudoersDir", "/etc/sudoers.d")
|
||||
|
||||
def get_sshd_conf_file_path(conf=__conf__):
|
||||
return conf.get("OS.SshdConfigPath", "/etc/ssh/sshd_config")
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class DaemonHandler(object):
|
||||
if os.path.isfile(pid_file):
|
||||
pid = fileutil.read_file(pid_file)
|
||||
|
||||
if pid is not None and os.path.isdir(os.path.join("/proc", pid)):
|
||||
if self.distro.osutil.check_pid_alive(pid):
|
||||
logger.info("Daemon is already running: {0}", pid)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ class EnvHandler(object):
|
||||
return
|
||||
|
||||
#The dhcp process hasn't changed since last check
|
||||
if os.path.isdir(os.path.join('/proc', self.dhcpid.strip())):
|
||||
if self.distro.osutil.check_pid_alive(self.dhcpid.strip()):
|
||||
return
|
||||
|
||||
newpid = self.distro.osutil.get_dhcp_pid()
|
||||
|
||||
@@ -114,21 +114,36 @@ class DefaultOSUtil(object):
|
||||
raise OSUtilError(("Failed to set password for {0}: {1}"
|
||||
"").format(username, output))
|
||||
|
||||
def conf_sudoer(self, username, nopasswd):
|
||||
# for older distros create sudoers.d
|
||||
if not os.path.isdir('/etc/sudoers.d/'):
|
||||
# create the /etc/sudoers.d/ directory
|
||||
os.mkdir('/etc/sudoers.d/')
|
||||
# add the include of sudoers.d to the /etc/sudoers
|
||||
sudoers = '\n' + '#includedir /etc/sudoers.d/\n'
|
||||
fileutil.append_file('/etc/sudoers', sudoers)
|
||||
sudoer = None
|
||||
if nopasswd:
|
||||
sudoer = "{0} ALL = (ALL) NOPASSWD\n".format(username)
|
||||
def conf_sudoer(self, username, nopasswd=False, remove=False):
|
||||
sudoers_dir = conf.get_sudoers_dir()
|
||||
sudoers_wagent = os.path.join(sudoers_dir, 'waagent')
|
||||
|
||||
if not remove:
|
||||
# for older distros create sudoers.d
|
||||
if not os.path.isdir(sudoers_dir):
|
||||
sudoers_file = os.path.join(sudoers_dir, '../sudoers')
|
||||
# create the sudoers.d directory
|
||||
os.mkdir(sudoers_dir)
|
||||
# add the include of sudoers.d to the /etc/sudoers
|
||||
sudoers = '\n#includedir ' + sudoers_dir + '\n'
|
||||
fileutil.append_file(sudoers_file, sudoers)
|
||||
sudoer = None
|
||||
if nopasswd:
|
||||
sudoer = "{0} ALL=(ALL) NOPASSWD: ALL\n".format(username)
|
||||
else:
|
||||
sudoer = "{0} ALL=(ALL) ALL\n".format(username)
|
||||
fileutil.append_file(sudoers_wagent, sudoer)
|
||||
fileutil.chmod(sudoers_wagent, 0o440)
|
||||
else:
|
||||
sudoer = "{0} ALL = (ALL) ALL\n".format(username)
|
||||
fileutil.append_file('/etc/sudoers.d/waagent', sudoer)
|
||||
fileutil.chmod('/etc/sudoers.d/waagent', 0o440)
|
||||
#Remove user from sudoers
|
||||
if os.path.isfile(sudoers_wagent):
|
||||
try:
|
||||
content = fileutil.read_file(sudoers_wagent)
|
||||
sudoers = content.split("\n")
|
||||
sudoers = [x for x in sudoers if username not in x]
|
||||
fileutil.write_file(sudoers_wagent, "\n".join(sudoers))
|
||||
except IOError as e:
|
||||
raise OSUtilError("Failed to remove sudoer: {0}".format(e))
|
||||
|
||||
def del_root_password(self):
|
||||
try:
|
||||
@@ -267,7 +282,7 @@ class DefaultOSUtil(object):
|
||||
|
||||
|
||||
def get_dvd_device(self, dev_dir='/dev'):
|
||||
patten=r'(sr[0-9]|hd[c-z]|cdrom[0-9])'
|
||||
patten=r'(sr[0-9]|hd[c-z]|cdrom[0-9]|cd[0-9])'
|
||||
for dvd in [re.match(patten, dev) for dev in os.listdir(dev_dir)]:
|
||||
if dvd is not None:
|
||||
return "/dev/{0}".format(dvd.group(0))
|
||||
@@ -285,7 +300,7 @@ class DefaultOSUtil(object):
|
||||
os.makedirs(mount_point)
|
||||
|
||||
for retry in range(0, max_retry):
|
||||
retcode = self.mount(dvd, mount_point, option="-o ro -t iso9660,udf",
|
||||
retcode = self.mount(dvd, mount_point, option="-o ro -t udf,iso9660",
|
||||
chk_err=chk_err)
|
||||
if retcode == 0:
|
||||
logger.info("Successfully mounted dvd")
|
||||
@@ -338,7 +353,7 @@ class DefaultOSUtil(object):
|
||||
return False
|
||||
|
||||
def mount(self, dvd, mount_point, option="", chk_err=True):
|
||||
cmd = "mount {0} {1} {2}".format(dvd, option, mount_point)
|
||||
cmd = "mount {0} {1} {2}".format(option, dvd, mount_point)
|
||||
return shellutil.run_get_output(cmd, chk_err)[0]
|
||||
|
||||
def umount(self, mount_point, chk_err=True):
|
||||
@@ -492,7 +507,7 @@ class DefaultOSUtil(object):
|
||||
|
||||
def set_dhcp_hostname(self, hostname):
|
||||
autosend = r'^[^#]*?send\s*host-name.*?(<hostname>|gethostname[(,)])'
|
||||
dhclient_files = ['/etc/dhcp/dhclient.conf', '/etc/dhcp3/dhclient.conf']
|
||||
dhclient_files = ['/etc/dhcp/dhclient.conf', '/etc/dhcp3/dhclient.conf', '/etc/dhclient.conf']
|
||||
for conf_file in dhclient_files:
|
||||
if not os.path.isfile(conf_file):
|
||||
continue
|
||||
@@ -501,7 +516,7 @@ class DefaultOSUtil(object):
|
||||
return
|
||||
fileutil.update_conf_file(conf_file,
|
||||
'send host-name',
|
||||
'send host-name {0}'.format(hostname))
|
||||
'send host-name "{0}";'.format(hostname))
|
||||
|
||||
def restart_if(self, ifname):
|
||||
shellutil.run("ifdown {0} && ifup {1}".format(ifname, ifname))
|
||||
@@ -579,16 +594,7 @@ class DefaultOSUtil(object):
|
||||
logger.error("{0} is a system user. Will not delete it.", username)
|
||||
shellutil.run("> /var/run/utmp")
|
||||
shellutil.run("userdel -f -r " + username)
|
||||
#Remove user from suders
|
||||
if os.path.isfile("/etc/suders.d/waagent"):
|
||||
try:
|
||||
content = fileutil.read_file("/etc/sudoers.d/waagent")
|
||||
sudoers = content.split("\n")
|
||||
sudoers = [x for x in sudoers if username not in x]
|
||||
fileutil.write_file("/etc/sudoers.d/waagent",
|
||||
"\n".join(sudoers))
|
||||
except IOError as e:
|
||||
raise OSUtilError("Failed to remove sudoer: {0}".format(e))
|
||||
self.conf_sudoer(username, remove=True)
|
||||
|
||||
def decode_customdata(self, data):
|
||||
return base64.b64decode(data)
|
||||
@@ -606,7 +612,7 @@ class DefaultOSUtil(object):
|
||||
if ret[0] == 0:
|
||||
return int(ret[1])
|
||||
else:
|
||||
raise OSUtilError("Failed to get procerssor cores")
|
||||
raise OSUtilError("Failed to get processor cores")
|
||||
|
||||
def set_admin_access_to_ip(self, dest_ip):
|
||||
#This allows root to access dest_ip
|
||||
@@ -621,3 +627,5 @@ class DefaultOSUtil(object):
|
||||
shellutil.run(rm_old.format(dest_ip), chk_err=False)
|
||||
shellutil.run(rule.format(dest_ip))
|
||||
|
||||
def check_pid_alive(self, pid):
|
||||
return pid is not None and os.path.isdir(os.path.join('/proc', pid))
|
||||
|
||||
@@ -122,7 +122,7 @@ class ProvisionHandler(object):
|
||||
crypt_id=crypt_id, salt_len=salt_len)
|
||||
|
||||
logger.info("Configure sudoer")
|
||||
self.distro.osutil.conf_sudoer(ovfenv.username, ovfenv.user_password is None)
|
||||
self.distro.osutil.conf_sudoer(ovfenv.username, nopasswd=ovfenv.user_password is None)
|
||||
|
||||
logger.info("Configure sshd")
|
||||
self.distro.osutil.conf_sshd(ovfenv.disable_ssh_password_auth)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Microsoft Azure Linux Agent
|
||||
#
|
||||
# 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+
|
||||
#
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Microsoft Azure Linux Agent
|
||||
#
|
||||
# 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+
|
||||
#
|
||||
|
||||
from azurelinuxagent.distro.default.distro import DefaultDistro
|
||||
from azurelinuxagent.distro.freebsd.resourceDisk import FreeBSDResourceDiskHandler
|
||||
from azurelinuxagent.distro.freebsd.osutil import FreeBSDOSUtil
|
||||
|
||||
|
||||
class FreeBSDDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(FreeBSDDistro, self).__init__()
|
||||
self.osutil = FreeBSDOSUtil()
|
||||
self.resource_disk_handler = FreeBSDResourceDiskHandler(self)
|
||||
@@ -0,0 +1,181 @@
|
||||
# Microsoft Azure Linux Agent
|
||||
#
|
||||
# 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 azurelinuxagent.utils.shellutil as shellutil
|
||||
import azurelinuxagent.utils.textutil as textutil
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
|
||||
from azurelinuxagent.exception import OSUtilError
|
||||
|
||||
|
||||
class FreeBSDOSUtil(DefaultOSUtil):
|
||||
def __init__(self):
|
||||
super(FreeBSDOSUtil, self).__init__()
|
||||
self._scsi_disks_timeout_set = False
|
||||
|
||||
def restart_ssh_service(self):
|
||||
return shellutil.run('service sshd restart', chk_err=False)
|
||||
|
||||
def useradd(self, username, expiration=None):
|
||||
"""
|
||||
Create user account with 'username'
|
||||
"""
|
||||
userentry = self.get_userentry(username)
|
||||
if userentry is not None:
|
||||
logger.warn("User {0} already exists, skip useradd", username)
|
||||
return
|
||||
|
||||
if expiration is not None:
|
||||
cmd = "pw useradd {0} -e {1} -m".format(username, expiration)
|
||||
else:
|
||||
cmd = "pw useradd {0} -m".format(username)
|
||||
retcode, out = shellutil.run_get_output(cmd)
|
||||
if retcode != 0:
|
||||
raise OSUtilError(("Failed to create user account:{0}, "
|
||||
"retcode:{1}, "
|
||||
"output:{2}").format(username, retcode, out))
|
||||
|
||||
def del_account(self, username):
|
||||
if self.is_sys_user(username):
|
||||
logger.error("{0} is a system user. Will not delete it.", username)
|
||||
shellutil.run('> /var/run/utx.active')
|
||||
shellutil.run('rmuser -y ' + username)
|
||||
self.conf_sudoer(username, remove=True)
|
||||
|
||||
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))
|
||||
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)
|
||||
if ret != 0:
|
||||
raise OSUtilError(("Failed to set password for {0}: {1}"
|
||||
"").format(username, output))
|
||||
|
||||
def del_root_password(self):
|
||||
err = shellutil.run('pw mod user root -w no')
|
||||
if err:
|
||||
raise OSUtilError("Failed to delete root password: Failed to update password database.")
|
||||
|
||||
def get_if_mac(self, ifname):
|
||||
data = self._get_net_info()
|
||||
if data[0] == ifname:
|
||||
return data[2].replace(':', '').upper()
|
||||
return None
|
||||
|
||||
def get_first_if(self):
|
||||
return self._get_net_info()[:2]
|
||||
|
||||
def route_add(self, net, mask, gateway):
|
||||
cmd = 'route add {0} {1} {2}'.format(net, gateway, mask)
|
||||
return shellutil.run(cmd, chk_err=False)
|
||||
|
||||
def is_missing_default_route(self):
|
||||
"""
|
||||
For FreeBSD, the default broadcast goes to current default gw, not a all-ones broadcast address, need to
|
||||
specify the route manually to get it work in a VNET environment.
|
||||
SEE ALSO: man ip(4) IP_ONESBCAST,
|
||||
"""
|
||||
return True
|
||||
|
||||
def set_route_for_dhcp_broadcast(self, ifname):
|
||||
return shellutil.run("route add 255.255.255.255 0.0.0.0 -ifp {0}".format(ifname), chk_err=False)
|
||||
|
||||
def remove_route_for_dhcp_broadcast(self, ifname):
|
||||
shellutil.run("route delete 255.255.255.255", chk_err=False)
|
||||
|
||||
def get_dhcp_pid(self):
|
||||
ret = shellutil.run_get_output("pgrep -n dhclient")
|
||||
return ret[1] if ret[0] == 0 else None
|
||||
|
||||
def eject_dvd(self, chk_err=True):
|
||||
dvd = self.get_dvd_device()
|
||||
retcode = shellutil.run("cdcontrol -f {0} eject".format(dvd))
|
||||
if chk_err and retcode != 0:
|
||||
raise OSUtilError("Failed to eject dvd: ret={0}".format(retcode))
|
||||
|
||||
def restart_if(self, ifname):
|
||||
# Restart dhclient only to publish hostname
|
||||
shellutil.run("/etc/rc.d/dhclient restart {0}".format(ifname), chk_err=False)
|
||||
|
||||
def get_total_mem(self):
|
||||
cmd = "sysctl hw.physmem |awk '{print $2}'"
|
||||
ret, output = shellutil.run_get_output(cmd)
|
||||
if ret:
|
||||
raise OSUtilError("Failed to get total memory: {0}".format(output))
|
||||
try:
|
||||
return int(output)/1024/1024
|
||||
except ValueError:
|
||||
raise OSUtilError("Failed to get total memory: {0}".format(output))
|
||||
|
||||
def get_processor_cores(self):
|
||||
ret, output = shellutil.run_get_output("sysctl hw.ncpu |awk '{print $2}'")
|
||||
if ret:
|
||||
raise OSUtilError("Failed to get processor cores.")
|
||||
|
||||
try:
|
||||
return int(output)
|
||||
except ValueError:
|
||||
raise OSUtilError("Failed to get total memory: {0}".format(output))
|
||||
|
||||
def set_scsi_disks_timeout(self, timeout):
|
||||
if self._scsi_disks_timeout_set:
|
||||
return
|
||||
|
||||
ret, output = shellutil.run_get_output('sysctl kern.cam.da.default_timeout={0}'.format(timeout))
|
||||
if ret:
|
||||
raise OSUtilError("Failed set SCSI disks timeout: {0}".format(output))
|
||||
self._scsi_disks_timeout_set = True
|
||||
|
||||
def check_pid_alive(self, pid):
|
||||
return shellutil.run('ps -p {0}'.format(pid), chk_err=False) == 0
|
||||
|
||||
@staticmethod
|
||||
def _get_net_info():
|
||||
"""
|
||||
There is no SIOCGIFCONF
|
||||
on freeBSD - just parse ifconfig.
|
||||
Returns strings: iface, inet4_addr, and mac
|
||||
or 'None,None,None' if unable to parse.
|
||||
We will sleep and retry as the network must be up.
|
||||
"""
|
||||
iface = ''
|
||||
inet = ''
|
||||
mac = ''
|
||||
|
||||
err, output = shellutil.run_get_output('ifconfig -l ether', chk_err=False)
|
||||
if err:
|
||||
raise OSUtilError("Can't find ether interface:{0}".format(output))
|
||||
ifaces = output.split()
|
||||
if not ifaces:
|
||||
raise OSUtilError("Can't find ether interface.")
|
||||
iface = ifaces[0]
|
||||
|
||||
err, output = shellutil.run_get_output('ifconfig ' + iface, chk_err=False)
|
||||
if err:
|
||||
raise OSUtilError("Can't get info for interface:{0}".format(iface))
|
||||
|
||||
for line in output.split('\n'):
|
||||
if line.find('inet ') != -1:
|
||||
inet = line.split()[1]
|
||||
elif line.find('ether ') != -1:
|
||||
mac = line.split()[1]
|
||||
logger.verb("Interface info: ({0},{1},{2})", iface, inet, mac)
|
||||
|
||||
return iface, inet, mac
|
||||
@@ -0,0 +1,118 @@
|
||||
# Microsoft Azure Linux Agent
|
||||
#
|
||||
# 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 azurelinuxagent.logger as logger
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
from azurelinuxagent.distro.default.resourceDisk import ResourceDiskHandler
|
||||
from azurelinuxagent.exception import ResourceDiskError
|
||||
|
||||
|
||||
class FreeBSDResourceDiskHandler(ResourceDiskHandler):
|
||||
"""
|
||||
This class handles resource disk mounting for FreeBSD.
|
||||
|
||||
The resource disk locates at following slot:
|
||||
scbus2 on blkvsc1 bus 0:
|
||||
<Msft Virtual Disk 1.0> at scbus2 target 1 lun 0 (da1,pass2)
|
||||
|
||||
There are 2 variations based on partition table type:
|
||||
1. MBR: The resource disk partition is /dev/da1s1
|
||||
2. GPT: The resource disk partition is /dev/da1p2, /dev/da1p1 is for reserved usage.
|
||||
"""
|
||||
def __init__(self, distro):
|
||||
super(FreeBSDResourceDiskHandler, self).__init__(distro)
|
||||
|
||||
@staticmethod
|
||||
def parse_gpart_list(data):
|
||||
dic = {}
|
||||
for line in data.split('\n'):
|
||||
if line.find("Geom name: ") != -1:
|
||||
geom_name = line[11:]
|
||||
elif line.find("scheme: ") != -1:
|
||||
dic[geom_name] = line[8:]
|
||||
return dic
|
||||
|
||||
def mount_resource_disk(self, mount_point, fs):
|
||||
if fs != 'ufs':
|
||||
raise ResourceDiskError("Unsupported filesystem type:{0}, only ufs is supported.".format(fs))
|
||||
|
||||
# 1. Detect device
|
||||
err, output = shellutil.run_get_output('gpart list')
|
||||
if err:
|
||||
raise ResourceDiskError("Unable to detect resource disk device:{0}".format(output))
|
||||
disks = self.parse_gpart_list(output)
|
||||
|
||||
err, output = shellutil.run_get_output('camcontrol periphlist 2:1:0')
|
||||
if err:
|
||||
raise ResourceDiskError("Unable to detect resource disk device:{0}".format(output))
|
||||
|
||||
# 'da1: generation: 4 index: 1 status: MORE\npass2: generation: 4 index: 2 status: LAST\n'
|
||||
device = None
|
||||
for line in output.split('\n'):
|
||||
index = line.find(':')
|
||||
if index > 0:
|
||||
geom_name = line[:index]
|
||||
if geom_name in disks:
|
||||
device = geom_name
|
||||
break
|
||||
|
||||
if not device:
|
||||
raise ResourceDiskError("Unable to detect resource disk device.")
|
||||
logger.info('Resource disk device {0} found.', device)
|
||||
|
||||
# 2. Detect partition
|
||||
partition_table_type = disks[device]
|
||||
|
||||
if partition_table_type == 'MBR':
|
||||
provider_name = device + 's1'
|
||||
elif partition_table_type == 'GPT':
|
||||
provider_name = device + 'p2'
|
||||
else:
|
||||
raise ResourceDiskError("Unsupported partition table type:{0}".format(output))
|
||||
|
||||
err, output = shellutil.run_get_output('gpart show -p {0}'.format(device))
|
||||
if err or output.find(provider_name) == -1:
|
||||
raise ResourceDiskError("Resource disk partition not found.")
|
||||
|
||||
partition = '/dev/' + provider_name
|
||||
logger.info('Resource disk partition {0} found.', partition)
|
||||
|
||||
# 3. Mount partition
|
||||
mount_list = shellutil.run_get_output("mount")[1]
|
||||
existing = self.distro.osutil.get_mount_point(mount_list, partition)
|
||||
|
||||
if existing:
|
||||
logger.info("Resource disk {0} is already mounted", partition)
|
||||
return existing
|
||||
|
||||
fileutil.mkdir(mount_point, mode=0o755)
|
||||
mount_cmd = 'mount -t {0} {1} {2}'.format(fs, partition, mount_point)
|
||||
err = shellutil.run(mount_cmd, chk_err=False)
|
||||
if err:
|
||||
logger.info('Creating {0} filesystem on partition {1}'.format(fs, partition))
|
||||
err, output = shellutil.run_get_output('newfs -U {0}'.format(partition))
|
||||
if err:
|
||||
raise ResourceDiskError("Failed to create new filesystem on partition {0}, error:{1}"
|
||||
.format(partition, output))
|
||||
err, output = shellutil.run_get_output(mount_cmd, chk_err=False)
|
||||
if err:
|
||||
raise ResourceDiskError("Failed to mount partition {0}, error".format(partition, output))
|
||||
|
||||
logger.info("Resource disk partition {0} is mounted at {1} with fstype {2}", partition, mount_point, fs)
|
||||
return mount_point
|
||||
@@ -28,6 +28,7 @@ from azurelinuxagent.distro.redhat.distro import RedhatDistro, Redhat6xDistro
|
||||
from azurelinuxagent.distro.coreos.distro import CoreOSDistro
|
||||
from azurelinuxagent.distro.suse.distro import SUSE11Distro, SUSEDistro
|
||||
from azurelinuxagent.distro.debian.distro import DebianDistro
|
||||
from azurelinuxagent.distro.freebsd.distro import FreeBSDDistro
|
||||
|
||||
def get_distro(distro_name=DISTRO_NAME, distro_version=DISTRO_VERSION,
|
||||
distro_full_name=DISTRO_FULL_NAME):
|
||||
@@ -60,6 +61,8 @@ def get_distro(distro_name=DISTRO_NAME, distro_version=DISTRO_VERSION,
|
||||
return Redhat6xDistro()
|
||||
else:
|
||||
return RedhatDistro()
|
||||
elif distro_name == "freebsd":
|
||||
return FreeBSDDistro()
|
||||
else:
|
||||
logger.warn("Unable to load distro implemetation for {0}.", distro_name)
|
||||
logger.warn("Use default distro implemetation instead.")
|
||||
|
||||
@@ -28,7 +28,7 @@ def get_distro():
|
||||
if 'FreeBSD' in platform.system():
|
||||
release = re.sub('\-.*\Z', '', ustr(platform.release()))
|
||||
osinfo = ['freebsd', release, '', 'freebsd']
|
||||
if 'linux_distribution' in dir(platform):
|
||||
elif 'linux_distribution' in dir(platform):
|
||||
osinfo = list(platform.linux_distribution(full_distribution_name=0))
|
||||
full_name = platform.linux_distribution()[0].strip()
|
||||
osinfo.append(full_name)
|
||||
|
||||
@@ -66,40 +66,6 @@ def append_file(filepath, contents, asbin=False, encoding='utf-8'):
|
||||
"""
|
||||
write_file(filepath, contents, asbin=asbin, encoding=encoding, append=True)
|
||||
|
||||
def replace_file(filepath, contents):
|
||||
"""
|
||||
Write 'contents' to 'filepath' by creating a temp file,
|
||||
and replacing original.
|
||||
"""
|
||||
handle, temp = tempfile.mkstemp(dir=os.path.dirname(filepath))
|
||||
#if type(contents) == str:
|
||||
#contents=contents.encode('latin-1')
|
||||
try:
|
||||
os.write(handle, contents)
|
||||
except IOError as err:
|
||||
logger.error('Write to file {0}, Exception is {1}', filepath, err)
|
||||
return 1
|
||||
finally:
|
||||
os.close(handle)
|
||||
|
||||
try:
|
||||
os.rename(temp, filepath)
|
||||
except IOError as err:
|
||||
logger.info('Rename {0} to {1}, Exception is {2}', temp, filepath, err)
|
||||
logger.info('Remove original file and retry')
|
||||
try:
|
||||
os.remove(filepath)
|
||||
except IOError as err:
|
||||
logger.error('Remove {0}, Exception is {1}', temp, filepath, err)
|
||||
|
||||
try:
|
||||
os.rename(temp, filepath)
|
||||
except IOError as err:
|
||||
logger.error('Rename {0} to {1}, Exception is {2}', temp, filepath,
|
||||
err)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def base_name(path):
|
||||
head, tail = os.path.split(path)
|
||||
@@ -156,7 +122,7 @@ def update_conf_file(path, line_start, val, chk_err=False):
|
||||
conf = read_file(path).split('\n')
|
||||
conf = [x for x in conf if not x.startswith(line_start)]
|
||||
conf.append(val)
|
||||
replace_file(path, '\n'.join(conf))
|
||||
write_file(path, '\n'.join(conf))
|
||||
|
||||
def search_file(target_dir_name, target_file_name):
|
||||
for root, dirs, files in os.walk(target_dir_name):
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#
|
||||
# Microsoft Azure Linux Agent Configuration
|
||||
#
|
||||
|
||||
# Specified program is invoked with the argument "Ready" when we report ready status
|
||||
# to the endpoint server.
|
||||
Role.StateConsumer=None
|
||||
|
||||
# Specified program is invoked with XML file argument specifying role
|
||||
# configuration.
|
||||
Role.ConfigurationConsumer=None
|
||||
|
||||
# Specified program is invoked with XML file argument specifying role topology.
|
||||
Role.TopologyConsumer=None
|
||||
|
||||
# Enable instance creation
|
||||
Provisioning.Enabled=y
|
||||
|
||||
# Password authentication for root account will be unavailable.
|
||||
Provisioning.DeleteRootPassword=y
|
||||
|
||||
# Generate fresh host key pair.
|
||||
Provisioning.RegenerateSshHostKeyPair=y
|
||||
|
||||
# Supported values are "rsa", "dsa" and "ecdsa".
|
||||
Provisioning.SshHostKeyPairType=rsa
|
||||
|
||||
# Monitor host name changes and publish changes via DHCP requests.
|
||||
Provisioning.MonitorHostName=y
|
||||
|
||||
# Decode CustomData from Base64.
|
||||
Provisioning.DecodeCustomData=n
|
||||
|
||||
# Execute CustomData after provisioning.
|
||||
Provisioning.ExecuteCustomData=n
|
||||
|
||||
# Algorithm used by crypt when generating password hash.
|
||||
#Provisioning.PasswordCryptId=6
|
||||
|
||||
# Length of random salt used when generating password hash.
|
||||
#Provisioning.PasswordCryptSaltLength=10
|
||||
|
||||
# Format if unformatted. If 'n', resource disk will not be mounted.
|
||||
ResourceDisk.Format=y
|
||||
|
||||
# File system on the resource disk
|
||||
# Typically ext3 or ext4. FreeBSD images should use 'ufs' here.
|
||||
ResourceDisk.Filesystem=ufs
|
||||
|
||||
# Mount point for the resource disk
|
||||
ResourceDisk.MountPoint=/mnt/resource
|
||||
|
||||
# Create and use swapfile on resource disk.
|
||||
ResourceDisk.EnableSwap=n
|
||||
|
||||
# Size of the swapfile.
|
||||
ResourceDisk.SwapSizeMB=0
|
||||
|
||||
# Enable verbose logging (y|n)
|
||||
Logs.Verbose=n
|
||||
|
||||
# Root device timeout in seconds.
|
||||
OS.RootDeviceScsiTimeout=300
|
||||
|
||||
# If "None", the system default version is used.
|
||||
OS.OpensslPath=None
|
||||
|
||||
OS.PasswordPath=/etc/master.passwd
|
||||
|
||||
OS.SudoersDir=/usr/local/etc/sudoers.d
|
||||
|
||||
# If set, agent will use proxy server to access internet
|
||||
#HttpProxy.Host=None
|
||||
#HttpProxy.Port=None
|
||||
|
||||
# Detect Scvmm environment, default is n
|
||||
# DetectScvmmEnv=n
|
||||
|
||||
#
|
||||
# Lib.Dir=/var/lib/waagent
|
||||
|
||||
#
|
||||
# DVD.MountPoint=/mnt/cdrom/secure
|
||||
|
||||
#
|
||||
# Pid.File=/var/run/waagent.pid
|
||||
|
||||
#
|
||||
# Extension.LogDir=/var/log/azure
|
||||
|
||||
#
|
||||
# Home.Dir=/home
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
# PROVIDE: waagent
|
||||
# REQUIRE: sshd netif dhclient
|
||||
# KEYWORD: nojail
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
PATH=$PATH:/usr/local/bin
|
||||
name="waagent"
|
||||
rcvar="waagent_enable"
|
||||
pidfile="/var/run/waagent.pid"
|
||||
command="/usr/local/sbin/${name}"
|
||||
command_interpreter="python"
|
||||
command_args="start"
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
||||
@@ -51,6 +51,10 @@ def set_systemd_files(data_files, dest="/lib/systemd/system",
|
||||
src=["init/waagent.service"]):
|
||||
data_files.append((dest, src))
|
||||
|
||||
def set_rc_files(data_files, dest="/etc/rc.d/", src=["init/freebsd/waagent"]):
|
||||
data_files.append((dest, src))
|
||||
|
||||
|
||||
def get_data_files(name, version, fullname):
|
||||
"""
|
||||
Determine data_files according to distro name, version and init system type
|
||||
@@ -106,6 +110,10 @@ def get_data_files(name, version, fullname):
|
||||
else:
|
||||
#sles 12+ and openSUSE 13.2+ use systemd
|
||||
set_systemd_files(data_files, dest='/usr/lib/systemd/system')
|
||||
elif name == 'freebsd':
|
||||
set_bin_files(data_files, dest="/usr/local/sbin")
|
||||
set_conf_files(data_files, src=["config/freebsd/waagent.conf"])
|
||||
set_rc_files(data_files)
|
||||
else:
|
||||
#Use default setting
|
||||
set_bin_files(data_files)
|
||||
|
||||
Reference in New Issue
Block a user