├── LICENSE ├── README.md ├── install-unifi └── install-unifi.sh └── rc.d └── unifi.sh /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, John Burwell 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | unifi-controller-freebsd-freenas 2 | ============= 3 | 4 | A shell script package that provides the UniFi Controller software. 5 | 6 | Purpose 7 | ------- 8 | 9 | The objective of this project is to develop and maintain a package that provides [Ubiquiti's](http://www.ubnt.com/) UniFi Controller software for the FreeBSD-based jail. Current stable version 5.5.20 10 | 11 | Status 12 | ------ 13 | 14 | The project now provides two working scripts: an rc script to start and stop the UniFi controller, and an installation script to automatically download and install everything, including the rc script. 15 | 16 | Upgrade 17 | ------- 18 | Upgrade to current is working to 5.5.20 (possibly) 19 | 20 | Milestones 21 | ---------- 22 | 23 | Installs snappy java after Unifi Controller is installed to comply with new controller software. 24 | 25 | 26 | 27 | Challenges 28 | ---------- 29 | 30 | 31 | Licensing 32 | --------- 33 | 34 | This project itself is licensed according to the two-clause BSD license. 35 | 36 | The UniFi Controller software is licensed as-is with no warranty, according to the README included with the software. 37 | 38 | [Ubiquiti has indicated via email](https://github.com/gozoinks/unifi-pfsense/wiki/Tacit-Approval) that acceptance of the EULA on the web site is not required before downloading the software. 39 | 40 | Installation 41 | ------------ 42 | 43 | To install the controller software and the rc script: 44 | 45 | 1. Log in to the jail command line shell as root. 46 | 2. Run this one-line command, which downloads the install script from Github and executes it with sh or copy install_unifi.sh file to new file and sh ./filename.sh and your controller will be running when complete. 47 | 48 | ``` 49 | fetch -o install-unifi.sh https://raw.githubusercontent.com/TechButton/unifi-controller-freebsd-freenas/master/install-unifi/install-unifi.sh 50 | ``` 51 | Or 52 | 53 | ``` 54 | Login with SSH to your FreeNAS (or alternatively go to shell in WebGUI) 55 | type: 'jls' (without ' ' ) and take the note of the # of jail of your Unifi installation 56 | type: jexec # csh' (where # is the number of the jail noted in last step) 57 | type: fetch -o install-unifi.sh https://raw.githubusercontent.com/TechButton/unifi-controller-freebsd-freenas/master/install-unifi/install-unifi.sh 58 | type: chmod 755 install-unifi.sh 59 | type: ./install-unifi.sh 60 | ``` 61 | 62 | 63 | The install script will install dependencies, download the UniFi controller software, make some adjustments, and start the UniFi controller. 64 | 65 | Starting and Stopping 66 | --------------------- 67 | 68 | To start and stop the controller, use the `service` command from the command line. 69 | 70 | - To start the controller: 71 | 72 | ``` 73 | service unifi.sh start 74 | ``` 75 | The UniFi controller takes a few minutes to start. The 'start' command exits immediately while the startup continues in the background. 76 | 77 | - To stop the controller: 78 | 79 | ``` 80 | service unifi.sh stop 81 | ``` 82 | The the stop command takes a while to execute, and then the shutdown continues for several minutes in the background. The rc script will wait until the command received and the shutdown is finished. The idea is to hold up system shutdown until the UniFi controller has a chance to exit cleanly. 83 | 84 | 85 | References 86 | ---------- 87 | Current Version 5.5.20 fixes 88 | https://community.ubnt.com/t5/UniFi-Updates-Blog/UniFi-5-5-20-Stable-has-been-released/ba-p/2011817 89 | Thanks to thecodemonk for your hard work, modified from https://github.com/thecodemonk/unifi-pfsense 90 | 91 | These sources of information immediately come to mind: 92 | 93 | - [UniFi product information page](http://www.ubnt.com/unifi#UnifiSoftware) 94 | - [UniFI download and documentation](http://www.ubnt.com/download#UniFi:AP) 95 | - [UniFi updates blog](http://community.ubnt.com/t5/UniFi-Updates-Blog/bg-p/Blog_UniFi) 96 | - [Unifi Stable build page] (https://community.ubnt.com/t5/UniFi/ct-p/UniFi) 97 | -------------------------------------------------------------------------------- /install-unifi/install-unifi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # install-unifi.sh 4 | # Installs the Uni-Fi controller software on a FreeBSD machine or FreeBSD Jail running on FreeNAS. 5 | 6 | # The latest version of UniFi: 7 | UNIFI_SOFTWARE_URL="https://dl.ubnt.com/unifi/5.8.28/UniFi.unix.zip" 8 | 9 | # The rc script associated with this branch or fork: 10 | RC_SCRIPT_URL="https://raw.githubusercontent.com/TechButton/unifi-controller-freebsd-freenas/master/rc.d/unifi.sh" 11 | 12 | # If pkg-ng is not yet installed, bootstrap it: 13 | if ! /usr/sbin/pkg -N 2> /dev/null; then 14 | echo "FreeBSD pkgng not installed. Installing..." 15 | env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap 16 | echo " done." 17 | fi 18 | 19 | # If installation failed, exit: 20 | if ! /usr/sbin/pkg -N 2> /dev/null; then 21 | echo "ERROR: pkgng installation failed. Exiting." 22 | exit 1 23 | fi 24 | 25 | # Stop the controller if it's already running... 26 | # First let's try the rc script if it exists: 27 | if [ -f /usr/local/etc/rc.d/unifi.sh ]; then 28 | echo -n "Stopping the unifi service..." 29 | /usr/sbin/service unifi.sh stop 30 | echo " done." 31 | fi 32 | 33 | # Then to be doubly sure, let's make sure ace.jar isn't running for some other reason: 34 | if [ $(ps ax | grep -c "/usr/local/UniFi/lib/[a]ce.jar start") -ne 0 ]; then 35 | echo -n "Killing ace.jar process..." 36 | /bin/kill -15 `ps ax | grep "/usr/local/UniFi/lib/[a]ce.jar start" | awk '{ print $1 }'` 37 | echo " done." 38 | fi 39 | 40 | # And then make sure mongodb doesn't have the db file open: 41 | if [ $(ps ax | grep -c "/usr/local/UniFi/data/[d]b") -ne 0 ]; then 42 | echo -n "Killing mongod process..." 43 | /bin/kill -15 `ps ax | grep "/usr/local/UniFi/data/[d]b" | awk '{ print $1 }'` 44 | echo " done." 45 | fi 46 | 47 | # If an installation exists, we'll need to back up configuration: 48 | if [ -d /usr/local/UniFi/data ]; then 49 | echo "Backing up UniFi data..." 50 | BACKUPFILE=/var/backups/unifi-`date +"%Y%m%d_%H%M%S"`.tgz 51 | /usr/bin/tar -vczf ${BACKUPFILE} /usr/local/UniFi/data 52 | fi 53 | 54 | # Add the fstab entries apparently required for OpenJDKse: 55 | if [ $(grep -c fdesc /etc/fstab) -eq 0 ]; then 56 | echo -n "Adding fdesc filesystem to /etc/fstab..." 57 | echo -e "fdesc\t\t\t/dev/fd\t\tfdescfs\trw\t\t0\t0" >> /etc/fstab 58 | echo " done." 59 | fi 60 | 61 | if [ $(grep -c proc /etc/fstab) -eq 0 ]; then 62 | echo -n "Adding procfs filesystem to /etc/fstab..." 63 | echo -e "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0" >> /etc/fstab 64 | echo " done." 65 | fi 66 | 67 | # Run mount to mount the two new filesystems: 68 | echo -n "Mounting new filesystems..." 69 | /sbin/mount -a 70 | echo " done." 71 | 72 | # Install mongodb, OpenJDK, and unzip (required to unpack Ubiquiti's download): 73 | # -F skips a package if it's already installed, without throwing an error. 74 | echo "Installing required packages..." 75 | env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install mongodb openjdk8 unzip pcre v8 snappy 76 | echo " done." 77 | 78 | # Switch to a temp directory for the Unifi download: 79 | cd `mktemp -d -t unifi` 80 | 81 | # Download the controller from Ubiquiti (assuming acceptance of the EULA): 82 | echo -n "Downloading the UniFi controller software..." 83 | /usr/bin/fetch ${UNIFI_SOFTWARE_URL} 84 | echo " done." 85 | 86 | # Unpack the archive into the /usr/local directory: 87 | # (the -o option overwrites the existing files without complaining) 88 | echo -n "Installing UniFi controller in /usr/local..." 89 | /usr/local/bin/unzip -o UniFi.unix.zip -d /usr/local 90 | echo " done." 91 | 92 | # Update Unifi's symbolic link for mongod to point to the version we just installed: 93 | echo -n "Updating mongod link..." 94 | /bin/ln -sf /usr/local/bin/mongod /usr/local/UniFi/bin/mongod 95 | echo " done." 96 | 97 | # Fetch the rc script from github: 98 | echo -n "Installing rc script..." 99 | /usr/bin/fetch -o /usr/local/etc/rc.d/unifi.sh ${RC_SCRIPT_URL} 100 | echo " done." 101 | 102 | # Fix permissions so it'll run 103 | chmod +x /usr/local/etc/rc.d/unifi.sh 104 | 105 | # Add the startup variable to rc.conf.local. 106 | # Eventually, this step will need to be folded into pfSense, which manages the main rc.conf. 107 | # In the following comparison, we expect the 'or' operator to short-circuit, to make sure the file exists and avoid grep throwing an error. 108 | if [ ! -f /etc/rc.conf.local ] || [ $(grep -c unifi_enable /etc/rc.conf.local) -eq 0 ]; then 109 | echo -n "Enabling the unifi service..." 110 | echo "unifi_enable=YES" >> /etc/rc.conf.local 111 | echo " done." 112 | fi 113 | 114 | # Restore the backup: 115 | if [ ! -z "${BACKUPFILE}" ] && [ -f ${BACKUPFILE} ]; then 116 | echo "Restoring UniFi data..." 117 | mv /usr/local/UniFi/data /usr/local/UniFi/data-orig 118 | /usr/bin/tar -vxzf ${BACKUPFILE} -C / 119 | fi 120 | #TODO - *Need to verify the current version of snappyjava* 121 | echo "Install snappy java" 122 | env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install snappyjava 123 | /bin/mv /usr/local/UniFi/lib/snappy-java-1.1.2.6.jar snappy-java-1.1.2.6.jar.bak 124 | /bin/ln -s /usr/local/share/java/classes/snappy-java.jar /usr/local/UniFi/lib/snappy-java-1.1.2.6.jar 125 | 126 | # Start it up: 127 | echo -n "Starting the unifi service..." 128 | /usr/sbin/service unifi.sh start 129 | echo " done." 130 | -------------------------------------------------------------------------------- /rc.d/unifi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # REQUIRE: FILESYSTEMS 4 | # REQUIRE: NETWORKING 5 | # PROVIDE: unifi 6 | 7 | . /etc/rc.subr 8 | 9 | name="unifi" 10 | rcvar="unifi_enable" 11 | start_cmd="unifi_start" 12 | stop_cmd="unifi_stop" 13 | 14 | pidfile="/var/run/${name}.pid" 15 | 16 | load_rc_config ${name} 17 | 18 | unifi_start() 19 | { 20 | if checkyesno ${rcvar}; then 21 | echo "Starting UniFi controller. " 22 | 23 | # Open up netcat to listen on port 8080, and then close the connection immediately, then quit. 24 | # This works around the long startup delay. Thanks to gcohen55. 25 | echo "" | nc -l 127.0.0.1 8080 >/dev/null & 26 | 27 | # The process will run until it is terminated and does not fork on its own. 28 | # So we start it in the background and stash the pid: 29 | /usr/local/bin/java -jar /usr/local/UniFi/lib/ace.jar start & 30 | echo $! > $pidfile 31 | 32 | fi 33 | } 34 | 35 | unifi_stop() 36 | { 37 | 38 | if [ -f $pidfile ]; then 39 | echo -n "Signaling the UniFi controller to stop..." 40 | 41 | # This process does take a while, but the stop command finishes before 42 | # the service is actually stopped. So we start it in the background: 43 | /usr/local/bin/java -jar /usr/local/UniFi/lib/ace.jar stop & 44 | 45 | # Get the pid of the stopper: 46 | stopper=$! 47 | 48 | # Wait until the stopper finishes: 49 | while [ `pgrep $stopper` ]; do 50 | echo -n "." 51 | sleep 5 52 | done 53 | 54 | echo " acknowledged." 55 | echo -n "Waiting for the UniFi controller to stop (this can take a long time)..." 56 | 57 | # ...then we wait until the service identified by the pid file goes away: 58 | while [ `pgrep -F $pidfile` ]; do 59 | echo -n "." 60 | sleep 5 61 | done 62 | 63 | # Remove the pid file: 64 | rm $pidfile 65 | 66 | echo " stopped."; 67 | else 68 | echo "There is no pid file. The controller may not be running." 69 | fi 70 | } 71 | 72 | run_rc_command "$1" 73 | --------------------------------------------------------------------------------