hi all,
I am trying to write a customizationSpec from an xml input.
Although I am almost finished this it seems like it is way overcomplicated.
Is it possible to generate a sysprep file and pass the content into the customization task? I noticed there is an example of modifying a resourceElement containing a sysprep.inf which would be 100% ideal for what I am trying to do however it doesn't show how to use the resource element in the customize task?
ie
task = vm.customizeTask(resourceElement of sysprep.inf )
I have little need to convert to licenseDataMode customizationNetBIOSMode objects etc as this seems like defeating the purpose of what I am trying to achieve.
note because I am doing this for mass deployment simply setting the objects its not suitable as they need to be dynamically set and will be likely to be different for each server deployed.
server1 = customizationSpec1 (such as sysprep1.inf)
server2 = customizationSpec2 (such as sysprep2.inf)
server3 = customizationSpecx (such as sysprepx.inf)
Ok, I took the challenge and created a working example.
Lessons learned:
- You need the GobalIpSettings, even if there are empty
- You need adapterMapping with IP-Settings for each network card, even if the specific settings are already in the sysprep-text ***GRML***
- Don't forget the Licensing Model in the sysprep text :-):
[LicenseFilePrintData]
AutoMode = PerServer
AutoUsers = 10
- The error messages you get wiithin vCenter are not helpful. It helps a bit to increase the log level of vCenter (vsphere client => Administration => Logging => set to verbose ). The logfile location depend on the windows version, in w2k8 under c:\program data\vmware\vmware virtualcenter\logs
in w2k3 under %TMP%\vpxd\logs
Don't forget to reset the loglevel for production!!
At the end I finished with following code (don't be confused, it takes the fixed ip from sysprep. the commented IpGeneratorTypes did not work !?!?)
var sysprepMime = sysprepFile.getContentAsMimeAttachment();
var sysprepText = sysprepMime.content
System.debug("sysprep: " + sysprepText);
//create the custSpec objects
var custSpec = new VcCustomizationSpec();
System.debug("custSpec: " + custSpec);
var myVcCustomizationSysprepText = new VcCustomizationSysprepText() ;
System.debug("myVcCustomizationSysprepText: " + myVcCustomizationSysprepText);
myVcCustomizationSysprepText.value = sysprepText //from Resource element above
custSpec.identity = myVcCustomizationSysprepText;
System.debug("custSpec.identity: " + custSpec.identity);
//fill the mandatory GlobalIPSettings
var myVcCustomizationGlobalIPSettings = new VcCustomizationGlobalIPSettings() ;
custSpec.globalIPSettings = myVcCustomizationGlobalIPSettings;
System.debug("custSpec.globalIPSettings: " + custSpec.globalIPSettings);
//fill in the NIC-settings-map for one nic with unknownIPGenerator (IP-spec is in sysprep-text):
var mappingMap = new Array();
var myVcCustomizationAdapterMapping = new VcCustomizationAdapterMapping() ;
var myVcCustomizationIPSettings = new VcCustomizationIPSettings() ;
var myIpGenerator;
//myIpGenerator = new VcCustomizationUnknownIpGenerator() ;
//myIpGenerator = new VcCustomizationFixedIp();
//myIpGenerator.ipAddress = "1.2.3.4";
myIpGenerator = new VcCustomizationDhcpIpGenerator() ;
myVcCustomizationIPSettings.ip = myIpGenerator;
myVcCustomizationAdapterMapping.adapter = myVcCustomizationIPSettings;
System.debug("myVcCustomizationIPSettings.ip:" + myVcCustomizationIPSettings.ip);
System.debug("myVcCustomizationAdapterMapping.adapter: " + myVcCustomizationAdapterMapping.adapter);
mappingMap.push(myVcCustomizationAdapterMapping);
System.debug("mappingMap: " + mappingMap);
//adding map to custSpec
custSpec.nicSettingMap = mappingMap;
vmToCustomize.customizeVM_Task(custSpec);
It works as long a the VM has only one nic (otherwise you have to add more adapterSettings to the NicMappingMap...).
You can download the full example here: http://www.vcoportal.de/download/workflow/customizeVM.workflow
Regards,
Joerg
Hi!
If I remember right, there is a attribute for the cutomization spec where you can define that you have an answer file.
But I'm not sure if it's possible to change any values in the CustomizationSpec afterwards when you are using a file.
So maybe you have to generate the different sysprep.inf-files programmatically.
It's in the CustomizationSpec.identity => CustomizationIdentitySettings => CustomizationSysprepText
Regards,
Joerg
I found this which seems ok. I will just generate the sysprep.inf as you mentioned.
var spec = new VimCustomizationSysprepText();
spec.value = strTemplate;
ok so I have been through the pain of using the
getCustomizationSpecSysprepText action.
This returns a type of VimCustomizationSysprepText
As it turns out the vm method only accepts VimCustomizationSysprep as an input
vm.customizeVM_Task(customizationSpec of type VimCustomizationSysprep);
I figured there would be some form of serialization to get the correct object type but this is the result.
[2011-04-29 14:54:40.637] [I] Cannot convert com.vmware.vim.vi35.CustomizationSysprepText@2ce9bf5a to com.vmware.vim.vi35.CustomizationSpec (Workflow:Mass Deploy - with SysprepText / Do Sysprep (item13)#4)
So my question is if there is a default action that creates one of these VimCustomizationSysprepText how do you implement / action this object
Hi!
I think you have to "combine" the proper objects manually..:
var myCustSpec = new VimCustomizationSpec();
myCustSpec.identity = myCustSpecText // from action
Are you working with vSphere4 or vCenter 3.5?
In 4 I think the classes are named different: VcCustomizationIdentitySettings and VcCustomizationSysprepText ;
Regards,
Joerg
i am working on vc 3.5 hence all my objects are vimXXX instead of vcXXX
cheers I will have a crack at this it makes sense.
ok so I tried that and it didn't work either.
Sysprep file looks ok after generation (some stuff ommitted for licensing / corporate reasons).
Unattended]
OemSkipEula=Yes
[GuiUnattended]
AdminPassword="hello"
EncryptedAdminPassword=NO
OEMSkipRegional=1
TimeZone=110
OemSkipWelcome=1
[UserData]
ProductID=xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
FullName="somewhere"
OrgName="RIP"
ComputerName=test
[SetupMgr]
DistFolder=C:\setup\Common\CommonSource\WIN2KSRVSR2SP2\Disk1\I386
DistShare=\\10.xx.xx.xx\johntest$
[Identification]
JoinDomain="blah blah blah"
DomainAdmin="blah"
DomainAdminPassword="blahblah"
[Networking]
InstallDefaultComponents=No
[NetAdapters]
Adapter1=params.Adapter1
[params.Adapter1]
INFID=*
[NetClients]
MS_MSClient=params.MS_MSClient
[NetServices]
MS_SERVER=params.MS_SERVER
[NetProtocols]
MS_TCPIP=params.MS_TCPIP
[params.MS_TCPIP]
DNS=No
UseDomainNameDevolution=No
EnableLMHosts=Yes
AdapterSections=params.MS_TCPIP.Adapter1
[params.MS_TCPIP.Adapter1]
SpecificTo=Adapter1
DHCP=No
IPAddress=10.xx.xx.xx
SubnetMask=255.255.255.0
DefaultGateway=10.xx.xx.x
DNSServerSearchOrder=10.xx.xxx.xxx,10.xx.xxx.xxx
WINS=No
NetBIOSOptions=0
so all is good there.
2011-04-29 16:48:14.221] [I] ; nested exception is:
java.io.IOException: java.io.IOException: Non nillable element 'globalIPSettings' is null. (Workflow:Mass Deploy - with SysprepText / Do sysprep (item13)#3)
so its basically saying all the other objects of the customizationSpec needs the other objects need to be setup, however in saying that as per the detail in the sysprep.inf most of those items are covered by that as well.
so somehow the .inf file must have to get split into the various parts of the spec object.
globalipsettings
identity
adaptermapping
etc
this whole customizationSpec is so complicated for what is typically a very simple admin task.
do you know of a picture view of the object model and any documents its quite hard to follow from the api doco due to the depth of the object schema.
hmm, answering via iPhone did not work 😞
Anyway, here is what I try to send before:
Indeed, the customization stuff is really "fully modeled", for some use cases a bit over-engineered 🙂
You can find some uml charts in steve jin's book about vsphere API.
I did a workaround to avoid all the spec stuff: I used the customization answer saved in vcenter. So you can use a wizard to fill all necessary infos. But not very generic,and it's complicated when you have more than one vcenter...
Now, that I'm on a real computer, the link to Steve's book and Blog:
http://www.amazon.com/VMware-VI-vSphere-SDK-Infrastructure/dp/0137153635
edit: forgot to mention: All this complexity of course is not an Orchestrator issue! It's part of the vSphere API, so you have to deal with it even when working with PowerCLI for instance. Maybe you can find some useful information also in their part of the forum, e.g. here:
http://communities.vmware.com/message/1496001
http://communities.vmware.com/thread/297748
Cheers,
Joerg
Ok, I took the challenge and created a working example.
Lessons learned:
- You need the GobalIpSettings, even if there are empty
- You need adapterMapping with IP-Settings for each network card, even if the specific settings are already in the sysprep-text ***GRML***
- Don't forget the Licensing Model in the sysprep text :-):
[LicenseFilePrintData]
AutoMode = PerServer
AutoUsers = 10
- The error messages you get wiithin vCenter are not helpful. It helps a bit to increase the log level of vCenter (vsphere client => Administration => Logging => set to verbose ). The logfile location depend on the windows version, in w2k8 under c:\program data\vmware\vmware virtualcenter\logs
in w2k3 under %TMP%\vpxd\logs
Don't forget to reset the loglevel for production!!
At the end I finished with following code (don't be confused, it takes the fixed ip from sysprep. the commented IpGeneratorTypes did not work !?!?)
var sysprepMime = sysprepFile.getContentAsMimeAttachment();
var sysprepText = sysprepMime.content
System.debug("sysprep: " + sysprepText);
//create the custSpec objects
var custSpec = new VcCustomizationSpec();
System.debug("custSpec: " + custSpec);
var myVcCustomizationSysprepText = new VcCustomizationSysprepText() ;
System.debug("myVcCustomizationSysprepText: " + myVcCustomizationSysprepText);
myVcCustomizationSysprepText.value = sysprepText //from Resource element above
custSpec.identity = myVcCustomizationSysprepText;
System.debug("custSpec.identity: " + custSpec.identity);
//fill the mandatory GlobalIPSettings
var myVcCustomizationGlobalIPSettings = new VcCustomizationGlobalIPSettings() ;
custSpec.globalIPSettings = myVcCustomizationGlobalIPSettings;
System.debug("custSpec.globalIPSettings: " + custSpec.globalIPSettings);
//fill in the NIC-settings-map for one nic with unknownIPGenerator (IP-spec is in sysprep-text):
var mappingMap = new Array();
var myVcCustomizationAdapterMapping = new VcCustomizationAdapterMapping() ;
var myVcCustomizationIPSettings = new VcCustomizationIPSettings() ;
var myIpGenerator;
//myIpGenerator = new VcCustomizationUnknownIpGenerator() ;
//myIpGenerator = new VcCustomizationFixedIp();
//myIpGenerator.ipAddress = "1.2.3.4";
myIpGenerator = new VcCustomizationDhcpIpGenerator() ;
myVcCustomizationIPSettings.ip = myIpGenerator;
myVcCustomizationAdapterMapping.adapter = myVcCustomizationIPSettings;
System.debug("myVcCustomizationIPSettings.ip:" + myVcCustomizationIPSettings.ip);
System.debug("myVcCustomizationAdapterMapping.adapter: " + myVcCustomizationAdapterMapping.adapter);
mappingMap.push(myVcCustomizationAdapterMapping);
System.debug("mappingMap: " + mappingMap);
//adding map to custSpec
custSpec.nicSettingMap = mappingMap;
vmToCustomize.customizeVM_Task(custSpec);
It works as long a the VM has only one nic (otherwise you have to add more adapterSettings to the NicMappingMap...).
You can download the full example here: http://www.vcoportal.de/download/workflow/customizeVM.workflow
Regards,
Joerg
aha .. great stuff.
yeah it took me a long while too work out the model. I think I have it pretty sorted without the sysprep but it caved my head in for a few days. 😉
I still think I prefer the resource element for a large chunk of the work. its a shame it doesn't handle the adapter mapping object serialisation from the syspreptext as that would of made the entire job quite simple.
thank you very much for your help here, i have a few vm books arriving this week I believe one of them is the one you mentioned above.
the uml charts are like gold I was almost there but this just cleared up the entire picture.
cheers.
oops I missed your last line about the nic details actually being used.
I will try this monday.
Is the referenced example stil valid/available? I've downloaded, but the zip contains 3 files. Neither the zip nor the contained files import as a workflow/package or other vCO content.
i can probably dig up the mass deployment workflows I did for this based on joerg's assistance.
what esx version are using using ? I should have 3,4,5 packages floating around somewhere.
What .zip file are you referring to? http://www.vcoportal.de/download/workflow/customizeVM.workflow points to a workflow file that can be directly imported to vCO (right click on a folder in you workflow tree, select "import workflow"). Just make sure that your windows system does not rename the file to .zip (because technically it is a .zip file)
Cheers,
Joerg