Automatic Shutdown/Wake Up on FreeNAS

In an attempt to conserve as much electricity as I can, I used some python scripting to automatically turn my FreeNAS server on and off as required. Requires programming knowledge.

WARNING: THIS POST ASSUMES SOME PROGRAMMING KNOWLEDGE, as you will have to tweak it to your own setup. If you aren’t able to generally figure out what is going on in this post, you shouldn’t try it. I take no responsibility to damage caused to your system! I wrote this post in a rush, so I may miss out basic steps.

In an attempt to conserve as much electricity as I can, I turn off my FreeNAS server whenever it’s not being used. Unfortunately, this was quite a tedious task to do manually. So, I used some scripting to automatically turn it on and off. The scripting for auto shutdown is done on the FreeNAS server, while auto wake up is done client-side.

Auto Shutdown

Using a cronjob, the FreeNAS server monitors a preset list of computers (via IP addresses). Once all the computers are off (i.e. no longer reachable on the network), it’ll turn itself off.

1) Create a file named shutdown.py with the following code: shutdown.py

2) Edit the IP addresses section with whichever computers you want to monitor in your network, e.g.:

###### IP addresses #####
# IP addresses go underneath this line, one on each line in the format: ip_list.append('x.x.x.x')
ip_list.append('192.168.1.2')
ip_list.append('192.168.1.3')
###### End IP addresses

3) Place the file somewhere on your server, and make sure it’s executable. You can make a file executable by SSH’ing into the FreeNAS server, and entering the command chmod +x /mnt/path/to/shutdown.py, changing /mnt/path/to/ to the directory that shutdown.py is in.

4) Create a cronjob to run the file. You can do this via the Web UI. For example, the following settings run the script every 5 minutes from 12am-5am. You can adjust this to your own liking.

Automatically Wake Up

Whenever any of the computers in the house are turned on, they send a Wake-on-LAN signal to the FreeNAS server and automatically mount the shares.

Mac OS

Python is required to run this script! Basically, these scripts will check every 3 minutes that the FreeNAS server is on, and that the network shares are mounted. If not, it will attempt to turn on the FreeNAS server (by sending WakeOnLAN) and mounting afp shares. Please feel free to edit the scripts as you see fit, or change the directories they are in, of course making the necessary changes.

1) Create the file com.hoongern.nasmounter.plist in /Users/<your username>/Library/LaunchAgents

2) Create the file nas.py in /Library/Scripts/. YOU HAVE TO EDIT the configuration in the script as required:

3) Restart your Mac. If I remember, launchctl should find the new task. You can run launchctl list and check if com.hoongern.nasmounter is listed. If it’s not, I can’t actually remember what to do. I don’t actually use Mac OS, you see…

Windows

To be honest, I haven’t written a script for Windows. Not that it should be hard at all – just use a similar python script, the Task Scheduler, and the “net use” command to mount Samba shares. If there’s enough interest, I can write it up and post it here – let me know!

Linux

Again, no script yet. Shouldn’t be difficult with a similar python script, cronjob, and the “mount” command to mount Samba/NFS shares.

