зеркало из https://github.com/Azure/WALinuxAgent.git
Update setup
This commit is contained in:
Родитель
1fe109dc54
Коммит
bfe3d2e712
|
@ -23,5 +23,8 @@
|
|||
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
|
||||
#
|
||||
|
||||
import walinuxagent.agent as agent
|
||||
|
||||
if __name__ == '__main__':
|
||||
agent.Main()
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#walinuxagent - start Windows Azure agent
|
||||
|
||||
description "walinuxagent"
|
||||
author "Ben Howard <ben.howard@canonical.com>"
|
||||
|
||||
start on (filesystem and started rsyslog)
|
||||
|
||||
pre-start script
|
||||
|
||||
WALINUXAGENT_ENABLED=1
|
||||
[ -r /etc/default/walinuxagent ] && . /etc/default/walinuxagent
|
||||
|
||||
if [ "$WALINUXAGENT_ENABLED" != "1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x /usr/sbin/waagent ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#Load the udf module
|
||||
modprobe -b udf
|
||||
end script
|
||||
|
||||
exec /usr/sbin/waagent -daemon
|
38
setup.py
38
setup.py
|
@ -18,13 +18,33 @@
|
|||
#
|
||||
|
||||
from distutils.core import setup
|
||||
from walinuxagent.utils.osutil import CurrOSInfo
|
||||
import walinuxagent.agent as agent
|
||||
|
||||
setup(name='waagent',
|
||||
version='2.1',
|
||||
description='',
|
||||
author='',
|
||||
url='',
|
||||
packages=['walinuxagent'],
|
||||
data_files=[('bin', ['bin/waagent']),
|
||||
('config', ['config/waagent.conf', 'config/waagent.logrotate'])]
|
||||
)
|
||||
name = CurrOSInfo[0]
|
||||
version = CurrOSInfo[1]
|
||||
codeName = CurrOSInfo[2]
|
||||
|
||||
data_files=[]
|
||||
if name == 'ubuntu':
|
||||
data_files.extend([
|
||||
('/usr/sbin', ['bin/waagent']),
|
||||
('/etc', ['config/waagent.conf']),
|
||||
('/etc/logrotate.d', ['config/waagent.logrotate']),
|
||||
('/etc/init', ['config/ubuntu/waagent.conf']),
|
||||
])
|
||||
else:
|
||||
print "Don't kown how to install on {0} {1} {2}".format(name,
|
||||
version,
|
||||
codeName)
|
||||
sys.exit(-1)
|
||||
|
||||
setup(name=agent.GuestAgentName,
|
||||
version=agent.GuestAgentVersion,
|
||||
description=agent.GuestAgentLongVersion,
|
||||
author=agent.GuestAgentAuthor,
|
||||
url=agent.GuestAgentUri,
|
||||
packages=['walinuxagent',
|
||||
'walinuxagent.utils',
|
||||
'walinuxagent.protocol'],
|
||||
data_files=data_files)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# 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+
|
||||
#
|
||||
# Implements parts of RFC 2131, 1541, 1497 and
|
||||
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
|
||||
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
|
||||
|
||||
import env
|
||||
import test.tools as tools
|
||||
import uuid
|
||||
import unittest
|
||||
import os
|
||||
import json
|
||||
import walinuxagent.utils.fileutil as fileutil
|
||||
import walinuxagent.agent as agent
|
||||
|
||||
class TestAgent(unittest.TestCase):
|
||||
def test_parse_args(self):
|
||||
cmd, force, verbose = agent.ParseArgs(["deprovision+user",
|
||||
"-force",
|
||||
"/verbose"])
|
||||
self.assertEquals("deprovision+user", cmd)
|
||||
self.assertTrue(force)
|
||||
self.assertTrue(verbose)
|
||||
|
||||
cmd, force, verbose = agent.ParseArgs(["wrong cmd"])
|
||||
self.assertEquals("help", cmd)
|
||||
self.assertFalse(force)
|
||||
self.assertFalse(verbose)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,687 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import imp
|
||||
import json
|
||||
import time
|
||||
import pwd
|
||||
|
||||
# waagent has no '.py' therefore create waagent module import manually.
|
||||
waagent=imp.load_source('waagent','waagent')
|
||||
|
||||
from waagent import RunGetOutput, Run, LoggerInit
|
||||
|
||||
"""
|
||||
Test waagent in azure using azure-cli
|
||||
Usage:
|
||||
|
||||
./azure_test.py --stable_vm_image b4590d9e3ed742e4a1d46e5424aa335e__openSUSE-12.3-v120 --source_disk "http://mystorage.blob.core.windows.net/vhds/my-suse2.vhd" --acct "<storage acct key>" --testname my-osuse --mount_point /mnt/disk --agent_path ../waagent --stable_vm_acct_name MyUserName --stable_vm_acct_pass 'myp455wd' --test_vm_acct_name MyUserName --test_vm_acct_pass 'myp455wd' --azure_location "East US" --part_num 1 --retries 20 --fstype scsi --test_vm_acct_cert /root/.ssh/myCert.pem --stable_vm_acct_cert /root/.ssh/myCert.pem --keep_test_vm_vhd no --teardown_test_vm always --prompt no
|
||||
|
||||
azure_test --vm <stable vm name> --testname <testname> [--acct <storage account>]
|
||||
[--disk <vhd url to use as initial disk image>]
|
||||
If --disk is specified, use this vhd as starting point,
|
||||
otherwise use a copy of the stable vm as the starting vhd.
|
||||
|
||||
Starting VHD is attached to stable vm and the sources are copied to it.
|
||||
Spin up a new VM using the VHD.
|
||||
Loop waiting for provisioned.
|
||||
If not provisioned:
|
||||
Destroy vm and attach the disk to the stable vm.
|
||||
Copy the logs to the localhost.
|
||||
Destroy all created objects except the starting vhd.
|
||||
Exit(1)
|
||||
If Provosioned:
|
||||
Copy the logs to the local host.
|
||||
Exit(0)
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
sudo ./azure_test.py --vm my-stable-vm-name --disk "http://mystorageaccount.blob.core.windows.net/myvhds/my-new-os.vhd" --acct mylong-unquoted-starage-account-id --testname my-vm-test --mount_point /my-stablevm-mountpoint --agent_path ../waagent --vm_acct_name root --testvm_acct_name azureuser --testvm_acct_pass 'azureuserpassword' --location "East US" --part_num 2 --retry 20 --fstype bsd --testvm_acct_cert /home/azureuser/.ssh/myCert.pem --keep_vhd "once" --teardown "always" --prompt "no"
|
||||
"""
|
||||
|
||||
def makeDiskImage(di_name,vhd_url,location,copy=False):
|
||||
"""
|
||||
Create new data disk image of the VHD. If 'copy'
|
||||
is set to True, then create a new VHD in the form of myvhd-di.vhd
|
||||
based on the VHD source name. If 'copy is set to False, re-use the
|
||||
vhd. Returns return code and diskimageVHD path. Code is 0 on
|
||||
success or the azure-cli error code upon error.
|
||||
"""
|
||||
if copy :
|
||||
target = os.path.dirname(vhd_url)
|
||||
target = target+ '/' + di_name + '.vhd'
|
||||
else :
|
||||
target = vhd_url
|
||||
cmd='azure vm disk create --json ' + di_name + ' --blob-url ' + target + ' ' + vhd_url
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log(output)
|
||||
waagent.Log(str(code))
|
||||
return target,code
|
||||
|
||||
def makeVMImage(vmi_name,vhd_url,copy=False):
|
||||
"""
|
||||
Create new VM Image based on Disk Image.
|
||||
Returns 0 on success or error code upon error.
|
||||
"""
|
||||
if copy :
|
||||
target = os.path.dirname(vhd_url)
|
||||
target = target+ '/' + vmi_name + '.vhd'
|
||||
else :
|
||||
target = vhd_url
|
||||
cmd='azure vm image create --json ' + vmi_name + ' --base-vhd ' + target + ' --os Linux --blob-url ' + vhd_url
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log(str(code))
|
||||
waagent.Log(output)
|
||||
return code
|
||||
|
||||
def makeVM(vm_name,vmi_name,vhd_url,test_name,location,vmuser_name,vmuser_pass,vmuser_cert,copy=False):
|
||||
"""
|
||||
Create new VM from the VM Image.
|
||||
Returns 0 on success or error code upon error.
|
||||
"""
|
||||
target=os.path.dirname(vhd_url)
|
||||
target = target + '/' + test_name + '.vhd'
|
||||
cmd='azure vm create --json '
|
||||
if copy :
|
||||
cmd += ' --blob-url "' + target + '"'
|
||||
else :
|
||||
target=vhd_url
|
||||
cmd += ' --location "' + location + '"'
|
||||
if os.path.exists(vmuser_cert):
|
||||
cmd += ' -t "' + vmuser_cert + '"'
|
||||
cmd += ' -e 22 ' + vm_name + ' ' + vmi_name + ' ' + vmuser_name + ' \'' +vmuser_pass + '\''
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log(str(code))
|
||||
waagent.Log(output)
|
||||
retry=3
|
||||
while code !=0 and retry > 0 :
|
||||
time.sleep(5)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
retry -=1
|
||||
return target
|
||||
|
||||
def flushDiskImage(di_name,dele=True):
|
||||
"""
|
||||
Delete the VM Image.
|
||||
On error we asume the VM disk image is deleted
|
||||
"""
|
||||
cmd='azure vm disk delete --json '
|
||||
if dele :
|
||||
cmd += '--blob-delete '
|
||||
cmd+= di_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
def flushVMImage(vmi_name):
|
||||
"""
|
||||
Delete the VM Image.
|
||||
Always delete the underlying blob.
|
||||
On error we asume the VM image is deleted.
|
||||
"""
|
||||
cmd='azure vm image delete --blob-delete --json ' + vmi_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
def flushVM(vm_name,dele=False):
|
||||
"""
|
||||
Delete the VM.
|
||||
On error we asume the VM is deleted
|
||||
"""
|
||||
cmd='azure vm delete --json '
|
||||
if dele :
|
||||
cmd += ' --blob-delete '
|
||||
cmd += vm_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
|
||||
def createStableVMFromVMImage(vm_image,vhd_url):
|
||||
"""
|
||||
Create a new stable vm, provisioned with acct and certificate from
|
||||
the VMImage, using the basepath of vhd_url for the new VM's vhd.
|
||||
"""
|
||||
stableVM=testname+'-stable-vm'
|
||||
return makeVM(stableVM,vm_image,vhd_url,testname+'-stable',location,stableVMaccount,stableVMpass,stableVMCert,copy=True)
|
||||
|
||||
def createStableVMFromVHD(vmi_name,vhd_url):
|
||||
"""
|
||||
Create a new stable vm, provisioned with acct and certificate from
|
||||
the VHD, using the basepath of vhd_url for the new VM's vhd.
|
||||
"""
|
||||
makeVMImage(vmi_name,vhd_url,False)
|
||||
return createStableVMFromVMImage(vmi_name,vhd_url)
|
||||
|
||||
def createDiskImageFromStableVMDisk(vm_name):
|
||||
"""
|
||||
Determine the media link for the os disk of the stable vm.
|
||||
Create vhd disk image copy. <vm_name>-<testname>-di
|
||||
Return new disk_image_media_path or None on error.
|
||||
"""
|
||||
cmd='azure vm disk list --json'
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
if code:
|
||||
print 'Error is ' + str(code)
|
||||
waagent.Log( 'Error is ' + str(code))
|
||||
return None
|
||||
j=json.loads(output)
|
||||
source_media_link=None
|
||||
for i in j :
|
||||
if i.has_key('AttachedTo'):
|
||||
if i['AttachedTo']['RoleName'] == vm_name:
|
||||
source_media_link=i['MediaLink']
|
||||
break
|
||||
if not source_media_link:
|
||||
print 'Unable to locate OS disk for ' + vm_name
|
||||
waagent.Log( 'Unable to locate OS disk for ' + vm_name )
|
||||
return None
|
||||
target_name= testname + '-di'
|
||||
makeDiskImage(target_name,source_media_link,location,copy=True)
|
||||
target_media_link=os.path.dirname(source_media_link) + '/' + target_name + '.vhd'
|
||||
return target_media_link
|
||||
|
||||
def addDiskImageToVM(vm_name,di_name):
|
||||
"""
|
||||
Attach the disk image to the 'stableVM'.
|
||||
Returns the LUN if successful otherwise returns None
|
||||
NOTE: azure vm show may return json matching the disk image
|
||||
name yet missing the LUN. When this occurs, the LUN is '0'.
|
||||
"""
|
||||
cmd='azure vm disk attach --json ' + vm_name + ' ' + di_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log(str(code))
|
||||
waagent.Log(output)
|
||||
cmd='azure vm show --json ' + vm_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
retries=3
|
||||
while code != 0 and retries:
|
||||
retries-=1
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
|
||||
if code == 0:
|
||||
jsn=json.loads(output)
|
||||
for i in jsn['DataDisks']:
|
||||
if i['DiskName'] == di_name:
|
||||
if 'Lun' in i :
|
||||
return i['Lun']
|
||||
else :
|
||||
return u'0'
|
||||
return None
|
||||
|
||||
|
||||
def dropDiskImageFromVM(vm_name,lun):
|
||||
"""
|
||||
Detach the disk image from the 'stableVM'.
|
||||
On Error we assume the disk is no longer attached.
|
||||
"""
|
||||
cmd='azure vm disk detach --json ' + vm_name + ' ' + lun
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
def checkVMProvisioned(vm_name):
|
||||
cmd='azure vm show --json ' + vm_name
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
code,output=RunGetOutput(cmd,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
if code ==0 :
|
||||
j=json.loads(output)
|
||||
print vm_name+' instance status: ', j['InstanceStatus']
|
||||
waagent.Log( vm_name+' instance status: ' + j['InstanceStatus'])
|
||||
if j['InstanceStatus'] == 'ReadyRole':
|
||||
return True, j['InstanceStatus']
|
||||
else :
|
||||
print 'Error: ' + output , code
|
||||
waagent.Log( 'Error: ' + output + str(code))
|
||||
return False, j['InstanceStatus']
|
||||
|
||||
def updateAgent(agent_path,vm_name,account,cert,disk_mountpoint,mnt_opts,lun,partnum,provisioned_account):
|
||||
"""
|
||||
Copy the agent specified in 'agent' to the Disk
|
||||
using the 'stableVM'.
|
||||
"""
|
||||
retries=30
|
||||
retry=0
|
||||
cmd='uptime'
|
||||
while ssh_command(vm_name,account,cmd)[1] != 0 and retry < retries :
|
||||
time.sleep(10)
|
||||
retry+=1
|
||||
#setup sudo NOPASSWD
|
||||
pss=stableVMpass.replace('$','\$')
|
||||
cmd='echo \'' + pss + '\' > /home/' + account + '/pswd '
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='echo \'#!/bin/bash\ncat /home/' + account + '/pswd\n\' > /home/' + account + '/pw.sh'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='chmod +x /home/' + account + '/pw.sh'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A mkdir -p ' + disk_mountpoint
|
||||
ssh_command(vm_name,account,cmd)
|
||||
retries=3
|
||||
# TODO retires here for the mount
|
||||
#mount
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A mount ' +mnt_opts + ' ' + lunToDiskName(lun,partnum) + ' ' +disk_mountpoint
|
||||
waagent.Log( cmd)
|
||||
retry=0
|
||||
while ssh_command(vm_name,account,cmd)[1] not in (0,32) and retry < retries :
|
||||
if retry == 0:
|
||||
if 'bsd' in fstype:
|
||||
fcmd = "export SUDO_ASKPASS=./pw.sh && sudo -A fsck_ffs -y "
|
||||
else :
|
||||
fcmd = "export SUDO_ASKPASS=./pw.sh && sudo -A fsck -y "
|
||||
fcmd += lunToDiskName(lun,partnum)
|
||||
ssh_command(vm_name,account,fcmd)
|
||||
time.sleep(2)
|
||||
retry+=1
|
||||
|
||||
# remove packaged agent service if present.
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' dpkg -r walinuxagent'
|
||||
ssh_command(vm_name,account,cmd) # remove Ubuntu walinuxagent agent service if present.
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A rm '+ disk_mountpoint+'/etc/default/walinuxagent'
|
||||
ssh_command(vm_name,account,cmd) # remove Ubuntu walinuxagent agent service if present.
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' rpm -e WALinuxAgent'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#copy agent
|
||||
remote_path='/tmp'
|
||||
print 'scp ' + agent_path + ' to ' + vm_name + ' ' + account + ':' + remote_path
|
||||
waagent.Log( 'scp ' + agent_path + ' to ' + vm_name + ' ' + account + ':' + remote_path)
|
||||
retry=0
|
||||
while scp_to_host_command(account,vm_name,remote_path,agent_path)[1] != 0 and retry < retries :
|
||||
time.sleep(2)
|
||||
retry+=1
|
||||
# move agent to /usr/sbin
|
||||
cmd= 'export SUDO_ASKPASS=./pw.sh && sudo -A cp ' + remote_path +'/waagent '+ disk_mountpoint+'/usr/sbin/waagent'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd= 'export SUDO_ASKPASS=./pw.sh && sudo -A chmod 755 '+ disk_mountpoint+'/usr/sbin/waagent'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
# Fix the password file
|
||||
if 'bsd' in fstype:
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A cp /etc/master.passwd ' + disk_mountpoint + '/etc/master.passwd'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
else :
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A cp /etc/passwd ' + disk_mountpoint + '/etc/passwd'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A cp /etc/shadow ' + disk_mountpoint + '/etc/shadow'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#remove /var/lib/waagent
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A rm -rf ' + disk_mountpoint + '/var/lib/waagent'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#remove /var/log/waagent*
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A rm -rf ' + disk_mountpoint + '/var/log/waagent*'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#delete the provisioning user
|
||||
if 'bsd' in fstype:
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' rmuser -y ' + provisioned_account
|
||||
ssh_command(vm_name,account,cmd)
|
||||
else :
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' userdel -f ' + provisioned_account
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' groupdel ' + provisioned_account
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A rm -rf ' + disk_mountpoint + '/home/' + provisioned_account
|
||||
ssh_command(vm_name,account,cmd)
|
||||
# install agent
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chroot '+ disk_mountpoint+' /usr/sbin/waagent verbose install '
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd="export SUDO_ASKPASS=./pw.sh && sudo -A sed -i 's/Verbose=n/Verbose=y/' " + disk_mountpoint+"/etc/waagent.conf"
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#umount
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A umount ' + lunToDiskName(lun,partnum)
|
||||
ssh_command(vm_name,account,cmd)
|
||||
|
||||
def gatherAgentInfo(localpath,vm_name,account,cert,disk_mountpoint,mnt_opts,lun,partnum):
|
||||
"""
|
||||
Copy the /var/lib/waagent, and /var/log directories to
|
||||
localhost:localpath.
|
||||
"""
|
||||
retries=30
|
||||
retry=0
|
||||
cmd='uptime'
|
||||
while ssh_command(vm_name,account,cmd)[1] != 0 and retry < retries :
|
||||
time.sleep(10)
|
||||
retry+=1
|
||||
#mount
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A mount ' +mnt_opts + ' ' + lunToDiskName(lun,partnum) + ' ' +disk_mountpoint
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
ssh_command(vm_name,account,cmd)
|
||||
#copy info
|
||||
Run("mkdir -p "+ localpath)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A mkdir -p /tmp/results'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A cp -r ' + disk_mountpoint + '/var/log /tmp/results/'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A cp -r ' + disk_mountpoint + '/var/lib/waagent /tmp/results/'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chmod -R 777 /tmp/results'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A chown -R ' + account + ' /tmp/results'
|
||||
ssh_command(vm_name,account,cmd)
|
||||
scp_from_host_command(account,vm_name,'/tmp/results/*',localpath)
|
||||
#umount
|
||||
cmd='export SUDO_ASKPASS=./pw.sh && sudo -A umount ' + lunToDiskName(lun,partnum)
|
||||
print cmd
|
||||
waagent.Log( cmd)
|
||||
ssh_command(vm_name,account,cmd)
|
||||
|
||||
def lunToDiskName(lun,partnum):
|
||||
if 'bsd' in fstype :
|
||||
return lunToFreeBSDDiskName(lun,partnum)
|
||||
else :
|
||||
return lunToScsiDiskName(lun,partnum)
|
||||
|
||||
def lunToScsiDiskName(lun,partnum):
|
||||
"""
|
||||
Convert lun to '/dev/sd[chr(ord('c')+lun)]partnum'
|
||||
"""
|
||||
return str('/dev/sd'+chr( (ord('c')+int(lun)) ) +str(partnum))
|
||||
|
||||
def lunToFreeBSDDiskName(lun,partnum):
|
||||
"""
|
||||
Convert lun to '/dev/da' + str(lun) + 'p' + partnum
|
||||
"""
|
||||
return '/dev/da'+ str(int(lun)) + 'p' + str(partnum)
|
||||
|
||||
def ssh_command(host,account,cmd):
|
||||
"""
|
||||
Wrapper for an ssh operation.
|
||||
"""
|
||||
if stableVMCert == None:
|
||||
if not os.path.exists('./pw.sh'):
|
||||
with open('./pw.sh','w') as F:
|
||||
F.write('#!/bin/bash\ncat ./pswd\n')
|
||||
os.system('chmod +x ./pw.sh')
|
||||
with open('./pswd','w') as F:
|
||||
F.write(stableVMpass)
|
||||
req = "export SSH_ASKPASS=./pw.sh && setsid ssh -T -o StrictHostKeyChecking='no' " + account + "@" + host.lower() + ".cloudapp.net \"" + cmd + "\""
|
||||
else :
|
||||
req = "ssh -t -o StrictHostKeyChecking='no' " + account + "@" + host.lower() + ".cloudapp.net \"" + cmd + "\""
|
||||
print req
|
||||
waagent.Log(req)
|
||||
code,output=RunGetOutput(req,False)
|
||||
print output,code
|
||||
waagent.Log(str(code))
|
||||
waagent.Log(output.encode('ascii','ignore'))
|
||||
return output,code
|
||||
|
||||
def scp_to_host_command(account,host,remote_path,local_path):
|
||||
"""
|
||||
Wrapper for an scp operation. Always uses -r.
|
||||
Requires key authentication configured.
|
||||
"""
|
||||
req="scp -o StrictHostKeyChecking='no' -r " + local_path + " " + account + "@" + host.lower() + ".cloudapp.net:" + remote_path
|
||||
print req
|
||||
waagent.Log( req)
|
||||
code,output=RunGetOutput(req,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
def scp_from_host_command(account,host,remote_path,local_path):
|
||||
"""
|
||||
Wrapper for an scp operation. Always uses -r.
|
||||
Requires key authentication configured.
|
||||
"""
|
||||
req="scp -r " + account + "@" + host.lower() + ".cloudapp.net:" + remote_path + " " + local_path
|
||||
print req
|
||||
waagent.Log( req)
|
||||
code,output=RunGetOutput(req,False)
|
||||
print output,code
|
||||
waagent.Log( str(code))
|
||||
waagent.Log(output)
|
||||
return output,code
|
||||
|
||||
def teardown(name):
|
||||
diskImageName=os.path.splitext(os.path.basename(sourceVHD))[0]+'-di'
|
||||
while makeDiskImage(diskImageName,sourceVHD,location,True)[1] !=0 :
|
||||
time.sleep(20)
|
||||
lun=addDiskImageToVM(stableVM,diskImageName)
|
||||
while lun == None :
|
||||
time.sleep(2)
|
||||
lun=addDiskImageToVM(stableVM,diskImageName)
|
||||
out,code=flushVM(vmName,True)
|
||||
if code != 0 :
|
||||
vmDisk=out[out.find('disk with name ')+len('disk with name '):out.find(' is currently in use')]
|
||||
while flushDiskImage(vmDisk,True)[1] != 0 :
|
||||
time.sleep(5)
|
||||
out,code=flushVMImage(vmImageName)
|
||||
if code != 0 :
|
||||
vmDisk=out[out.find('disk with name ')+len('disk with name '):out.find(' is currently in use')]
|
||||
while flushDiskImage(vmDisk,True)[1] != 0 :
|
||||
time.sleep(5)
|
||||
gatherAgentInfo(localInfo+'/'+name,stableVM,stableVMaccount,stableVMCert,stableVMMountpoint,mountOptions,lun,partNum)
|
||||
print 'Logs for ' + vmName + ' copied to ' + localInfo + '/' + name
|
||||
waagent.Log( 'Logs for ' + vmName + ' copied to ' + localInfo + '/' + name)
|
||||
# detach and delete the disk image
|
||||
while dropDiskImageFromVM(stableVM,lun)[1] != 0 :
|
||||
time.sleep(2)
|
||||
while flushDiskImage(diskImageName,('no' in keep_vhd))[1] != 0 :
|
||||
time.sleep(2)
|
||||
out,code=flushVM(stableVM,True)
|
||||
if code != 0 :
|
||||
stableVMDisk=out[out.find('disk with name ')+len('disk with name '):out.find(' is currently in use')]
|
||||
while flushDiskImage(stableVMDisk,True)[1] != 0 :
|
||||
time.sleep(5)
|
||||
if stableVMImageName:
|
||||
while flushVMImage(stableVMImageName,True)[1] != 0 :
|
||||
time.sleep(2)
|
||||
|
||||
def doPrompt() :
|
||||
if prompt in ('yes','on'):
|
||||
raw_input('Press enter to continue:')
|
||||
|
||||
if __name__ == '__main__' :
|
||||
"""
|
||||
Create a disk image and attach it to StableVM.
|
||||
Copy the current sources to it.
|
||||
Detach and delete the disk image container
|
||||
Delete the vm image container and the VM.
|
||||
Create a vm image container, and the VM.
|
||||
Check the VM for provision succedded:
|
||||
if so, exit
|
||||
if provisioning failed:
|
||||
delete the vm, delete the vm image, create a disk image
|
||||
from the VM's vhd, attach the disk to the stable VM, copy
|
||||
/var/log and /var/lib/waagent to the localhost.
|
||||
"""
|
||||
stableVM=''
|
||||
mountOptions=''
|
||||
stableVMMountpoint='/mnt/disk' # need to ensure this is created if not existing.
|
||||
sourceVHD=''
|
||||
location=""
|
||||
localAgent='/home/ericg/Public/git_repos/private/WALinuxAgent-Private/waagent_freebsd'
|
||||
localInfo='./logs'
|
||||
stableVMaccount='' # Need to ensure root permissions for this to work
|
||||
stableVMpass=''
|
||||
stableVMCert=''
|
||||
provisionedVMaccount=''
|
||||
provisionedVMpass=''
|
||||
provisionedVMCert=''
|
||||
account=''
|
||||
testname='azuretest'
|
||||
partNum=1
|
||||
provision_retries=1
|
||||
fstype='scsi'
|
||||
keep_vhd='no'
|
||||
teardown_test_vm='fail'
|
||||
teardown_stable_vm='fail'
|
||||
prompt = 'yes'
|
||||
stable_vm_vhd=None
|
||||
stableVMImageName=None
|
||||
stable_vm_image=None
|
||||
logfile='azure_test.log'
|
||||
"""
|
||||
We need to create a disk image container and attach it to a stable
|
||||
vm in order to copy the current sources to it. Then we detach it,
|
||||
delete the disk image container, create a vm image container, and
|
||||
the VM.
|
||||
"""
|
||||
|
||||
for i in range(len(sys.argv)) :
|
||||
if '--stable_vm' == sys.argv[i] : stableVM=sys.argv[i+1]
|
||||
elif '--source_disk' == sys.argv[i]: sourceVHD=sys.argv[i+1]
|
||||
elif '--storage_acct' == sys.argv[i]: account=sys.argv[i+1]
|
||||
elif '--testname' == sys.argv[i] : testname=sys.argv[i+1]
|
||||
elif '--stable_vm_mount_point' == sys.argv[i] : stableVMMountpoint=sys.argv[i+1]
|
||||
elif '--agent_path' == sys.argv[i] : localAgent=sys.argv[i+1]
|
||||
elif '--stable_vm_acct_name' == sys.argv[i] : stableVMaccount=sys.argv[i+1]
|
||||
elif '--stable_vm_acct_pass' == sys.argv[i] : stableVMpass=sys.argv[i+1]
|
||||
elif '--stable_vm_acct_cert' == sys.argv[i] : stableVMCert=sys.argv[i+1]
|
||||
elif '--test_vm_acct_name' == sys.argv[i] : provisionedVMaccount=sys.argv[i+1]
|
||||
elif '--test_vm_acct_pass' == sys.argv[i] : provisionedVMpass=sys.argv[i+1]
|
||||
elif '--test_vm_acct_cert' == sys.argv[i] : provisionedVMCert=sys.argv[i+1]
|
||||
elif '--azure_location' == sys.argv[i] : location=sys.argv[i+1]
|
||||
elif '--mount_opts' == sys.argv[i] : mountOptions=sys.argv[i+1]
|
||||
elif '--part_num' == sys.argv[i] : partNum=sys.argv[i+1]
|
||||
elif '--retries' == sys.argv[i] : provision_retries=int(sys.argv[i+1])
|
||||
elif '--fs_type' == sys.argv[i] : fstype=sys.argv[i+1]
|
||||
elif '--keep_test_vm_vhd' == sys.argv[i] : keep_vhd=sys.argv[i+1]
|
||||
elif '--teardown_test_vm' == sys.argv[i] : teardown_test_vm=sys.argv[i+1]
|
||||
elif '--teardown_stable_vm' == sys.argv[i] : teardown_stable_vm=sys.argv[i+1]
|
||||
elif '--prompt' == sys.argv[i] : prompt=sys.argv[i+1]
|
||||
elif '--stable_vm_image' == sys.argv[i] : stable_vm_image=sys.argv[i+1]
|
||||
elif '--stable_vm_vhd' == sys.argv[i] : stable_vm_vhd=sys.argv[i+1]
|
||||
elif '--logfile' == sys.argv[i] : logfile=sys.argv[i+1]
|
||||
|
||||
LoggerInit(logfile,'')
|
||||
waagent.Log("User: "+ pwd.getpwuid(os.geteuid()).pw_name +" Running Command :\n" + reduce(lambda x, y: x+' '+y,sys.argv))
|
||||
|
||||
if len(stableVM) == 0 and not ( stable_vm_image or stable_vm_vhd ):
|
||||
print '--vm <stable vm> must be provided unless --stable_vm_image or --stable_vm_vhd'
|
||||
waagent.Log( '--vm <stable vm> must be provided!')
|
||||
sys.exit(1)
|
||||
else:
|
||||
if stable_vm_image:
|
||||
sourceVHD=createStableVMFromVMImage(stable_vm_image,sourceVHD)
|
||||
stableVM=testname+'-stable-vm'
|
||||
elif stable_vm_vhd:
|
||||
stableVMImageName=testname+'-stable-vi'
|
||||
sourceVHD=createStableVMFromVHD(stableVMImageName,stable_vm_vhd)
|
||||
stableVM=testname+'-stable-vm'
|
||||
p = False
|
||||
retries = provision_retries
|
||||
while not p and retries > 0:
|
||||
p,out = checkVMProvisioned(stableVM)
|
||||
if not p:
|
||||
if 'Failed' in out or 'Timeout' in out :
|
||||
break
|
||||
print stableVM + ' Not Provisioned - sleeping on retry:' + str( provision_retries - retries )
|
||||
waagent.Log( stableVM + ' Not Provisioned - sleeping on retry:' + str( provision_retries - retries ) )
|
||||
time.sleep(30)
|
||||
retries -= 1
|
||||
else :
|
||||
print stableVM + ' Provision SUCCEEDED.'
|
||||
waagent.Log( stableVM + ' Provision SUCCEEDED.')
|
||||
# done creating the stable vm
|
||||
vmImageName=os.path.splitext(os.path.basename(sourceVHD))[0]+'-vi'
|
||||
#flushVMImage(vmImageName)
|
||||
|
||||
# if no disk image name is provided we want to clone the stable vm disk.
|
||||
if not sourceVHD:
|
||||
sourceVHD=createDiskImageFromStableVMDisk(stableVM)
|
||||
if not sourceVHD:
|
||||
print 'Errors - unable to create disk image - assuming created'
|
||||
waagent.Log( 'Errors - unable to create disk image - assuming created')
|
||||
diskImageName=os.path.splitext(os.path.basename(sourceVHD))[0]
|
||||
else :
|
||||
diskImageName=os.path.splitext(os.path.basename(sourceVHD))[0]+'-di'
|
||||
diskImageVHD,code=makeDiskImage(diskImageName,sourceVHD,location,True)
|
||||
if code:
|
||||
print 'Error - unable to make ' + diskImageName
|
||||
waagent.Log( 'Error - unable to make ' + diskImageName)
|
||||
|
||||
lun=addDiskImageToVM(stableVM,diskImageName)
|
||||
while lun == None :
|
||||
time.sleep(2)
|
||||
lun=addDiskImageToVM(stableVM,diskImageName)
|
||||
|
||||
doPrompt()
|
||||
updateAgent(localAgent,stableVM,stableVMaccount,stableVMCert,stableVMMountpoint,mountOptions,lun,partNum,provisionedVMaccount)
|
||||
doPrompt()
|
||||
#reboot to prevent stale mount bugs
|
||||
cmd= 'export SUDO_ASKPASS=./pw.sh && sudo -A reboot'
|
||||
ssh_command(stableVM,stableVMaccount,cmd)
|
||||
|
||||
while dropDiskImageFromVM(stableVM,lun)[1] != 0 :
|
||||
time.sleep(2)
|
||||
while flushDiskImage(diskImageName,False)[1] != 0 :
|
||||
time.sleep(2)
|
||||
vmImageName=os.path.splitext(os.path.basename(sourceVHD))[0]+'-vi'
|
||||
flushVMImage(vmImageName)
|
||||
vmName=testname+'-vm'
|
||||
flushVM(vmName)
|
||||
makeVMImage(vmImageName,diskImageVHD,True)
|
||||
sourceVHD=makeVM(vmName,vmImageName,sourceVHD,testname,location,provisionedVMaccount,provisionedVMpass,provisionedVMCert,True)
|
||||
print 'The new source vhd is ' + sourceVHD
|
||||
waagent.Log( 'The new source vhd is ' + sourceVHD)
|
||||
p = False
|
||||
retries = provision_retries
|
||||
while not p and retries > 0:
|
||||
p,out = checkVMProvisioned(vmName)
|
||||
if not p:
|
||||
if 'Failed' in out or 'Timeout' in out :
|
||||
break
|
||||
print vmName + ' Not Provisioned - sleeping on retry:' + str( provision_retries - retries )
|
||||
waagent.Log( vmName + ' Not Provisioned - sleeping on retry:' + str( provision_retries - retries ) )
|
||||
time.sleep(30)
|
||||
else :
|
||||
print vmName + ' Provision SUCCEEDED.'
|
||||
waagent.Log( vmName + ' Provision SUCCEEDED.')
|
||||
doPrompt()
|
||||
if teardown_test_vm in ('success','always'):
|
||||
teardown(testname+'_pass')
|
||||
sys.exit(0)
|
||||
retries -= 1
|
||||
|
||||
print vmName + ' Provision FAILED.'
|
||||
waagent.Log( vmName + ' Provision FAILED.')
|
||||
doPrompt()
|
||||
if teardown_test_vm in ('fail','always'):
|
||||
teardown(testname+'_fail')
|
||||
sys.exit(1)
|
23
tests/env.py
23
tests/env.py
|
@ -1,23 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
import imp
|
||||
import os
|
||||
|
||||
projet_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
waagent = imp.load_source('waagent', os.path.join(projet_root, 'waagent'))
|
||||
|
||||
waagent.LoggerInit('/tmp/test.log','/dev/stdout')
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
import unittest
|
||||
from env import waagent
|
||||
|
||||
sample_mount_list = """\
|
||||
/dev/sda1 on / type ext4 (rw)
|
||||
proc on /proc type proc (rw)
|
||||
sysfs on /sys type sysfs (rw)
|
||||
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
|
||||
tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")
|
||||
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
|
||||
/dev/sdb1 on /mnt/resource type ext4 (rw)
|
||||
"""
|
||||
|
||||
device_name="/dev/sdb"
|
||||
|
||||
class TestWAAgentUtils(unittest.TestCase):
|
||||
|
||||
def test_get_mount_point(self):
|
||||
normal = sample_mount_list
|
||||
mp = waagent.GetMountPoint(normal, device_name)
|
||||
self.assertEqual(mp, '/mnt/resource')
|
||||
|
||||
null = None
|
||||
mp = waagent.GetMountPoint(null, device_name)
|
||||
self.assertEqual(mp, None)
|
||||
|
||||
malformed = 'asdfasdfasdfa aasdf'
|
||||
mp = waagent.GetMountPoint(malformed, device_name)
|
||||
self.assertEqual(mp, None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,386 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
import socket
|
||||
import fcntl
|
||||
import struct
|
||||
import array
|
||||
import re
|
||||
import tempfile
|
||||
import unittest
|
||||
import random
|
||||
import string
|
||||
import threading
|
||||
from time import ctime, sleep
|
||||
import imp
|
||||
|
||||
# waagent has no '.py' therefore create waagent module import manually.
|
||||
waagent=imp.load_source('waagent','../waagent')
|
||||
|
||||
TestingVersion = "$CommitBranch:future$|$LastCommitDate:2013-04-16 15:52:17 -0700$|$LastCommitHash:7ad7c643b2adbac40b1ea4a5b6eb19f0fe971623$"
|
||||
|
||||
|
||||
class WaagentTestCases(unittest.TestCase):
|
||||
"""
|
||||
Test cases for waagent
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
Check for root permissions.
|
||||
Check Distro is supported.
|
||||
Create a waagent.conf file.
|
||||
"""
|
||||
waagent.LoggerInit('/var/log/waagent.log','/dev/console')
|
||||
if not self.AmIRoot():
|
||||
raise Exception('I need to run as root')
|
||||
DistroName=platform.dist()[0]
|
||||
self.failUnless(hasattr(waagent,DistroName+'Distro') == True,DistroName+' is not a supported linux distribution.')
|
||||
waagent.MyDistro=getattr(waagent,DistroName+'Distro')()
|
||||
# set up /etc/waagent.conf
|
||||
with open('/etc/waagent.conf','wb') as f:
|
||||
f.write(waagent.WaagentConf)
|
||||
f.close()
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Remove test resources.
|
||||
This is a stub
|
||||
"""
|
||||
pass
|
||||
|
||||
def AmIRoot(self):
|
||||
"""
|
||||
Check that our uid is root.
|
||||
"""
|
||||
return 'root' in waagent.RunGetOutput('id')[1]
|
||||
|
||||
def writetothelog(self,id):
|
||||
"""
|
||||
Convienence function.
|
||||
Used by testTwoLogWritingThreads()
|
||||
Write 'start', sleep for id seconds and
|
||||
write 'end' to the logfile.
|
||||
"""
|
||||
waagent.Log(str(id)+' start ')
|
||||
sleep(id)
|
||||
waagent.Log(str(id)+' end ')
|
||||
|
||||
def noop(self,arg2):
|
||||
"""
|
||||
Set a method to noop() to prevent its operation.
|
||||
"""
|
||||
pass
|
||||
|
||||
##############TESTCASES##########################
|
||||
|
||||
###############Astract Distro - Concrete Distro Tests##############
|
||||
|
||||
def testMyDistroMemberVariables(self):
|
||||
"""
|
||||
Ensure that required Distro properties are not None.
|
||||
"""
|
||||
assert waagent.MyDistro.agent_service_name is not None , 'MyDistro.agent_service_name must not be None'
|
||||
assert waagent.MyDistro.selinux is not None , 'MyDistro.selinux must not be None'
|
||||
assert waagent.MyDistro.ssh_service_name is not None , 'MyDistro.ssh_service_name must not be None'
|
||||
assert waagent.MyDistro.ssh_config_file is not None , 'MyDistro.ssh_config_file must not be None'
|
||||
assert waagent.MyDistro.hostname_file_path is not None , 'MyDistro.hostname_file_path must not be None'
|
||||
assert waagent.MyDistro.dhcp_client_name is not None , 'MyDistro.dhcp_client_name must not be None'
|
||||
assert waagent.MyDistro.requiredDeps is not None , 'MyDistro.requiredDeps must not be None'
|
||||
assert waagent.MyDistro.init_script_file is not None , 'MyDistro.init_script_file must not be None'
|
||||
assert waagent.MyDistro.agent_package_name is not None , 'MyDistro.agent_package_name must not be None'
|
||||
assert waagent.MyDistro.fileBlackList is not None , 'MyDistro.fileBlackList must not be None'
|
||||
assert waagent.MyDistro.agent_files_to_uninstall is not None , 'MyDistro.agent_files_to_uninstall must not be None'
|
||||
assert waagent.MyDistro.grubKernelBootOptionsFile is not None , 'MyDistro.grubKernelBootOptionsFile must not be None'
|
||||
assert waagent.MyDistro.grubKernelBootOptionsLine is not None , 'MyDistro.grubKernelBootOptionsLine must not be None'
|
||||
|
||||
|
||||
def testMyDistro_restartSshService(self):
|
||||
"""
|
||||
Test MyDistro.restartSshService()
|
||||
"""
|
||||
cmd = 'service '+ waagent.MyDistro.ssh_service_name + ' status'
|
||||
sshpid=string.rsplit(waagent.RunGetOutput(cmd)[1],' ',1)
|
||||
waagent.MyDistro.restartSshService()
|
||||
assert sshpid is not string.rsplit(waagent.RunGetOutput(cmd)[1],' ',1),'ssh server pid is unchanged.'
|
||||
|
||||
# def testMyDistro_checkPackageInstalled(self):
|
||||
# """MyDistro can check if WaLinuxAgent package is installed"""
|
||||
# assert waagent.MyDistro.checkPackageInstalled(waagent.MyDistro.agent_package_name) != 0, waagent.MyDistro.agent_package_name+' is Not Installed.'
|
||||
|
||||
# def testMyDistro_checkPackageUpdateable(self):
|
||||
# """MyDistro can check if WaLinuxAgent package is updateable to new version."""
|
||||
# assert waagent.MyDistro.checkPackageUpdateable(waagent.MyDistro.agent_package_name) == 0 , waagent.MyDistro.agent_package_name+' is not updateable.'
|
||||
|
||||
|
||||
def testMyDistro_isSelinuxSystem(self):
|
||||
"""
|
||||
MyDistro can perform Selinux operations.
|
||||
Test MyDistro.isSelinuxSystem, if true then also test:
|
||||
MyDistro.isSelinuxRunning
|
||||
MyDistro.setSelinuxEnforce
|
||||
MyDistro.setSelinuxContext
|
||||
"""
|
||||
selinux=waagent.MyDistro.isSelinuxSystem()
|
||||
if selinux:
|
||||
assert waagent.MyDistro.isSelinuxRunning(), 'Selinux not running.'
|
||||
assert waagent.MyDistro.setSelinuxEnforce(0), 'Unable to call setenforce(0).'
|
||||
assert waagent.MyDistro.setSelinuxContext('./test_waagent.py','unconfined_u:object_r:ssh_home_t:s0'), 'Unable to set Selinux context.'
|
||||
assert waagent.MyDistro.setSelinuxEnforce(0), 'Unable to call setenforce(1).'
|
||||
else:
|
||||
print 'Selinux not installed. - skipping Selinux tests'
|
||||
|
||||
def testMyDistro_load_unload_ata_piix(self):
|
||||
"""
|
||||
Attempt to insert and remove ata_piix.ko
|
||||
by calling MyDistro.load_ata_piix
|
||||
and MyDistro.unload_ata_piix.
|
||||
"""
|
||||
assert waagent.MyDistro.load_ata_piix() == 0, 'Unable to load ata_piix.ko.'
|
||||
assert waagent.MyDistro.unload_ata_piix() == 0, 'Unable to unload ata_piix.ko.'
|
||||
|
||||
def testMyDistro_publishHostname(self):
|
||||
"""
|
||||
Test MyDistro.publishHostname
|
||||
on success, the distro dependent config
|
||||
contains the hostname, but currently
|
||||
this test suceeds if the config files were written
|
||||
without error.
|
||||
"""
|
||||
assert waagent.MyDistro.publishHostname('LENG') == 0, 'Error setting hostname to LENG.'
|
||||
|
||||
# def testMyDistro_registerAgentService(self):
|
||||
# assert waagent.MyDistro.registerAgentService() == 0, 'Unable to register agent as service.'
|
||||
|
||||
def testMyDistro_setHostname(self):
|
||||
"""
|
||||
Test MyDistro.setHostname.
|
||||
Successfull if hostname is changed.
|
||||
Reset hostname when finished.
|
||||
"""
|
||||
code,oldname = waagent.RunGetOutput('hostname')
|
||||
waagent.MyDistro.setHostname('HOSTNAMETEST')
|
||||
code,newname = waagent.RunGetOutput('hostname')
|
||||
assert 'HOSTNAMETEST' == newname.strip(), 'Unable to set hostname.'
|
||||
waagent.MyDistro.setHostname(oldname)
|
||||
|
||||
def testMyDistro_checkDependencies(self):
|
||||
"""
|
||||
Test MyDistro.checkDependencies succeeds
|
||||
"""
|
||||
assert waagent.MyDistro.checkDependencies() == 0 , 'Dependency Check failed.'
|
||||
|
||||
def testMyDistro_startAgentService(self):
|
||||
"""
|
||||
Test MyDistro.startAgentService.
|
||||
"""
|
||||
assert waagent.MyDistro.startAgentService() == 0, 'Unable to start ' + waagent.MyDistro.agent_service_name
|
||||
|
||||
def testMyDistro_stopAgentService(self):
|
||||
"""
|
||||
Test MyDistro.stopAgentService.
|
||||
"""
|
||||
assert waagent.MyDistro.stopAgentService() == 0, 'Unable to stop ' + waagent.MyDistro.agent_service_name
|
||||
|
||||
def testMyDistro_deleteRootPassword(self):
|
||||
"""
|
||||
Test MyDistro.deleteRootPassword.
|
||||
Restore the shadow file to previous state when finished.
|
||||
"""
|
||||
#copy the shadow
|
||||
waagent.Run('cp /etc/shadow /etc/shadow.keep')
|
||||
waagent.MyDistro.deleteRootPassword()
|
||||
assert waagent.Run('grep LOCK /etc/shadow') == 0 , 'Error removing root password.'
|
||||
# put shadow back
|
||||
waagent.Run('mv /etc/shadow.keep /etc/shadow')
|
||||
|
||||
def testFindIn_AppendTo_RemoveFrom_LinuxKernelCmdline(self):
|
||||
"""
|
||||
Test LinuxKernelCmdline operations.
|
||||
Search for 'splish=splash' in the kernel boot options, expect fail.
|
||||
Add 'splish=splash'. Search for splish=splash expect success.
|
||||
Remove 'splish=splash', confirm splish=splash absent
|
||||
"""
|
||||
m=waagent.FindInLinuxKernelCmdline('splish=splash')
|
||||
assert not m, '"splish=splash" was found before i put it there!!! edit it to remove "splish=splash" please.'
|
||||
|
||||
waagent.AppendToLinuxKernelCmdline('splish=splash')
|
||||
m=waagent.FindInLinuxKernelCmdline('splish=splash')
|
||||
assert m, 'AppendToLinuxKernelCmdline failed, "splish=splash" still not found.'
|
||||
|
||||
waagent.RemoveFromLinuxKernelCmdline('splish=splash')
|
||||
m=waagent.FindInLinuxKernelCmdline('splish=splash')
|
||||
assert not m, 'RemoveFromLinuxKernelCmdline failed, "splish=splash" still found.'
|
||||
|
||||
###############Generic waagent tests##############
|
||||
|
||||
def testLogFile(self):
|
||||
"""
|
||||
Write a random number with waagent.Log() and read it back.
|
||||
"""
|
||||
rnds=str(random.random())
|
||||
waagent.Log('testLogFile: '+rnds)
|
||||
found = rnds in (open('/var/log/waagent.log','rb').read())
|
||||
assert found,'Unable to find '+rnds+' in /var/log/waagent.log'
|
||||
|
||||
def testFindReplaceStringInFile(self):
|
||||
"""
|
||||
Test file/string operations using
|
||||
string literals and regular expressions.
|
||||
Tests:
|
||||
FindStringInFile
|
||||
ReplaceStringInFile
|
||||
|
||||
"""
|
||||
fn='/tmp/junk'
|
||||
if os.path.exists(fn):
|
||||
os.remove(fn)
|
||||
sp='splish splash'
|
||||
yb='yabba dabba do'
|
||||
open(fn,'wb').write(sp+' I was taking a bath.')
|
||||
m=waagent.FindStringInFile(fn,sp)
|
||||
assert m is not None,'waagent.FindStringInFile() Failed: '+sp+' not found in ' + fn + '.'
|
||||
src=r'^(.*)('+sp+')(.*)$'
|
||||
rpl=r'\1 '+sp+'\2 '+yb+' \3'
|
||||
waagent.ReplaceStringInFile(fn,src,rpl)
|
||||
m=waagent.FindStringInFile(fn,yb)
|
||||
assert m is not None,'waagent.ReplaceStringInFile() Failed: '+yb+' not found in ' + fn + '.'
|
||||
|
||||
def testGetFirstActiveNetworkInterfaceNonLoopback(self):
|
||||
"""
|
||||
Test GetFirstActiveNetworkInterfaceNonLoopback.
|
||||
Fail if iface is 'lo'
|
||||
"""
|
||||
addr='null'
|
||||
iface=waagent.GetFirstActiveNetworkInterfaceNonLoopback()[0]
|
||||
addr=waagent.GetFirstActiveNetworkInterfaceNonLoopback()[1]
|
||||
assert len(iface)>1,'Interface name too short'
|
||||
assert iface is not 'lo','Loopback Interface was returned'
|
||||
print 'iface=' + iface + ' addr=' + addr
|
||||
|
||||
def testTwoLogWritingThreads(self):
|
||||
"""
|
||||
Test that two threads writing to the same log
|
||||
function do not block or scramble messages.
|
||||
TODO - there is no check for success !!!
|
||||
"""
|
||||
for j in range(5):
|
||||
t1=threading.Thread(target=self.writetothelog,args=(4,))
|
||||
t2=threading.Thread(target=self.writetothelog,args=(2,))
|
||||
t1.start()
|
||||
t2.start()
|
||||
t1.join()
|
||||
t2.join()
|
||||
|
||||
def testCertificatesParse(self):
|
||||
"""
|
||||
TODO - need cert xml from test...
|
||||
"""
|
||||
pass
|
||||
|
||||
def testSharedConfigParse(self):
|
||||
|
||||
"""
|
||||
Test SharedConfig().Parse returns without error.
|
||||
"""
|
||||
assert waagent.SharedConfig().Parse(SHAREDCONFIG), 'Error parsing SharedConfig.xml'
|
||||
|
||||
|
||||
def testOvfEnvParse(self):
|
||||
"""
|
||||
Test OvfEnv().Parse returns without error.
|
||||
"""
|
||||
assert waagent.OvfEnv().Parse(OVFXML) is not None , 'Failed to Parse ovfxml'
|
||||
|
||||
def testOvfEnvProcess(self):
|
||||
"""
|
||||
We expect the /var/lib/waagent/Certificates.p7m file exists.
|
||||
Test ovfenv.Process() return other than None.
|
||||
"""
|
||||
assert os.path.exists('/var/lib/waagent/Certificates.p7m') , 'We expect the /var/lib/waagent/Certificates.p7m file exists.'
|
||||
waagent.WaAgent = waagent.Agent()
|
||||
ovfenv=waagent.OvfEnv().Parse(OVFXML)
|
||||
waagent.WaAgent.EnvMonitor = waagent.EnvMonitor()
|
||||
assert ovfenv.Process() is None , 'Failed to Process ovfxml'
|
||||
waagent.Run("userdel -f -r myUserName")
|
||||
|
||||
def testAgentProvision(self):
|
||||
"""
|
||||
TODO - Test Provision in non-fabric environment
|
||||
"""
|
||||
waagent.verbose = True
|
||||
waagent.WaAgent = waagent.Agent()
|
||||
waagent.WaAgent.EnvMonitor = waagent.EnvMonitor()
|
||||
waagent.Config = waagent.ConfigurationProvider()
|
||||
# we cant report our role unless we have one.
|
||||
waagent.WaAgent.ReportRoleProperties=self.noop
|
||||
err=waagent.WaAgent.Provision()
|
||||
assert err == None, 'Provision Failed error ' + str(err)
|
||||
|
||||
|
||||
########################################
|
||||
|
||||
|
||||
|
||||
OVFXML="""<?xml version="1.0" encoding="utf-8"?>
|
||||
<Environment xmlns="http://schemas.dmtf.org/ovf/environment/1" xmlns:oe="http://schemas.dmtf.org/ovf/environment/1" xmlns:wa="http://schemas.microsoft.com/windowsazure" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<wa:ProvisioningSection><wa:Version>1.0</wa:Version><LinuxProvisioningConfigurationSet xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType><HostName>egub13-vm</HostName><UserName>myUserName</UserName><UserPassword>mypassword</UserPassword><DisableSshPasswordAuthentication>false</DisableSshPasswordAuthentication><SSH><PublicKeys><PublicKey><Fingerprint>2D97B25D49B98ECC90BF1600D66D68799CFB361E</Fingerprint><Path>/home/myUserName/.ssh/authorized_keys</Path></PublicKey></PublicKeys></SSH></LinuxProvisioningConfigurationSet></wa:ProvisioningSection>
|
||||
|
||||
<wa:PlatformSettingsSection><wa:Version>1.0</wa:Version><PlatformSettings xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><KmsServerHostname>kms.core.windows.net</KmsServerHostname></PlatformSettings></wa:PlatformSettingsSection>
|
||||
</Environment>
|
||||
"""
|
||||
|
||||
SHAREDCONFIG="""
|
||||
<SharedConfig version="1.0.0.0" goalStateIncarnation="1">
|
||||
<Deployment name="db00a7755a5e4e8a8fe4b19bc3b330c3" guid="{ce5a036f-5c93-40e7-8adf-2613631008ab}" incarnation="2">
|
||||
<Service name="MyVMRoleService" guid="{00000000-0000-0000-0000-000000000000}" />
|
||||
<ServiceInstance name="db00a7755a5e4e8a8fe4b19bc3b330c3.1" guid="{d113f4d7-9ead-4e73-b715-b724b5b7842c}" />
|
||||
</Deployment>
|
||||
<Incarnation number="1" instance="MachineRole_IN_0" guid="{a0faca35-52e5-4ec7-8fd1-63d2bc107d9b}" />
|
||||
<Role guid="{73d95f1c-6472-e58e-7a1a-523554e11d46}" name="MachineRole" settleTimeSeconds="10" />
|
||||
<LoadBalancerSettings timeoutSeconds="0" waitLoadBalancerProbeCount="8">
|
||||
<Probes>
|
||||
<Probe name="MachineRole" />
|
||||
<Probe name="55B17C5E41A1E1E8FA991CF80FAC8E55" />
|
||||
<Probe name="3EA4DBC19418F0A766A4C19D431FA45F" />
|
||||
</Probes>
|
||||
</LoadBalancerSettings>
|
||||
<OutputEndpoints>
|
||||
<Endpoint name="MachineRole:Microsoft.WindowsAzure.Plugins.RemoteAccess.Rdp" type="SFS">
|
||||
<Target instance="MachineRole_IN_0" endpoint="Microsoft.WindowsAzure.Plugins.RemoteAccess.Rdp" />
|
||||
</Endpoint>
|
||||
</OutputEndpoints>
|
||||
<Instances>
|
||||
<Instance id="MachineRole_IN_0" address="10.115.153.75">
|
||||
<FaultDomains randomId="0" updateId="0" updateCount="0" />
|
||||
<InputEndpoints>
|
||||
<Endpoint name="a" address="10.115.153.75:80" protocol="http" isPublic="true" loadBalancedPublicAddress="70.37.106.197:80" enableDirectServerReturn="false" isDirectAddress="false" disableStealthMode="false">
|
||||
<LocalPorts>
|
||||
<LocalPortRange from="80" to="80" />
|
||||
</LocalPorts>
|
||||
</Endpoint>
|
||||
<Endpoint name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Rdp" address="10.115.153.75:3389" protocol="tcp" isPublic="false" enableDirectServerReturn="false" isDirectAddress="false" disableStealthMode="false">
|
||||
<LocalPorts>
|
||||
<LocalPortRange from="3389" to="3389" />
|
||||
</LocalPorts>
|
||||
</Endpoint>
|
||||
<Endpoint name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.RdpInput" address="10.115.153.75:20000" protocol="tcp" isPublic="true" loadBalancedPublicAddress="70.37.106.197:3389" enableDirectServerReturn="false" isDirectAddress="false" disableStealthMode="false">
|
||||
<LocalPorts>
|
||||
<LocalPortRange from="20000" to="20000" />
|
||||
</LocalPorts>
|
||||
</Endpoint>
|
||||
</InputEndpoints>
|
||||
</Instance>
|
||||
</Instances>
|
||||
</SharedConfig>
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s=unittest.TestLoader().loadTestsFromTestCase(WaagentTestCases)
|
||||
unittest.TextTestRunner(verbosity=2).run(s)
|
||||
# import cProfile
|
||||
# cProfile.run('unittest.TextTestRunner(verbosity=2).run(s)','profile.out')
|
||||
|
5236
waagent
5236
waagent
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -18,6 +18,8 @@
|
|||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import shutil
|
||||
import walinuxagent.logger as logger
|
||||
import walinuxagent.conf as conf
|
||||
|
@ -30,7 +32,11 @@ import walinuxagent.extension as ext
|
|||
|
||||
GuestAgentName = "WALinuxAgent"
|
||||
GuestAgentLongName = "Microsoft Azure Linux Agent"
|
||||
GuestAgentVersion = "WALinuxAgent-2.1.0-pre"
|
||||
GuestAgentVersion='2.1.0-pre'
|
||||
GuestAgentLongVersion = "{0}-{1}".format(GuestAgentName, GuestAgentVersion)
|
||||
GuestAgentAuthor='MS OSTC'
|
||||
GuestAgentUri='https://github.com/Azure/WALinuxAgent'
|
||||
|
||||
VmmConfigFileName = "linuxosconfiguration.xml"
|
||||
VmmStartupScriptName= "install"
|
||||
DataLossWarningFile="DATALOSS_WARNING_README.txt"
|
||||
|
@ -137,11 +143,11 @@ class Agent():
|
|||
def savePid(self):
|
||||
fileutil.SetFileContents(CurrOS.GetAgentPidPath(), str(os.getpid()))
|
||||
|
||||
def ParseArgs():
|
||||
def ParseArgs(sysArgv):
|
||||
cmd = None
|
||||
force = False
|
||||
verbose = False
|
||||
for a in sys.argv[1:]:
|
||||
for a in sysArgv:
|
||||
if re.match("^([-/]*)deprovision\+user", a):
|
||||
cmd = "deprovision+user"
|
||||
elif re.match("^([-/]*)deprovision", a):
|
||||
|
@ -152,21 +158,23 @@ def ParseArgs():
|
|||
cmd = "version"
|
||||
elif re.match("^([-/]*)serialconsole", a):
|
||||
cmd = "serialconsole"
|
||||
elif re.match("^([-/]*)(help|usage|\?)", a):
|
||||
cmd = "help"
|
||||
elif re.match("^([-/]*)verbose", a):
|
||||
verbose = True
|
||||
elif re.match("^([-/]*)force", a):
|
||||
force = True
|
||||
elif re.match("^([-/]*)(help|usage|\?)", a):
|
||||
cmd = "help"
|
||||
else:
|
||||
cmd = "help"
|
||||
return cmd, force, verbose
|
||||
|
||||
def Version():
|
||||
print "{0} running on {1} {2}".format(GuestAgentVersion,
|
||||
print "{0} running on {1} {2}".format(GuestAgentLongVersion,
|
||||
CurrOSInfo[0],
|
||||
CurrOSInfo[1])
|
||||
def Usage():
|
||||
print "usage: {0} [-verbose] [-force] "
|
||||
"[-help|-deprovision[+user]|-version|-serialconsole|-daemon]"
|
||||
print ("usage: {0} [-verbose] [-force] "
|
||||
"[-help|-deprovision[+user]|-version|-serialconsole|-daemon]")
|
||||
|
||||
def Deprovision(force=False, deluser=False):
|
||||
configPath = CurrOS.GetConfigurationPath()
|
||||
|
@ -175,7 +183,6 @@ def Deprovision(force=False, deluser=False):
|
|||
print("WARNING! All SSH host key pairs will be deleted.")
|
||||
print("WARNING! Cached DHCP leases will be deleted.")
|
||||
CurrOS.OnDeprovisionStart()
|
||||
|
||||
delRootPasswd = config.getSwitch("Provisioning.DeleteRootPassword", False)
|
||||
if delRootPasswd:
|
||||
print("WARNING! root password will be disabled. "
|
||||
|
@ -200,13 +207,14 @@ def Deprovision(force=False, deluser=False):
|
|||
"/var/lib/dhcpcd", "/var/lib/dhcp")
|
||||
fileutil.RemoveFiles('/root/.bash_history', '/var/log/waagent.log')
|
||||
CurrOS.OnDeprovision()
|
||||
if ovf is not None and deluser
|
||||
|
||||
if ovf is not None and deluser:
|
||||
CurrOS.DeleteAccount(ovf.getUserName())
|
||||
|
||||
def Main():
|
||||
os.chdir(CurrOS.GetLibDir())
|
||||
logger.LoggerInit('/var/log/waagent.log', '/dev/console')
|
||||
command, force, verbose = ParseArgs()
|
||||
command, force, verbose = ParseArgs(sys.argv[1:])
|
||||
if command == "deprovision+user":
|
||||
Deprovision(force=force, deluser=True)
|
||||
elif command == "deprovision":
|
||||
|
@ -219,6 +227,7 @@ def Main():
|
|||
Version()
|
||||
elif command == "serialconsole":
|
||||
#TODO
|
||||
pass
|
||||
else:#command == 'help' or anything not supported
|
||||
Usage()
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
|
||||
import walinuxagent.utils.restutil as restutil
|
||||
from walinuxagent.protocol.contract import *
|
||||
from walinuxagent.protocol.common import *
|
||||
|
||||
class ProtocolV2(Protocol):
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class ProvisionHandler(object):
|
|||
if self.config.getSwitch("Provisioning.Enabled"):
|
||||
self._provision()
|
||||
else:
|
||||
#In some distro like Ubuntu, cloud init is used to do provision
|
||||
#In some distro like Ubuntu, cloud init does the provision
|
||||
#In this case, we need to wait the cloud init to complete
|
||||
#provision work and generate ssh host key
|
||||
CurrOS.WaitForSshHostKey()
|
||||
|
|
Загрузка…
Ссылка в новой задаче