{"id":26293747,"url":"https://github.com/veksh/ovfconf","last_synced_at":"2025-05-08T20:55:43.335Z","repository":{"id":211299852,"uuid":"43143647","full_name":"veksh/ovfconf","owner":"veksh","description":"Linux VM configuration with OVF (ovftool) and VMware vApp properties","archived":false,"fork":false,"pushed_at":"2019-11-05T16:22:04.000Z","size":51,"stargazers_count":22,"open_issues_count":0,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-31T18:08:41.487Z","etag":null,"topics":["ovf","ovf-environment","vmware"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/veksh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-09-25T13:24:31.000Z","updated_at":"2023-09-26T19:17:10.000Z","dependencies_parsed_at":"2023-12-07T17:57:28.144Z","dependency_job_id":null,"html_url":"https://github.com/veksh/ovfconf","commit_stats":null,"previous_names":["veksh/ovfconf"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veksh%2Fovfconf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veksh%2Fovfconf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veksh%2Fovfconf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/veksh%2Fovfconf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/veksh","download_url":"https://codeload.github.com/veksh/ovfconf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253149404,"owners_count":21861718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ovf","ovf-environment","vmware"],"created_at":"2025-03-15T02:30:20.322Z","updated_at":"2025-05-08T20:55:43.317Z","avatar_url":"https://github.com/veksh.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ovfconf\n\nSimple script to customize VM clones (or OVF template deployments) with new network\nsettings taken from OVF/vApp metadata\n\n# Overview\n\nOVF Environment is a way to pass arbitrary data to guest VM on power on, widely used to\ncustomize network parameters while deploying OVF templates. In form of \"vApp properties\"\nit could be also used to customize VM metadata in vCenter and to pass it to VM at startup.\nThis script reads that metadata and updates OS configuration if required. Script is short,\nrelatively easy to extend and not have external dependences like XML parsers, making it\neasy to integrate it in golden VM templates or OVF images.\n\nSee [OVF specification][ovf-spec] and William Lam [blog][lam-ovf-environment] for further\ndetails about OVF Environment, and VMware [blog post][vmware-ovf-blog] for some earlier\nexample of OS customization script.\n\n[ovf-spec]: http://dmtf.org/sites/default/files/standards/documents/DSP0243_1.1.1.pdf\n[lam-ovf-environment]: http://www.virtuallyghetto.com/2012/06/ovf-runtime-environment.html\n[vmware-ovf-blog]: http://blogs.vmware.com/vapp/2009/07/selfconfiguration-and-the-ovf-environment.html\n\n# Mode of operation and configuration changes\n\nScript is intended to be run at system startup to re-configure freshly deployed image or\nclone (but could be run later manually or be tried in test mode, see below). After getting\ndata from OVF environment it checks for hostname and IP address change. If changed, new IP\naddress and host name are set in\n- interface configuration file\n- hosts file\n- hostname config file\n- \"root\" user description in `/etc/passwd`\n- some application configs (sshd, nrpe, syslog-ng)\n\nOther optionally configurable vApp parameters include:\n- gateway IP address\n- DNS domain\n- DNS servers\n- NTP servers (ntpd and chrony are supported)\n- remote syslog server address (syslog-ng and rsyslogd are supported)\n- smarthost SMTP server address (for postfix)\n\nFinally, ssh host keys are erased (to be automatically regenerated for new host) and so\nclone is fully configured at the end of boot process.\n\nScript is tested on Suse Linux Enterprise (11.0 to 15.1) and CentOS 7 (and will refuse to run\nelsewhere) under VMWare ESXi 5.5 - 6.5 hypervisor. Changes to adapt it to other platforms will\nbe minimal, and there is a special \"test\" mode to check effects on copy of \"/etc\" (see\nsource and \"test\" directory).\n\nIt is safe to run this script at every startup: if environment is not changed (or not\navailable for some reason) no changes are performed.\n\n# Installation\n\nJust copy `ovfconf` script to `/usr/local/sbin` and install startup scripts:\n- centos 7, sles 12\n\n        cp ovfconf /usr/local/sbin/\n        cp ovfconf.service /etc/systemd/system/\n        systemctl enable ovfconf.service\n\n- sles 11\n\n        cp ovfconf /usr/local/sbin/\n        cp boot.ovfconf /etc/init.d/\n        chkconfig boot.ovfconf on\n\nExample RPM spec for SLES 11 is also provided.\n\nThere are no requirements except `perl`, `open-vm-tools` (classic Vmware Tools will do too)\nand usual system tools like `sed`.\n\n# VM and vCenter configuration\n\n## vCenter: optional network profile\n\nTo simplify cloning between data centers, \"network profile\" could be assigned to main VM\nadministrative network (later referred as \"adm-vm\"). Settings for subnet mask, gateway,\nDNS servers could be obtained from that profile. To configure it, go to \"Networking\"\nsection of vCenter administrative interface, select \"adm-vm\" and associate network profile\nwith it with multi-step wizard:\n- name: \"adm-vm ip profile\"\n- configure subnet and gateway, no DHCP, configure DNS server addresses, no ip pool\n    - dns is specified as \"10.0.128.1, 10.0.128.2\" but passed w/o space in OVF env\n    - possible separators are comma, semicolon on space\n- skip ipv6\n- configure DNS domain, no host prefix, search domain is same as, no proxy\n\nAfter that, some properties like \"gateway\" could be replaced with their \"dynamic\"\nversions: instead of \"static String\" dynamic \"Gateway from \u003cnet\u003e\" could be used.\n\n## vApp properties\n\nConfigure properties metadata for vApp before cloning: on VM settings in vCenter go to\nlast page (\"vApp options\"), enable them. Proceed to create metadata as follows (do not\nforget to specify current values as defaults, or VM will be reconfigured at startup):\n- Ensure ip allocation policy = \"manual\"\n- Expand \"Properties\", add our props (set \"Category\" and \"Label\", do not change rest)\n    - Category `name`: mandatory\n        - `hostname`: static \"String\" 3-30, default: current hostname\n        - `domain`: static \"String\" 5-50, default: current DNS domain name\n           - or dynamic \"Domain name\" from \"adm-vm\" network\n    - Category `address`: mandatory\n        - `ip`: static \"vApp IP address\" in \"adm-vm\", default: current IP\n        - `gateway`: dynamic \"Gateway from adm-vm\" or static \"vApp IP address\" in\n          \"adm-vm\", default: current GW\n    - Category `services`: optional; will be kept untouched if not used\n        - `dns`: dynamic \"DNS servers\" from \"adm-vm\"\n        - `ntp`: static String 5-50, default: current NTP servers, comma-separated\n           (there is no ntp property in network profile)\n        - `syslog`: static String 5-30, default: current syslog server IP or name\n            - \"External IP Address\" would be better, but there is no \"default value\" field\n              for it in 5.5 for some reason\n        - `relay`: static String 5-50, default: current smarthost\n- \"IP Allocation\": scheme \"OVF environment\", \"IPv4\"\n- \"Autoring\"/\"OVF Environment transport\": check \"VMware Tools\"\n\nManual creation of properties in OVF template is possible too, but usually it is easier to\nconfigure them in vCenter and export template with `ovftool` (see below). Usually exported\ntemplate requires a bit of manual customization, but most things work.\n\n# VM deployment scenarios\n\n## General preparation\n\nBetter power off VM before cloning. If \"host file\" is connected to CD-ROM disconnect it\nbefore cloning or copy of this file will be created. Better enable DSA key generation in\n`/etc/sysconfig/sshd` or older ssh clients will be unable to connect.\n\n## Cloning VMs in vCenter\n\nClone machine as usual, do not opt for \"customize OS\". On step 1e (\"Customize vApp\nproperties\"), enter new host name and IP address (and rest of params if moving to other\ndomain or network). Review configuration and power on VM.\n\nIf everything worked as expected, new IP address will be assigned and visible in vCenter\nshortly after boot. If something is amiss, VM will probably boot with old IP address and\nhostname (as exact copy of original), investigate log (`/tmp/ovfconf.log`) and retry.\n\n## Deploying OVF templates or cloning VMs with ovftool\n\n[`ovftool`][ovf-tool-doc] is command-line utility to work with VM images (not limited to\nOVF templates). It could be used to export VM to OVF image and import it again, and also\nto clone VMs, extract metadata and so on (see documentation for details), like this:\n- preview VM metadata and properties\n\n        ovftool vi://\u003cuser\u003e@\u003cvca\u003e/\u003cdatacenter\u003e/vm/\u003cvm-name\u003e\n\n- clone VM from one vCenter to another: only hostname and ip specified, rest of properties\n  assumed to be same (or come from network profile)\n\n        ovftool --name=new-vm \\\n          --datastore=host-storage1 --diskMode=thin \\\n          --network=adm-vm \\\n          --prop:\"hostname=new-vm\" \\\n          --prop:\"ip=1.2.3.4\" \\\n          vi://user@vca1/dc1/vm/template-vm \\\n          vi://alex@vca2/dc2/host/newhost.domain.com\n\nOne small caveat: `ovftool` does not work correctly when password contains special\nsymbols that require HTML escaping, so try to use alphanumeric passwords (\"-\" is ok too).\n\n[ovf-tool-doc]: https://www.vmware.com/support/developer/ovf/\n\n## Injecting OVF environment inside VM config file\n\nDeploying OVF to standalone ESXi host with `ovftool` is not reliable: even with\n`--X:injectOvfEnv --powerOn` it sometimes fail to actually pass OVF info. This could be\nworked around with injecting OVF directly into VM config (I've found with idea in William\nLam [blog post][lam-ovf-injection]). Basically, one must\n- clone VM somehow (`ovftool` is easiest way)\n\n        ovftool --name=newvm \\\n          --X:logLevel=verbose --X:logFile=newvm.log \\\n          --datastore=host2-ds1 --diskMode=thin \\\n          --network=adm-srv \\\n          vi://root@oldhost/template-vm \\\n          vi://root@newhost/\n\n- perform basic customization like enabling VNC console (just in case)\n- prepare XML file (see \"Technical Details\" section for format description and example)\n- convert it to one long line by escaping double-quote to \"|22\", newline to \"|0A\":\n\n        cat ovfEnv.newvm.xml | perl -ane '$_ =~ s/\"/|22/g; $_ =~ s/\\n/|0A/g; print'\n\n- add `guestinfo.ovfEnv = \"\u003cthat blob\"\u003e` into `\u003cvm\u003e.vmx`\n- `vim-cmd vmsvc/reload \u003cvm\u003e` and start VM\n\n[lam-ovf-injection]: http://www.virtuallyghetto.com/2014/06/an-alternate-way-to-inject-ovf-properties-when-deploying-virtual-appliances-directly-onto-esxi.html\n\n# Technical details on operation, XML data format\n\nTo get OVF environment from hypervisor script calls `vmware-rpctool 'info-get\nguestinfo.ovfEnv'` producing XML like\n\n    \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n    \u003cEnvironment\n         xmlns=\"http://schemas.dmtf.org/ovf/environment/1\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns:oe=\"http://schemas.dmtf.org/ovf/environment/1\"\n         xmlns:ve=\"http://www.vmware.com/schema/ovfenv\"\n         oe:id=\"\"\n         ve:vCenterId=\"vm-136\"\u003e\n       \u003cPlatformSection\u003e\n          \u003cKind\u003eVMware ESXi\u003c/Kind\u003e\n          \u003cVersion\u003e5.5.0\u003c/Version\u003e\n          \u003cVendor\u003eVMware, Inc.\u003c/Vendor\u003e\n          \u003cLocale\u003een\u003c/Locale\u003e\n       \u003c/PlatformSection\u003e\n       \u003cPropertySection\u003e\n             \u003cProperty oe:key=\"dns\" oe:value=\"1.2.3.1,1.2.3.2\"/\u003e\n             \u003cProperty oe:key=\"domain\" oe:value=\"domain.com\"/\u003e\n             \u003cProperty oe:key=\"gateway\" oe:value=\"1.1.1.254\"/\u003e\n             \u003cProperty oe:key=\"hostname\" oe:value=\"testvm1\"/\u003e\n             \u003cProperty oe:key=\"ip\" oe:value=\"1.1.1.1\"/\u003e\n             \u003cProperty oe:key=\"ntp\" oe:value=\"ntp1.domain.com, ntp2.domain.com\"/\u003e\n             \u003cProperty oe:key=\"relay\" oe:value=\"smtp.domain.com\"/\u003e\n             \u003cProperty oe:key=\"syslog\" oe:value=\"log.domain.com\"/\u003e\n       \u003c/PropertySection\u003e\n       \u003cve:EthernetAdapterSection\u003e\n          \u003cve:Adapter ve:mac=\"00:50:56:90:1f:50\" ve:network=\"adm-vm\" ve:unitNumber=\"7\"/\u003e\n       \u003c/ve:EthernetAdapterSection\u003e\n    \u003c/Environment\u003e\n\nValues for configuration parameters are then extracted and compared with current settings,\nand configs are changed when necessary.\n\nOn every boot copy of that XML will be created in `/tmp/ovfEnv.xml` (this could be used as\na template for customization or as debugging aid), log of activity is in `/tmp/ovfconf.log`.\n\n# Limitations\n\n- only one interface is supported\n- no ipv6 support\n- untested on redhat/centos 6.x, sles 12 etc\n- only some hard-coded apps and services are supported\n- has some assumptions about configuraton file formats\n- configuration parametrs (like log file name) are hard-coded too\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveksh%2Fovfconf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fveksh%2Fovfconf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fveksh%2Fovfconf/lists"}