├── .DS_Store ├── README.md ├── files ├── krb5.conf └── smb.conf └── scripts ├── linux-agent-installer.sh └── optimize.sh /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatvirtualboy/horizon-linux-vm/5df4a1cdc150e87b17fb43dc4d855a9ecca1eb38/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Horizon Linux VM 2 | Optimized Ubuntu Template for VMware Horizon 7 3 | 4 | ![Ubuntu 14.04.4 LTS](https://img.shields.io/badge/Ubuntu-18.04.4-orange) 5 | [![Published VMware Fling](https://img.shields.io/badge/VMware-Fling-blue)](https://labs.vmware.com/flings/horizon-ova-for-ubuntu) 6 | [![Tip Me via PayPal](https://img.shields.io/badge/PayPal-tip%20me-green.svg?logo=paypal)](https://www.paypal.me/phiredrop) 7 | [![Twitter Follow](https://img.shields.io/twitter/follow/thatvirtualboy?style=social)](https://twitter.com/thatvirtualboy) 8 | 9 | ### This project is [published as a VMware Fling](https://labs.vmware.com/flings/horizon-ova-for-ubuntu). Please visit the Flings site to get the latest OVA. 10 | 11 | Ubuntu Desktop is the perfect Virtual Desktop Infrastructure (VDI) alternative to Windows for VDI Admins who are looking to move away from a Windows-centric desktop delivery. With an infrastructure utilizing VMware Horizon 7, this pre-packaged OVA aims to ease the setup and configuration of a Ubuntu Template VM, especially for Windows Admins that aren’t familiar with a Linux desktop. 12 | 13 | ### Ubuntu Gnome in the Horizon Client (recommended) 14 |

15 | 16 | ### Ubuntu + Plasma Desktop in the Horizon Client 17 |

18 | 19 | ### Ubuntu + MATE Desktop in the Horizon Client 20 |

21 | 22 | ## Join the conversation 23 | Come say hi on Slack and engage with the community over at [VMware {CODE}](https://code.vmware.com/web/code/join). You can find us at our new channel [#ubuntu-ova-for-horizon](https://vmwarecode.slack.com/archives/CV56WUL84) 24 | 25 | ## Details 26 | 27 | ### Preconfigured Ubuntu OVA 28 | * Base image is Ubuntu 18.04.4 LTS x64 built from mini.iso for minimal footprint 29 | * VMware HW v14 (requires vSphere 6.7+) 30 | * Configured for 2D Graphics Settings 31 | * Default username/password is viewadmin/viewadmin 32 | * The VM includes the `optimize.sh` script which configures VM to Best Practices per Horizon 7 Documentation & joins the domain 33 | * The VM includes the `linux-agent-install.sh` script to install the Horizon Agent and configure USB 3.0 Redirection 34 | * Additional system tweaks and applications may be necessary for your needs. 35 | * Due to licensing limitations, the Horizon Agent is NOT included in this OVA. It must be downloaded manually after completing the optimization script. 36 | 37 | ## Instructions 38 | 39 | ### Steps: 40 | 1. [Download](https://labs.vmware.com/flings/horizon-ova-for-ubuntu) the pre packaged OVA & deploy to your datacenter 41 | 2. Boot the VM and ensure you get a valid IP and can reach the internet (you can use `sudo dhclient` to use DHCP) 42 | 3. Open a console to the VM and login as viewadmin/viewadmin 43 | 4. Open Terminal and type
`sudo apt-get update && sudo apt-get upgrade` 44 | 5. Install all available updates and reboot if prompted 45 | 6. Open Terminal and type
`su root -c ./optimize.sh` 46 | 7. Enter the root password (viewadmin) 47 | 8. Follow the prompts 48 | 49 | Once complete, you'll want to finish customizing your template to your needs before installing the Horizon Agent (e.g., configure SSO, configure 3D/NVIDIA GRID requirements, etc). See the Official VMware Linux Desktop Guide [here](https://docs.vmware.com/en/VMware-Horizon-7/7.11/linux-desktops-setup.pdf). 50 | 51 | After completing your customizations, you can manually install the Horizon Agent, or you can invoke the included _linux-agent-installer.sh_ script by typing `su root -c ./linux-agent-installer.sh` then proceed with building your pools. This script will install the Horizon Agent with default values, as well as prompt to enable USB 3.0 compatibility and redirection. 52 | 53 | ### Developer Desktop Package 54 | Choosing to install the Developer Desktop Package when prompted will install the following packages: 55 | 56 | * snapd 57 | * VSCode 58 | * Docker 59 | * Kind 60 | * Octant 61 | * zsh + ohmyzsh 62 | * NOTE: users will need to be added to `/etc/passwd` in order to set zsh as default shell 63 | 64 | NOTE: Enabling Developer Desktop Package requires you to add your subnet to _/etc/vmware/viewagent-custom.conf_ following the Horizon Agent install (e.g., `Subnet=10.10.100.1/24`) 65 | 66 | > For additional Developer-specific tweaks and detailed build guidance, see my colleague [Robert Guske's](https://twitter.com/vmw_rguske) excellent Horizon Linux Blog series [here](https://rguske.github.io/post/a-linux-development-desktop-with-vmware-horizon-part-i-horizon/) 67 | 68 | 69 | ## Changelog 70 | Version: 1.2 71 | 72 | * Special thanks to Robert Guske for testing & feedback 73 | * Support for Horizon 7.11 and 7.12 74 | * Support for vSphere 6.7+ 75 | * Updated OVA base image to Ubuntu 18.04.4 LTS 76 | * Updated Virtual Hardware to v14 77 | * Added option to configure static networking 78 | * Added support for USB 3.0 and USB Redirection (via linux-agent-installer.sh) 79 | * Added KDE Desktop Environment Option 80 | * Added Gnome Desktop Environment Option (recommended) 81 | * Developer Desktop Package option 82 | * Added Keyboard Layout Option 83 | * Added option to enable SSH 84 | * Removed runlevel 5 setting 85 | * Fixed MOTD prompt code 86 | * Disabled auto software updates 87 | * Removed greeter modifications to support SSO 88 | * Numerous improvements to script 89 | * Script renamed to 'optimize.sh' 90 | 91 | Version: 1.1.0 92 | 93 | * MATE Only Release 94 | * Increased vRAM to 128 MB instead of Automatic 95 | * Removed Audio Device 96 | * Updated default network device to VMXNET3 97 | * Updated repository for open-vm-tools to Ubuntu repo 98 | * Added Horizon 7.1 Agent Dependencies 99 | * Updated Dependency packages for Ubuntu 16.04 on Horizon 7.1 100 | * Agent installer script updated with Horizon 7.1 links 101 | * Updated Media Codec packages for Ubuntu 16.04 102 | * Updated MATE packages to Xenial 103 | * More reliable domain join 104 | * Password update optional 105 | * Timezone update optional 106 | * Option to change hostname 107 | * Desktop addons optional 108 | * Added retry attempts for failed wgets of smb and krb5 configuration files 109 | * Renamed ‘horizon-linux-installer.sh’ to ‘linux-agent-installer.sh 110 | 111 | Version: 1.0.0 112 | 113 | * Published as _Ubuntu OVA for Horizon_ on VMware Flings 114 | * Base updated to Ubuntu 16.04 LTS 115 | * Requires Horizon 7.0.3 or later 116 | 117 | Version: RC2 118 | 119 | * Horizon Agent installer script now available 120 | * Domain Join via Winbind is now optional to allow domain flexibility 121 | * Winbind default domain flag optional (previously set to false) 122 | * GNOME Flashback or MATE Desktop Environment option 123 | * OVA RAM increased to 2GB per best practice 124 | * OVA CPU increased to 2 vCPU per best practice 125 | * SVGA properties added to VMX per best practice 126 | * Disable LTS Upgrade Notification 127 | * Some script optimizations 128 | 129 | Version: RC1 130 | 131 | * Built from Ubuntu’s mini.iso for a minimal footprint 132 | * Installs the MATE desktop environment 133 | * Configures your Timezone 134 | * Updates admin (viewadmin) and root passwords 135 | * Configures DNS servers 136 | * Disables automatic Updates 137 | * Downloads and installs the latest Open VM Tools packages 138 | * Sets default run level to 5 139 | * Sets FQDN in /etc/hosts 140 | * Installs Horizon Agent dependencies 141 | * Installs Winbind 142 | * Configures krb5.conf 143 | * Configures smb.conf 144 | * Joins the domain 145 | * New user home directory config 146 | * Optimizes login screen for VDI 147 | * Remove guest login 148 | * Installs Drivers & Media Codecs 149 | * Currently only supports one domain controller 150 | * Support for 2D desktops only 151 | 152 | ## Key Considerations 153 | 154 | * Note your Active Directory may have different encryption type requirements. These can be modified in **krb5.conf** 155 | * After rebooting, you can run the command `wbinfo -g` to see your AD groups. This also confirms you are joined to the domain. 156 | * This script defaults the Winbind Separator to "+" in **smb.conf.** You can change it depending on your needs. More info [here](https://communities.vmware.com/docs/DOC-30246). 157 | * Using Winbind means each clone must re-join the domain after creation. You can create a local script on each clone to perform this, but it would require domain admin credentials in plaintext. In a production environment, it is recommended to remotely join your clones to the domain [using PowerCLI or SSH](https://docs.vmware.com/en/VMware-Horizon-7/7.11/linux-desktops-setup/GUID-314A1BC4-9670-4640-AE5E-98E8BA0E55C8.html?hWord=N4IghgNiBcIEYFcIGsQF8g). 158 | * Consider deleting the scripts from /home/viewadmin prior to creating your clones 159 | 160 | 161 | ## Troubleshooting 162 | 163 | ### Domain Join 164 | 165 | Joining the domain can fail for many reasons. You can try the below tests and review against the guide [here](https://thatvirtualboy.com/2016/09/27/deploying-linux-vdi-pools-with-horizon-7/#::Configure-Ubuntu-to-Integrate-with-Active-Directory). 166 | 167 | * If the VM failed to join the domain during the script, attempt manually joining again after the reboot. 168 | 169 | `kinit username@DOMAIN.COM` 170 | 171 | `klist` (to verify you received a ticket) 172 | 173 | `net ads join -U username%password` 174 | 175 | `net ads testjoin` (should say “Join is OK” if it worked) 176 | 177 | * If you consistently get the error `This operation is only allowed for the PDC of the domain` try 178 | 179 | `realm join -U username@DOMAIN.COM domaincontroller@domain.com` 180 | 181 | * Verify your **hosts**, **KRB5** and **SMB** configuration files reflect the correct addresses and IP addresses. 182 | 183 | * Verify there is no time drift between the Ubuntu VM and the DCs. You may need to reconfigure NTP or disable it. 184 | 185 | * Sometimes adding the DC to /etc/hosts can help nudge the domain join along 186 | 187 | ### Agent Status 188 | 189 | * If your Horizon Agent status is _Unreachable_ or _Waiting for Agent,_ review the official troubleshooting guide [here](https://docs.vmware.com/en/VMware-Horizon-7/7.0/com.vmware.horizon-view.linuxdesktops.doc/GUID-127FFC83-BD23-4A91-A074-480595DFB027.html). 190 | 191 | * Some environments may require you to add the Connection Server IP/FQDN to the **/etc/hosts** file. This is usually an environmental DNS issue. 192 | 193 | * Some environments may require you to add a search domain to _/etc/netplan/01-netcfg.yaml_ (e.g., `search: [corp.local]`) 194 | -------------------------------------------------------------------------------- /files/krb5.conf: -------------------------------------------------------------------------------- 1 | [libdefaults] 2 | ticket_lifetime = 600 3 | default_realm = YOURDOMAIN 4 | default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc rc4-hmac des-cbc-md5 5 | default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc rc4-hmac des-cbc-md5 6 | [realms] 7 | YOURDOMAIN = { 8 | kdc = IP of your AD 9 | default_domain = YOURDOMAIN 10 | } 11 | [domain_realm] 12 | .yourdomain = YOURDOMAIN 13 | yourdomain = YOURDOMAIN 14 | [kdc] 15 | profile = /etc/krb5kdc/kdc.conf 16 | [logging] 17 | kdc = FILE:/var/log/krb5kdc.log 18 | admin_server = FILE:/var/log/kadmin.log 19 | default = FILE:/var/log/krb5lib.log 20 | -------------------------------------------------------------------------------- /files/smb.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | workgroup = domainname 3 | password server = hostname of domain controller 4 | wins server = IP of wins server 5 | realm = DOMAIN 6 | security = ads 7 | idmap uid = 16777216-33554431 8 | idmap gid = 16777216-33554431 9 | template shell = /bin/bash 10 | winbind use default domain = false 11 | winbind offline logon = false 12 | winbind separator = + 13 | allow trusted domains = Yes 14 | -------------------------------------------------------------------------------- /scripts/linux-agent-installer.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Script for installing and configuring the VMware Horizon Agent for Linux + USB 3.0 with default values 4 | # 5 | # Please report any issues to Ryan on Twitter (@thatvirtualboy) or on VMware Flings 6 | # Changelog and source available at https://github.com/thatvirtualboy/horizon-linux-vm 7 | # www.thatvirtualboy.com 8 | # 9 | # 10 | # Changelog 11 | # v1.2 12 | # Updated links for Horizon 7.12 13 | # Added USB 3.0 and USB Redirection support 14 | 15 | # Check for root 16 | if [ "$(whoami)" != "root" ]; then 17 | echo 18 | echo -e "\e[31mOops! You must be root to continue! \n\e[0mPlease type: \e[36msu root -c ./linux-agent-installer.sh\e[0m" 19 | echo 20 | exit 1 21 | fi 22 | 23 | # Spinner 24 | function spinner { 25 | pid=$! 26 | i=0 27 | sp="/-\|" 28 | while kill -0 $pid 2>/dev/null 29 | do 30 | i=$(( (i+1) %4 )) 31 | printf "\r[${sp:$i:1}]" 32 | sleep .1 33 | done 34 | echo "" 35 | } 36 | 37 | 38 | # Prompt to download Horizon Agent 39 | clear 40 | echo "+--------------------------------------------------------------------+" 41 | echo "| You must first download the VMware Horizon 7.12 Agent for Linux |" 42 | echo "| before running this script. It will install the agent with default |" 43 | echo "| values. |" 44 | echo "| |" 45 | echo "| This script can also enable USB 3.0 support and USB Redirection. |" 46 | echo "| |" 47 | echo "| - Download: http://bit.ly/2T6fZQ0 |" 48 | echo "| - Place the downloaded file anywhere on this system |" 49 | echo "| - Invoke this script as root |" 50 | echo "| - Follow the prompts |" 51 | echo "| |" 52 | echo "| >>> VMware Flings <<< |" 53 | echo "+--------------------------------------------------------------------+" 54 | echo -e "\e[36m" 55 | read -p "Press any key to start..." -n1 -s 56 | echo -e "\e[0m" 57 | clear 58 | 59 | echo -e "\e[36m" 60 | read -e -p "Full path to downloaded VMware Horizon Agent file: " agentinstaller; 61 | echo -e "\e[0m" 62 | echo 63 | echo -e "\e[36m" 64 | read -p "System will now verify agent. Press [ENTER] to continue." -n1 -s 65 | echo -e "\e[0m" 66 | clear 67 | 68 | # Verify file 69 | if [ -f $agentinstaller ]; then 70 | echo -e "\e[36mUnpacking VMware Horizon View Agent for Linux...\e[0m" 71 | sleep 4 & spinner 72 | 73 | mkdir /tmp/hagentinstall 74 | tar -xzvf $agentinstaller -C /tmp/hagentinstall 75 | clear 76 | 77 | # Configure USB 3.0 and USB Redirection 78 | echo -e " ${ASK} \e[36mWould you like to enable USB 3.0 Support and USB Redirection?\e[0m" 79 | select yn in "Yes" "No"; do 80 | case $yn in 81 | Yes ) wget https://sourceforge.net/projects/usb-vhci/files/linux%20kernel%20module/vhci-hcd-1.15.tar.bz2 82 | sudo apt-get install make -y 83 | sudo apt-get install gcc -y 84 | sudo apt-get install libelf-dev -y 85 | tar -xzvf vhci-hcd-1.15.tar.gz 86 | cd vhci-hcd-1.15 87 | patch -p1 < /tmp/hagentinstall/VMware-horizonagent-linux-x86_64-*/resources/ vhci/patch/vhci.patch 88 | make clean && make && make install 89 | echo 90 | echo -e " ${INFO} \e[36mUSB 3.0 & Redirection enabled\e[0m" 91 | echo 92 | sleep 4 & spinner 93 | break;; 94 | No ) echo -e " ${INFO} \e[36mSkipping USB 3.0 & Redirection configuration\e[0m"; 95 | echo 96 | sleep 4 & spinner 97 | break;; 98 | esac 99 | done 100 | clear 101 | 102 | # Install Agent 103 | echo -e " ${INFO} \e[36mInovking agent installer...\e[0m" 104 | sleep 4 & spinner 105 | cd /tmp/hagentinstall/VMware-horizonagent-linux-x86_64-* 106 | ./install_viewagent.sh -A yes 107 | rc=$? 108 | else 109 | echo -e "\e[31mFile not found! Please verify your path and re-run this script.\e[0m" 110 | echo 111 | exit 1 112 | fi 113 | 114 | #figlet -f small VMware Flings 115 | # Header 116 | function printhead { 117 | clear 118 | printf $green"$header"$reset 119 | echo "" 120 | } 121 | 122 | 123 | # Display Header 124 | header='__ ____ __ _____ _ _ 125 | \ \ / | \/ __ ____ _ _ __ ___| ___| (_)_ __ __ _ ___ 126 | \ \ / /| |\/| \ \ /\ / / _` | __/ _ | |_ | | | _ \ / _` / __| 127 | \ V / | | | |\ V V | (_| | | | __| _| | | | | | | (_| \__ \ 128 | \_/ |_| |_| \_/\_/ \__,_|_| \___|_| |_|_|_| |_|\__, |___/ 129 | |___/' 130 | printhead 131 | echo " https://labs.vmware.com/flings/" 132 | echo 133 | echo 134 | echo 135 | echo -e "\e[36mHorizon Agent has been installed! See Horizon documentation for configuration options.\e[0m" 136 | echo 137 | echo -e "\e[31m" 138 | read -p "Press [ENTER] to reboot the VM..." 139 | echo -e "\e[0m" 140 | reboot 141 | -------------------------------------------------------------------------------- /scripts/optimize.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Horizon Optimizer for Linux by Ryan Klumph 4 | # Version: 1.2 5 | # Please report any issues to Ryan on Twitter (@thatvirtualboy) or on VMware Flings 6 | # Changelog and source available at https://github.com/thatvirtualboy/horizon-linux-vm 7 | # www.thatvirtualboy.com 8 | # 9 | 10 | # Changelog 11 | # v1.2 12 | # 13 | # Special thanks to Robert Guske for testing & feedback 14 | # Support for Horizon 7.11 and 7.12 15 | # Support for vSphere 6.7+ 16 | # Updated OVA base image to Ubuntu 18.04.4 LTS 17 | # Updated Virtual Hardware to v14 18 | # Added option to configure static networking 19 | # Added support for USB 3.0 and USB Redirection (via linux-agent-installer.sh) 20 | # Added KDE Desktop Environment Option 21 | # Added Gnome Desktop Environment Option (recommended) 22 | # Developer Desktop Package option 23 | # Added Keyboard Layout Option 24 | # Added option to enable SSH 25 | # Removed runlevel 5 setting 26 | # Fixed MOTD prompt code 27 | # Disabled auto software updates 28 | # Removed greeter modifications to support SSO 29 | # Numerous improvements to script 30 | # Script renamed to 'optimize.sh' 31 | # 32 | # v1.1.0 released May 17 2017 33 | # 34 | # MATE Only Release 35 | # Increased vRAM to 128 MB instead of Automatic 36 | # Removed Audio Device 37 | # Updated default network device to VMXNET3 38 | # Updated repository for open-vm-tools to Ubuntu repo 39 | # Added Horizon 7.1 Agent Dependencies 40 | # Updated Dependency packages for Ubuntu 16.04 on Horizon 7.1 41 | # Agent installer script updated with Horizon 7.1 links 42 | # Updated Media Codec packages for Ubuntu 16.04 43 | # Updated MATE packages to Xenial 44 | # More reliable domain join 45 | # Password update optional 46 | # Timezone update optional 47 | # Option to change hostname 48 | # Desktop addons optional 49 | # Added retry attempts for failed wgets of smb and krb5 configuration files 50 | # Renamed ‘horizon-linux-installer.sh’ to ‘linux-agent-installer.sh 51 | # 52 | # v1.0 GA Release Features 53 | # 54 | # Built from Ubuntu’s mini.iso for a minimal footprint 55 | # Configures your Timezone 56 | # Updates admin (viewadmin) and root passwords 57 | # Configures DNS Servers 58 | # Disables automatic updates (except for security updates) 59 | # Sets default run level to 5 60 | # Sets FQDN in /etc/hosts 61 | # Installs Horizon Agent dependencies 62 | # Installs Winbind 63 | # Configures krb5.conf 64 | # Configures smb.conf 65 | # New user home directory config 66 | # Optimizes login screen for VDI 67 | # Removes guest login 68 | # Installs Drivers & Media codecs 69 | # Domain Join is optional and occurs using Winbind. Other domain-join methods require manual configuration 70 | # Winbind default domain flag is optional (required for SSO) 71 | # Utilizes MATE DE (fork from GNOME 2) 72 | # OVA RAM configured for 2GB per best practice 73 | # OVA CPU configured for 2vCPU per best practice 74 | # OVA vRAM configured to 128 MB per best practice 75 | # SVGA properties configured to best practice 76 | # LTS Upgrade notifications disabled 77 | 78 | 79 | # Some Variables 80 | TICK="[$\e[92m√\e[0m]" 81 | CROSS="[!]" 82 | INFO="[i]" 83 | ASK="[\e[93m?\e[0m]" 84 | green='\e[32m' 85 | cyan='\e[36m' 86 | 87 | # Spinner 88 | function spinner { 89 | pid=$! 90 | i=0 91 | sp="/-\|" 92 | while kill -0 $pid 2>/dev/null 93 | do 94 | i=$(( (i+1) %4 )) 95 | printf "\r[${sp:$i:1}]" 96 | sleep .1 97 | done 98 | echo "" 99 | } 100 | 101 | # Header 102 | function printhead { 103 | clear 104 | printf $green"$header"$reset 105 | echo "" 106 | } 107 | 108 | 109 | # Display Header 110 | header='__ ____ __ _____ _ _ 111 | \ \ / | \/ __ ____ _ _ __ ___| ___| (_)_ __ __ _ ___ 112 | \ \ / /| |\/| \ \ /\ / / _` | __/ _ | |_ | | | _ \ / _` / __| 113 | \ V / | | | |\ V V | (_| | | | __| _| | | | | | | (_| \__ \ 114 | \_/ |_| |_| \_/\_/ \__,_|_| \___|_| |_|_|_| |_|\__, |___/ 115 | |___/' 116 | printhead 117 | echo "" 118 | printf $cyan"Checking system requirements...\n"$reset 119 | sleep 4 & spinner 120 | echo "" 121 | # Check for root 122 | if [ "$(whoami)" != "root" ]; then 123 | echo 124 | echo -e " ${CROSS} \e[31mOops! You must be root to continue! \n\e[0mPlease type: \e[36msu root -c ./optimize.sh\e[0m" 125 | echo 126 | exit 1 127 | else 128 | printf $green" Running as root. Great!\n"$reset 129 | echo "" 130 | fi 131 | 132 | # Check CPUs 133 | cpus="$(nproc)" 134 | if [[ "${cpus}" -lt 2 ]]; then 135 | echo "" 136 | printf $red"Attention: 2 to 4 CPUs recommended for best performance!\n"$reset 137 | printf $red"Current CPU: ("$((cpus))")\n"$reset 138 | anykey 139 | else 140 | printf $green" CPU for Ubuntu on Horizon OK! ("$((cpus))")\n"$reset 141 | echo 142 | fi 143 | 144 | # Check RAM 145 | ram="$(awk '/MemTotal/{print $2}' /proc/meminfo)" 146 | if [ "$ram" -lt "$((1*1002400))" ]; then 147 | echo 148 | printf $red"Attention: 2 GB RAM or more recommended for Ubuntu on Horizon!\n"$reset 149 | printf $red"Current RAM is: ("$((ram/1002400))" GB)\n"$reset 150 | anykey 151 | else 152 | printf $green" RAM for Ubuntu on Horizon OK! ("$((ram/1002400))" GB)\n"$reset 153 | echo 154 | fi 155 | 156 | # Check Network Settings 157 | if nc -zw1 vmware.com 443; 158 | then 159 | printf $green" Network Connection OK!\n"$reset 160 | else 161 | echo -e " ${CROSS} \e[31mI can't seem to get to the internet. You need a working Network connection to run this script.\e[0m" 162 | echo 163 | exit 1 164 | fi 165 | sleep 4 166 | 167 | clear 168 | echo "+--------------------------------------------------------------------+" 169 | echo "| This script will configure your Ubuntu Template for Horizon 7 |" 170 | echo "| with 2D graphics. It will also do the following: |" 171 | echo "| |" 172 | echo "| - Install Open VM Tools |" 173 | echo "| - Optimize a Desktop Environment |" 174 | echo "| - Set new passwords to UNIX (viewadmin) |" 175 | echo "| - Install Horizon Agent Dependencies |" 176 | echo "| - Join the domain (optional) |" 177 | echo "| - Other optimizations |" 178 | echo "| |" 179 | echo "| For a full list of changes and optimizations, |" 180 | echo "| please visit https://github.com/thatvirtualboy/horizon-linux-vm |" 181 | echo "| |" 182 | echo "| ** THIS SCRIPT IS NOT OFFICIALLY SUPPORTED BY VMWARE |" 183 | echo "| ** ENSURE YOU HAVE PROPER BACKUPS |" 184 | echo "| ** ENSURE SYSTEM IS FULLY UPDATED BEFORE INVOKING SCRIPT |" 185 | echo "| |" 186 | echo "| Thanks for using my fling! |" 187 | echo "| - @thatvirtualboy |" 188 | echo "| |" 189 | echo "| >>> VMware Flings <<< |" 190 | echo "+--------------------------------------------------------------------+" 191 | echo -e "\e[36m" 192 | read -p " Press any key to start..." -n1 -s 193 | echo -e "\e[0m" 194 | clear 195 | 196 | printhead 197 | 198 | domainProperties(){ 199 | # Configure Domain Properties 200 | echo 201 | read -p " [?] Please enter your domain (lowercase please. E.g., vcloud.local): " domainname; 202 | domainrealm=${domainname^^} 203 | echo 204 | sleep 2s 205 | read -p " [?] Please add a domain controller (shortname, lowercase. E.g., dcw2016): " domaincontroller; 206 | echo 207 | sleep 2s 208 | read -p " [?] What's your domain controller's IP address? " domaincontrollerip; 209 | echo 210 | sleep 2s 211 | read -p " [?] What's your WINS server IP address? " wins; 212 | echo 213 | sleep 2s 214 | read -p " [?] Enter a domain administrator (E.g., administrator): " domainadmin; 215 | sleep 2s 216 | #clear 217 | } 218 | 219 | # Configure keyboard layout 220 | echo -e " ${ASK}\e[36mThis template was configurd with a US Keyboard Layout. Would you like to change it? \e[0m" 221 | select yn in "Yes" "No"; do 222 | case $yn in 223 | Yes ) sudo dpkg-reconfigure keyboard-configuration 224 | break;; 225 | No ) echo -e " ${INFO} \e[36mMoving on...\e[0m"; 226 | sleep 2s 227 | break;; 228 | esac 229 | done 230 | clear 231 | printhead 232 | 233 | # Configure hostname 234 | hostn=$(cat /etc/hostname) 235 | 236 | # Display existing hostname 237 | echo -e " ${INFO}\e[36mExisting hostname is $hostn\e[0m" 238 | 239 | # Ask for new hostname 240 | echo -e " ${ASK} \e[36mWould you like to change your hostname? If you select yes you MUST NOT \e[0m" 241 | echo -e " \e[36mhave 'ubuntu' in the name. It will cause DNS issues. \e[0m" 242 | select cn in "Yes" "No"; do 243 | case $cn in 244 | Yes ) 245 | echo " ${INFO} Enter new hostname (shortname <15 chars, do NOT use 'ubuntu' in the name): " 246 | read newhost 247 | #change hostname in /etc/hosts & /etc/hostname 248 | sudo hostnamectl set-hostname $newhost 249 | sudo sed -i "s/$hostn/$newhost/g" /etc/hosts 250 | sudo sed -i "s/$hostn/$newhost/g" /etc/hostname 251 | #display new hostname 252 | echo -e " ${INFO} \e[36mYour new hostname is $newhost\e[0m" 253 | sleep 3s 254 | break;; 255 | No ) echo -e " ${INFO} \e[36mSkipping hostname configuration...\e[0m"; 256 | echo 257 | sleep 2s 258 | break;; 259 | esac 260 | done 261 | 262 | # Configure Networking 263 | clear 264 | printhead 265 | echo -e " ${ASK} \e[36mRight now your IP address is from DHCP. Would you like to configure static networking? (If you choose No, you must run 'sudo dhclient' after each reboot)\e[0m" 266 | select yn in "Yes" "No"; do 267 | case $yn in 268 | Yes ) 269 | read -p " ${INFO} Type your preferred IP Address and hit [ENTER] " staticip; read -p " ${INFO} Type your subnet mask in short form including the slash (e.g., /24) and hit [ENTER] " subnet; read -p " ${INFO} Type your Gateway IP and hit [ENTER] " gatewayip; read -p " ${INFO} Type your primary DNS server IP and hit [ENTER] " enterdns1; read -p " ${INFO} Type your secondary DNS server IP and hit [ENTER] " enterdns2; 270 | # create Netplan Config 271 | nic=`ifconfig | awk 'NR==1{print $1}'` 272 | sudo touch /etc/netplan/01-netcfg.yaml 273 | cat > /etc/netplan/01-netcfg.yaml <> /etc/hosts 321 | sudo timedatectl set-ntp off 322 | sudo apt-get install ntp -y 323 | echo 'server' $ntpserver 'prefer iburst' >> /etc/ntp.conf 324 | sudo service ntp restart 325 | break;; 326 | No ) echo -e " ${INFO} \e[36mSkipping NTP configuration...\e[0m"; 327 | echo 328 | sleep 2s 329 | break;; 330 | esac 331 | done 332 | clear 333 | printhead 334 | 335 | 336 | 337 | # Install Sudo 338 | aptitude install sudo -y &> /dev/null 339 | adduser viewadmin sudo &> /dev/null 340 | 341 | # Change Timezone // Only for OVA 342 | echo " ${INFO} Current Timezone is USA/Denver" 343 | echo -e " ${ASK} \e[36mWould you like to change your timezone?\e[0m" 344 | select an in "Yes" "No"; do 345 | case $an in 346 | Yes ) 347 | dpkg-reconfigure tzdata 348 | echo 349 | sleep 3 350 | clear 351 | printhead 352 | break;; 353 | No ) echo -e " ${INFO} \e[36mSkipping timezone configuration\e[0m"; 354 | echo 355 | sleep 2s 356 | break;; 357 | esac 358 | done 359 | clear 360 | printhead 361 | 362 | # Change password 363 | echo -e " ${ASK} \e[36mNow would be a good time to change some passwords. Would you like to change your default passwords? (Recommended)\e[0m" 364 | select bn in "Yes" "No"; do 365 | case $bn in 366 | Yes ) 367 | echo " ${INFO} The current password for viewadmin is [viewadmin]" 368 | echo -e "\e[36m" 369 | read -p " ${INFO} Press any key to change viewadmin's password... " -n1 -s 370 | echo -e "\e[0m" 371 | passwd viewadmin 372 | if [[ $? > 0 ]] 373 | then 374 | passwd viewadmin 375 | else 376 | sleep 2 377 | fi 378 | echo 379 | echo -e "\e[0m" 380 | echo " ${INFO} The current password for ROOT is [viewadmin]" 381 | echo -e "\e[36m" 382 | read -p " ${INFO} Press any key to change ROOT's password... " -n1 -s 383 | echo -e "\e[0m" 384 | passwd root 385 | if [[ $? > 0 ]] 386 | then 387 | passwd root 388 | else 389 | sleep 2 390 | fi 391 | echo 392 | echo -e "\e[0m" 393 | clear && printhead 394 | break;; 395 | No ) echo -e " ${INFO} \e[36mSkipping password configuration\e[0m"; 396 | echo 397 | sleep 2s 398 | break;; 399 | esac 400 | done 401 | clear 402 | printhead 403 | 404 | ########################################## 405 | # Install packages and perform OS Tweaks # 406 | ########################################## 407 | 408 | echo -e " \e[36mInitiating sublight thrusters sequence...\e[0m" 409 | echo 410 | sleep 2s 411 | 412 | # Install Open VM Tools and Kerberos 413 | apt-get update 414 | apt-get install open-vm-tools-desktop -y 415 | apt-get install krb5-locales -y 416 | 417 | # Install Media Codecs 418 | clear 419 | printhead 420 | echo -e " ${ASK} \e[36mWould you like to install Media Codecs and Desktop Applications? This makes the desktop more user-friendly. (gstreamer, libavcodec, unrar, ubuntu addons)\e[0m" 421 | select dn in "Yes" "No"; do 422 | case $dn in 423 | Yes ) 424 | apt-get install gstreamer1.0-plugins-good -y 425 | apt-get install libavcodec-extra -y 426 | apt-get install unrar -y 427 | apt-get install ubuntu-restricted-extras -y 428 | clear 429 | printhead 430 | break;; 431 | No ) echo -e " ${INFO} \e[36mSkipping desktop addons\e[0m"; 432 | echo 433 | sleep 2s 434 | break;; 435 | esac 436 | done 437 | 438 | clear 439 | printhead 440 | echo -e "\e[36m" 441 | echo " Performing additional optimizations..." 442 | echo -e "\e[0m" 443 | sleep 2s 444 | 445 | # Disable auto-suspend 446 | systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target 447 | 448 | # Disable LTS Upgrade MOTD 449 | sed -i '16 s/.*Prompt.*/Prompt=never/' /etc/update-manager/release-upgrades 450 | 451 | # Disable auto-updates 452 | sudo sed -i 's/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/' /etc/apt/apt.conf.d/20auto-upgrades 453 | 454 | 455 | # Update nsswitch 456 | sed -i '7 s/.*passwd:.*/passwd: compat winbind/' /etc/nsswitch.conf 457 | sed -i '9 s/.*shadow:.*/shadow: compat winbind/' /etc/nsswitch.conf 458 | sed -i '12 s/.*hosts:.*/hosts: cache db files dns/' /etc/nsswitch.conf 459 | 460 | # Enable home directory for new users 461 | echo 'session required pam_mkhomedir.so skel=/etc/skel/ umask=0022' >> /etc/pam.d/common-session 462 | 463 | # Install MATE desktop 464 | configureMATE(){ 465 | apt-get install ubuntu-mate-desktop -y 466 | apt-get install gdm3 -y 467 | 468 | } 469 | 470 | # Install GNOME desktop 471 | configureGNOME(){ 472 | apt-get install ubuntu-desktop -y 473 | } 474 | 475 | # Install K Desktop environment 476 | configureKDE(){ 477 | apt-get install kubuntu-desktop -y 478 | apt-get install gdm3 -y 479 | } 480 | 481 | # Install Winbind and configure Active Directory Integration 482 | winbind(){ 483 | apt-get install winbind libnss-winbind libpam-winbind -y 484 | wget --tries=3 https://raw.githubusercontent.com/thatvirtualboy/horizon-linux-vm/master/files/krb5.conf -O /etc/krb5.conf 485 | wget --tries=3 https://raw.githubusercontent.com/thatvirtualboy/horizon-linux-vm/master/files/smb.conf -O /etc/samba/smb.conf 486 | 487 | 488 | # Configure KRB5 489 | sed -i "3 s/.*default_realm.*/default_realm = ${domainname^^}/" /etc/krb5.conf 490 | sed -i "7 s/.*YOURDOMAIN.*/${domainname^^} = {/" /etc/krb5.conf 491 | sed -i "8 s/.*kdc.*/kdc = ${domaincontrollerip}/" /etc/krb5.conf 492 | sed -i "9 s/.*default_domain.*/default_domain = ${domainname^^}/" /etc/krb5.conf 493 | sed -i "12 s/.*.yourdomain.*/.${domainname,,} = ${domainname^^}/" /etc/krb5.conf 494 | sed -i "13 s/.*yourdomain.*/${domainname,,} = ${domainname^^}/" /etc/krb5.conf 495 | 496 | # Configure SMB 497 | sed -i "2 s/.*workgroup.*/workgroup = ${domainrealm%.*}/" /etc/samba/smb.conf 498 | sed -i "3 s/.*password.*/password server = ${domaincontroller,,}.${domainname,,}/" /etc/samba/smb.conf 499 | sed -i "4 s/.*wins.*/wins server = $wins/" /etc/samba/smb.conf 500 | sed -i "5 s/.*realm.*/realm = ${domainname^^}/" /etc/samba/smb.conf 501 | 502 | # Update Hosts file 503 | echo $domaincontrollerip $domaincontroller'.'$domainname $domaincontroller >> /etc/hosts 504 | 505 | # Update resolv 506 | echo 'nameserver ' $domaincontroller'.'$domainname >> /etc/resolv.conf 507 | 508 | clear 509 | printhead 510 | echo -e " ${ASK} \e[36mWould you like Winbind to use default domain? More info here: http://bit.ly/2eYWFl7\e[0m" 511 | select wn in "Yes" "No"; do 512 | case $wn in 513 | Yes ) 514 | sed -i "10 s/.*winbind.*/winbind use default domain = true/" /etc/samba/smb.conf 515 | break;; 516 | No ) break;; 517 | esac 518 | done 519 | 520 | service smbd restart 521 | service winbind restart 522 | 523 | # Install Kerberos & domain join 524 | apt-get install krb5-user -y 525 | clear 526 | printhead 527 | echo 528 | echo -e " ${INFO} \e[36mAttempting to join the domain...\e[0m" 529 | echo 530 | sleep 1s 531 | kinit $domainadmin'@'${domainname^^} 532 | net ads join -U $domainadmin'@'${domainname^^} 533 | net ads testjoin 534 | sleep 3s 535 | finish 536 | } 537 | 538 | # Perform cleanup 539 | finish(){ 540 | apt-get autoclean 541 | cat /dev/null > ~/.bash_history 542 | cat /dev/null > /var/log/horizon-optimizer.log 543 | clear 544 | printhead 545 | 546 | echo " https://labs.vmware.com/flings/" 547 | echo " https://thatvirtualboy.com" 548 | echo 549 | echo 550 | echo 551 | echo -e "\e[36m Your image has been optimized for Horizon 7!\e[0m" 552 | echo -e "\e[36m Additional configuration may be needed for AD and/or SSO.\e[0m" 553 | echo 554 | echo -e "\e[36m Next Steps: install desired apps, apply any customizations, and install the Horizon Agent.\e[0m" 555 | echo -e "\e[36m NOTE: The included 'linux-agent-installer.sh' script can assist in the agent install.\e[0m" 556 | 557 | echo 558 | echo -e "\e[31m" 559 | read -p "Press [ENTER] to reboot the VM..." 560 | echo -e "\e[0m" 561 | reboot 562 | } 563 | 564 | # Install Horizon Agent Dependencies 565 | apt-get install python -y 566 | apt-get install python-dbus -y 567 | apt-get install python-gobject -y 568 | 569 | 570 | # Choose DE 571 | clear 572 | printhead 573 | 574 | echo -e "\e[36m Choose a supported desktop session. Ubuntu Gnome is recommended and is the only DE\e[0m" 575 | echo -e "\e[36m that supports Session Collaboration (http://bit.ly/3927NWe).\e[0m" 576 | echo 577 | echo -e " ${INFO}\e[36m NOTE: MATE and KDE will prompt you for a default greeter.\e[0m" 578 | echo -e " \e[36m Select gdm3 (it's the only supported greeter for Ubuntu on Horizon).\e[0m" 579 | echo 580 | 581 | select knn in "GNOME" "MATE" "KDE" "None"; do 582 | case $knn in 583 | GNOME ) 584 | echo 585 | echo -e "\e[36mConfiguring GNOME Desktop Environment...\e[0m" 586 | echo 587 | sleep 2s 588 | configureGNOME 589 | break;; 590 | MATE ) 591 | echo 592 | echo -e "\e[36mConfiguring MATE Desktop Environment...\e[0m" 593 | echo 594 | sleep 2s 595 | configureMATE 596 | break;; 597 | KDE ) 598 | echo 599 | echo -e "\e[36mConfiguring Plasma Desktop Environment (KDE)...\e[0m" 600 | echo 601 | sleep 2s 602 | configureKDE 603 | break;; 604 | None ) 605 | echo 606 | echo -e "\e[36mSkipping installation of desktop environment...\e[0m" 607 | echo 608 | sleep 2s 609 | break;; 610 | esac 611 | done 612 | 613 | # Developer Desktop options 614 | clear 615 | printhead 616 | 617 | echo -e " ${INFO} \e[36mDo you want to install the Developer Desktop Package? See http://bit.ly/2VDsZhD for details.\e[0m" 618 | select dn in "Yes" "No"; do 619 | case $dn in 620 | Yes ) 621 | echo 622 | echo -e " \e[36mConfiguring Developer Desktop Package...\e[0m" 623 | apt-get install snapd -y 624 | snap install code --classic -y 625 | sudo apt install apt-transport-https ca-certificates curl software-properties-common -y 626 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 627 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" 628 | sudo apt update 629 | apt-cache policy docker-ce 630 | sudo apt install docker-ce -y 631 | sudo usermod -aG docker viewadmin 632 | curl -Lo ./kind "https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(uname)-amd64" 633 | chmod +x ./kind 634 | mv ./kind /some-dir-in-your-PATH/kind 635 | wget https://github.com/vmware-tanzu/octant/releases/download/v0.10.2/octant_0.10.2_Linux-64bit.deb 636 | dpkg -i octant_0.*.deb 637 | apt-get install zsh -y 638 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/thatvirtualboy/ohmyzsh/master/tools/install.sh)" 639 | break;; 640 | No ) 641 | echo -e " ${INFO} \e[36mSkipping Developer Desktop configuration...\e[0m"; 642 | sleep 2s 643 | break;; 644 | esac 645 | done 646 | 647 | # Prompt for SSH 648 | clear 649 | printhead 650 | echo -e " ${INFO} \e[36mWould you like to enable SSH? (This will NOT permit root login!)\e[0m" 651 | select dn in "Yes" "No"; do 652 | case $dn in 653 | Yes ) 654 | echo 655 | echo -e " \e[36mEnabling...\e[0m" 656 | echo 657 | apt-get install openssh-server -y 658 | sudo ufw allow ssh 659 | break;; 660 | No ) echo -e " ${INFO} \e[36mLeaving SSH disabled...\e[0m"; 661 | sleep 2s 662 | break;; 663 | esac 664 | done 665 | 666 | # Choose to join domain 667 | clear 668 | printhead 669 | 670 | echo -e " ${INFO} \e[36mConfiguring Active Directory Integration...\e[0m" 671 | echo 672 | echo -e " ${ASK} \e[36mDo you want to install Winbind and join the domain? If you choose No, you will need to manually configure Active Directory Integration later.\e[0m" 673 | select kn in "Yes" "No"; do 674 | case $kn in 675 | Yes ) 676 | domainProperties 677 | winbind 678 | break;; 679 | No ) 680 | finish 681 | break;; 682 | esac 683 | done 684 | sleep 2s 685 | --------------------------------------------------------------------------------