Trying out auto-mounting network shares with AppleScript

I wanted a neater way of auto-mounting network shares on startup than simply sticking the path in Login items so I thought I'd search around and see what methods were available.

I finally settled on using a bit of AppleScript to first check if the mount point exists and, if not, to attempt to mount the network share.

tell application "Finder"
 if not (exists POSIX file "/Volumes/Data") then
   mount volume "afp://some-server.local/Data"
  end try
  display dialog "Already Mounted"
 end if
end tell

Given that I wanted to mount multiple shares, putting the above in a function seemed like the way to go. Unfortunately, no matter what I tried, passing the path to Finder as a variable caused the test to always fail - even though though the path could be displayed via dialog as well as appearing in the AppleScript Editor's Events box. After finally giving up on that, I switched to a bash style test and all was well.

So, after all that, the function mountSmbShare() checks if the directory exists and, if not, tells Finder to mount it. It takes the remote and local paths as values - the local to allow for checking. I might try improving it so that it splits the remote path on the "/" then using the last value in the resulting array to work out the local path but it'll do for now.

on mountSmbShare(smbShare, mountPoint)
 if (do shell script "if [ -d " & quoted form of mountPoint & " ]; then echo '0'; else echo '1'; fi") is "1" then
  tell application "Finder"
    mount volume smbShare
   end try
  end tell
 end if
end mountSmbShare

mountSmbShare("smb://server.local/Multimedia", "/Volumes/Multimedia")
mountSmbShare("smb://server.local/Whatever", "/Volumes/Whatever")
mountSmbShare("smb://server.local/Public", "/Volumes/Public")
mountSmbShare("smb://server.local/www", "/Volumes/www")

I export the script to an application in ~/bin and add it to my Login items and - bam! - my shares are all automagically mounted every time I login. Happy days.

So that was my fun introduction to AppleScript. Always nice to play with something new (to me) but I probably would have been better served sticking with bash.

Setting up my new router lab

After putting in a new shelf and tidying up my network gear a week ago - as seen below - it was time to organize the Cisco routers I'd picked up off eBay during the week.

First thing to do was add the extra WICs I'd bought (WIC-1Ts as they could be had for around $15, whereas 2Ts started at $30). The 2821 - maxed out spec-wise and already running IOS 15.1 - came with no WICs at all, while I chose one of the 2600-series to be 'piggy-in-the-middle', so to speak, and it now has two serial cards.

And that was that. The 3 routers are now sitting on the trolley I picked up a couple weeks back (much cheaper than a wheeled-rack; easily movable/adjustable). Above them the switch setup is starting to take shape with the two 3550s that just came in the post. I'll add the 2950 I already have and hopefully a couple more - either more 3550s or perhaps a 2960 or two. With 4 or more I should be able to setup some decent LACP, PAgP and STP scenarios, along with L3 routing via the 3550s.


Testing out Link Aggregation

I picked up a TP-Link managed switch last week as something of a compromise between affordability and features - as it turns out though, it does just about everything I could ask for, just without the extra expense from buying something that has HP or Cisco written on the side.

I grabbed the TL-SG3216, a fanless L2 managed switch with 16x1Gigabit ports as it ticked all the boxes:
  • Silent (fanless)
  • Managed
  • Link Aggregation/802.3ad (LACP)
  • 802.1Q (VLAN)
  • STP

As a bonus, the CLI interface (via console cable or ssh) is very similar to Cisco's IOS, so I don't have to learn an entirely new syntax to configure it.

Before I replace my existing switch, I spent a bit of time testing out its features. First up, I setup a spare Raspberry Pi with a second ethernet interface (via a USB dongle) to test out link aggregation.

First up, the configuration on the Pi (Raspbian):

Install ifenslave to allow for the creation of bonded network interfaces

# apt-get install ifenslave

Remove lines for eth0, eth1 from `/etc/networking/interfaces` and replace with a bond0 entry that adds the two interfaces as slaves:

auto bond0
iface bond0 inet static
    # jumbo frame support
    mtu 9000
    # bond settings
    bond_miimon  100
    bond_mode 4
    bond-downdelay 200
    bond-updelay 200
    slaves eth0 eth1

Note on bond modes:

  • mode 0 (load balancing [rr])
  • mode 4 (802.3ad)

Bring up the interface:

# ifup bond0

Check its status:

# cat /proc/net/bonding/bond0

Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer2 (0)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200

802.3ad info
LACP rate: slow
Min links: 0
Aggregator selection policy (ad_select): stable
Active Aggregator Info:
    Aggregator ID: 1
    Number of ports: 1
    Actor Key: 4
    Partner Key: 1
    Partner Mac Address: 00:00:00:00:00:00

Slave Interface: eth0
MII Status: up
Speed: 10 Mbps
Duplex: half
Link Failure Count: 0
Permanent HW addr: b8:27:eb:95:0e:4d
Aggregator ID: 1
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 100 Mbps
Duplex: full
Link Failure Count: 2
Permanent HW addr: 20:c9:d0:2c:93:9a
Aggregator ID: 2
Slave queue ID: 0

One strange thing from the above output is that it listed eth0 as running at 10Meg and half-duplex. However, checking both the switch and eth0 via ifconfig and dmesg shows the interface running at 100Meg/full - so I'm not sure why this discrepancy exists.

Examining each interface in turn shows the two physical adapters up and running in slave mode while the created bond0 interface is running as a master. Once bonded, all interfaces share a hardware address (that of the first interface):

# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr b8:27:eb:95:0e:4d
          RX packets:5466 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4048 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:7513825 (7.1 MiB)  TX bytes:358909 (350.4 KiB)

# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr b8:27:eb:95:0e:4d
          RX packets:68 errors:0 dropped:42 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:7256 (7.0 KiB)  TX bytes:1408 (1.3 KiB)

# ifconfig bond0
bond0     Link encap:Ethernet  HWaddr b8:27:eb:95:0e:4d
          inet addr:  Bcast:  Mask:
          RX packets:320 errors:0 dropped:42 overruns:0 frame:0
          TX packets:129 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:30587 (29.8 KiB)  TX bytes:19586 (19.1 KiB)

Configuration on a TP-Link TL-SG3216 switch is as follows:

Add two ports to an etherchannel group and set the mode of the channel group to `active`:

switch01(config)#interface range gigabitEthernet 1/0/1-2

switch01(config-if-range)#channel-group 1 mode active


Show the etherchannel and LACP info to check the configuration is active:
switch01#show etherchannel
                Channel-group listing:

Group: 1
Group state = L2
Ports: 2  MaxPorts = 16
Protocol:   LACP

switch01#show lacp 1 int
Flags:  S - Device is requesting Slow LACPDUs
        F - Device is requesting Fast LACPDUs
        A - Device is in active mode       P - Device is in passive mode

Channel group 1
                            LACP port     Admin     Oper    Port        Port
Port      Flags   State     Priority      Key       Key     Number      State
Gi1/0/1   SA      Up        32768         0x1       0x783   0x1         0x7d
Gi1/0/2   SA      Up        32768         0x1       0x783   0x2         0x3d