31 thoughts on “Automatic Shutdown/Wake Up on FreeNAS”

    1. Yup, that’s one other way of doing it, by analyzing network activity =) I did actually look at it even before I started using FreeNAS. But personally, I like my network shares to be immediately accessible while my computers are on, hence me using ping instead. (And after all, my NAS power usage goes very low once the HDDs spin down)

  1. Hey this worked like a charm, thanks a lot!

    The only thing missing for me was the fact that I needed to prefix the command with the full path to python.

    I’m going to try and combine it with the network load script i found somewhere else, so it first checks if x computers are online, and then shutsdown when there is no significant traffic on the network port.

  2. i found the above script not to work on a freenas embedded system…..

    but found a script that uses sh script instead and works great on and embedded 8.3 freenas…..
    still using the cron job and set it to 15min or 10…. and running with sh then path to file… the below script works great for embedded..

    if [ “`id -u`” = “0” ]; then
    touch /var/log/check_if_up.log # Create log if not exist

    if [ `ls -la /var/log/check_if_up.log | awk ‘{print $5}’` -gt 1048576 ]; then
    mv /var/log/check_if_up.log /var/log/check_if_up.old # Backup log >1meg
    touch /var/log/check_if_up.log # Create a new log

    fi

    ping -c 4 -q 192.168.2.139 > /tmp/check_1.tmp # Test to see if 1st Host is up
    ping -c 4 -q 192.168.2.2 > /tmp/check_2.tmp # Test to see if 2nd Host is up

    if [ “`cat /tmp/check_1.tmp | awk ‘{print $1}’ | tail -n 1`” = “round-trip” ]; then
    echo The 1st Host is up… `date “+%Y-%m-%d %H:%M:%S”` >> /var/log/check_if_up.log

    elif [ “`cat /tmp/check_2.tmp | awk ‘{print $1}’ | tail -n 1`” = “round-trip” ]; then
    echo The 1st Host is down… `date “+%Y-%m-%d %H:%M:%S”` >> /var/log/check_if_up.log
    echo The 2nd Host is up… `date “+%Y-%m-%d %H:%M:%S”` >> /var/log/check_if_up.log

    else
    echo All Hosts are down. Shutdown FreeNAS at `date “+%Y-%m-%d %H:%M:%S”` >> /var/log/check_if_up.log
    /bin/sync
    /sbin/shutdown -p now

    fi

    fi

    1. The new Zune browser is surprisingly good, but not as good as the iPod’s. It works well, but isn’t as fast as Safari, and has a clunkier interface. If you occasionally plan on using the web browser that’s not an issue, but if you’re planning to browse the web alot from your PMP then the iPod’s larger screen and better browser may be important.

  3. What about something like this:
    Setup up a low power device (hacked pogoplug?) with a linux variation. This box intercepts/listens to requests on the network to access the Freenas. If there is a request, a WOL packet is sent to the server? I’m a bit of a do-it-yourselfer and this is the route that I’m looking at. I think this would be a more universal aproach to the problem. E.g. it would solve the problem of say, an android device wants to access a music/movie file on the nas without having to root the device and setup some kind of script.

    Your thoughts?

  4. Denis,

    Thanks so much for your posting of the shell script. Worked perfect!

    Also, thanks for this article. I am using this to shutdown my FreeNAS8 after my VMware Server finishes shutting down after power outage. Obviously, both my VMServer and FreeNAS are plugged into the same CyberPower UPS. I have tested this process out like 50 times now and it’s never failed. Great peace of mind!

    Thanks again to all!

    Doug

  5. I recently wrote an autoshutdown daemon in python, which is a bit more sophisticated. It checks for SSH / Console activity, filesystem activity and mapped shares. Advantages:

    – Does not shut down if a local sync via ssh is performed
    – Shuts down if no share is mapped or used and no other activity is detected

    Link: http://fynder.de/autoshutdown.txt

    Install:
    – Open SSH connection, type
    mount -uw / # mount / rw
    wget -c http://fynder.de/autoshutdown.txt -O /usr/local/sbin/autoshutdown.py
    chmod +x /usr/local/sbin/autoshutdown.py

    To run at startup an /conf/base/etc/rc.local must exist:

    #!/bin/sh
    /usr/local/sbin/autoshutdown.py start

    Don’t forget:
    chmod +x /conf/base/etc/rc.local

    Daemon should work after reboot, test it with:
    cat /tmp/autoshutdown.pid

    Feedback is welcome

  6. Simple and yet efficient approach of your shutdown.py. However, from the technical point of view, it is not written in a solid way.

    I urge you to read in the Python docs how exactly the communicate() and wait() methods of a Popen() object work. It’s important to get these details right. Also, you do not use ping in a solid fashion. Since we are monitoring a decoupled system involving many potentially failing components and real latency times, we need to add some forgiveness to our monitoring system. For this purpose, it is entirely fine to send a few ICMP requests and wait a few seconds for any response before considering the test as failed. Furthermore, there is no need to perform some unreliable parsing of ping’s stdout. Its exit code is made for telling us what we want to know (see the manpage of any ping program). If it’s 0, then the machine has answered. There is no better criterion to test for than this.

    Based on these considerations, I have written a more solid implementation of your approach:

    https://bitbucket.org/jgehrcke/freenas-utils/src/default/conditionalshutdown.py

    Feel free to use and/or to comment.

    Cheers,

    Jan-Philip

    1. Hi, Jan-Philip

      I have been using your script ‘conditionalshutdown.py’ for months now and it has worked perfectly. Thank you. Unfortunately somehow it broke. I upgraded to Freenas 9.2 about a week ago and the script has been working except for the last 24 hours.

      If I place the path to ‘conditionalshudown.py’ in the shell this is what I get:

      [root@freenas ~]# /mnt/USB4_Scripts_Utilities/Enabled/conditionalshutdown/condit
      ionalshutdown.py
      Traceback (most recent call last):
      File “/mnt/USB4_Scripts_Utilities/Enabled/conditionalshutdown/conditionalshutd
      own.py”, line 148, in
      encoding=’utf-8′)
      File “/usr/local/lib/python2.7/logging/handlers.py”, line 117, in __init__
      BaseRotatingHandler.__init__(self, filename, mode, encoding, delay)
      File “/usr/local/lib/python2.7/logging/handlers.py”, line 64, in __init__
      logging.FileHandler.__init__(self, filename, mode, encoding, delay)
      File “/usr/local/lib/python2.7/logging/__init__.py”, line 902, in __init__
      StreamHandler.__init__(self, self._open())
      File “/usr/local/lib/python2.7/logging/__init__.py”, line 927, in _open
      stream = codecs.open(self.baseFilename, self.mode, self.encoding)
      File “/usr/local/lib/python2.7/codecs.py”, line 881, in open
      file = __builtin__.open(filename, mode, buffering)
      IOError: [Errno 2] No such file or directory: ‘/mnt/USB4_Scripts_Utilities/condi
      tionalshutdown/logfile.log’
      [root@freenas ~]#

      To my knowledge I haven’t altered it, I have reloaded two different backups dating back two weeks, I have also recopied your file from the net and same errors, re-upgraded Freenas, and also reloaded older configuration files. It remains the same.

      Any ideas.

      1. Update;

        I removed all files from the folder
        Created a new ‘conditionalshutdown.py’
        Added my IP’s
        Changed the ‘Logfile_path’
        Changed permissions

        It works! I don’t know what happened. Hopefully I haven’t spoken to soon.

  7. Very useful information for newbies like me. conditionalshutdown.py worked in FreeNas 9.1.1.

    How do you make these scripts send an email in case of a shutdown?
    How do you turn off logging?

    Thanks you.

    1. Can you tell me how you do it in 9.1.1 you use int/shutdown scripts?

      i only need no change this?
      HOSTS_TO_CHECK = [
      “hostname1”,
      “hostname2”,
      “192.168.1.77”
      ]

      or this to
      logfile_path = “logfile.log”????

      i have this working in 8.2.0 but now do not know it

    1. HOW TO USE WITH FreeNAS-9.2.1.3-RELEASE
      I test freenas embedded system ON USB BOOT
      1) You only need change this:

      HOSTS_TO_CHECK = [
      “hostname1”,
      “hostname2”,
      “192.168.1.77”
      FOR YOUR HOST:
      HOSTS_TO_CHECK = [
      “192.168.1.115”

      And this to
      logfile_path = “logfile.log”
      FOR YOUR PATH:
      “/mnt/share/conditionalshutdown/logfile.log”
      2) save it on your nas
      \\192.168.1.109\SHARE\conditionalshutdown\ conditionalshutdown.py

      3) Don’t forget PERMISIONS:
      GO TO SHELL FROM WEB ADMIN FREENAS
      chmod +x /mnt/nas/conditionalshutdown/ conditionalshutdown.py

      4) INIT/SHUTDOWN SCRIPTS
      Add Init/Shutdown Script
      Type: Command
      Command: /usr/local/bin/python /mnt/nas/conditionalshutdown/conditionalshutdown.py
      Type: Post Init

      Saludos desde Argentina perdon por mi ingles!

    1. You can use WolCmd
      http://www.depicus.com/wake-on-lan/wake-on-lan-cmd.aspx

      1) Create PCS.TXT in same directory of wolcmd
      The syntax is as follows:
      [name pc] [mac address] [ip address] [subnet mask]
      myNAS BBBBBBBBBBBB 192.168.1.109 255.255.255.0
      Note: One pc one line. The easiest way to get the mac address of your FreeNas is to:
      1. Log into the FreeNas web interface
      2. Goto Shell
      3. ifconfig

      2) Create a bat WOL.BAT in same directory of wolcmd
      Open notepad and put:

      @echo off
      if not (%1)==() goto WAKE
      for /F “tokens=1-4” %%a in (PCs.txt) do call %0 %%a %%b %%c %%d
      goto QUIT
      :
      :WAKE
      echo WOL: %2 %3 %4
      wolcmd %2 %3 %4
      :
      :QUIT
      rem – – exit

      Save it as “WOL.BAT”

      3) Run bat automatically when Windows starts
      Create a shortcut, cut and paste into Startup folder
      Click the Start button , click All Programs, right-click the Startup folder, and then click Open.

      saludos! desde Argentina! Perdon por mi ingles

  8. Conditional shutdown of IP’s should be part of the WebUI – I suspect a lot of people want to do this. I for sure don’t want my box on 24/7. Firstly waste of electric and secondly wear my disks out.

      1. Uh, would be helpful if you’d cite the source of empirical data on your array failure comments. Personally, I’ve had a Synology NAS for 3+ years with WD Green drives that auto-turns on & off based on an presence/absence of an attached share. Some people use their NAS all day every day, some people only use them weekly for backups or such. It’s ludicrous that FreeNAS doesn’t have a similar built-in mechanism to put the control in the users’ hands. This script is a great option!

Leave a Reply