Monday, October 29, 2012

IIS, Visual Studio and Razor

I'm working on my second project that uses MVC and Razor. While working on the first one, I noticed that any time I tried to paste something into a .cshtml file, Visual Studio hung for what seemed like an eternity (although it was probably 10-20 seconds). It was so annoying that I edited those files in a text editor and never opened them in Visual Studio.

I didn't notice this problem in my current project, until today. Not only that, but suddenly every time I tried to set a breakpoint in a .cshtml file, Visual Studio would freeze and I would end up killing it with task manager. Everything worked fine until today, and I was pretty pissed when it quit working. I restarted Visual Studio multiple times, I rebooted my computer, I changed my code back to how it was at the beginning of the day, all to no avail.

But then I remembered that earlier today I had changed the ASP.NET Impersonation setting for my application in IIS because I needed it to impersonate a specific user. On a whim, I changed that back to the default (Authenticated user). And guess what? Now Visual Studio plays nicely with my .cshtml files.

Then, on another whim, I changed my specific user to an Administrator account and tried it again, and it still works.

So the moral of the story is to use an Administrator account (on the development machine) if you need to have IIS impersonate a specific user. I guess I can kind of see how using a regular account might mess with the breakpoints, but cutting and pasting? Really, Microsoft?

Wednesday, February 1, 2012

Automating rsync on a Mac

For reasons that I won't go into here, I decided that I wanted to sync some of the folders on one of my internal hard drives to another internal drive. This is not a backup system, because old versions of files are not saved (I have Time Machine for that)-- it's just a way to mirror data.

Naturally I thought of using rsync, and the command to copy the files is easy:

sudo rsync -axES --delete /Volumes/MacA/Data /Volumes/MacAMirror/

However, I wanted this to run automatically. I tried using Automator, but I'd have to enter a password each time the thing ran, which I did not want to do. In fact, I wanted it to run at night when I wasn't even here.

My solution? Create a symbolic link to rsync and then edit the sudoers file so that I didn't need to enter a password when running that program. I did this instead of changing my access to the main rsync executable so that I didn't accidentally get myself in trouble some time with rsync.

So first I created a directory to put my symbolic link and shell script in.

~$ mkdir ShellScripts
~$ cd ShellScripts
~/ShellScripts$ ln -s /usr/bin/rsync nopass_sudo_rsync
~/ShellScripts$ ls -l
total 16
lrwxr-xr-x  1 chrisg  staff   14 Jan 27 11:44 nopass_sudo_rsync -> /usr/bin/rsync
-rwxr--r--  1 chrisg  staff  334 Jan 31 12:50 rsync_data.sh

The script file (rsync_data.sh) looks like this:

#!/bin/sh

logger 'Start MacA rsync'
sudo /Users/chrisg/ShellScripts/nopass_sudo_rsync -axES --delete /Volumes/MacA/Data /Volumes/MacAMirror/
logger 'Stop MacA rsync'

Then I edited the sudoers file:

~/ShellScripts$ sudo visudo

I added this line to the Cmnd alias specification section:

Cmnd_Alias JUSTRUN  = /Users/chrisg/ShellScripts/nopass_sudo_rsync

And this line to the User privilege specification

chrisg  ALL=(ALL) NOPASSWD: JUSTRUN

This creates a group of commands called JUSTRUN that chrisg is allowed to run with sudo without a password.

The last step was to create a plist file in /Library/LaunchDaemons.

~/ShellScripts$ cd /Library/LaunchDaemons
/Library/LaunchDaemons$ sudo vi org.chrisg.daily.rsync_data.plist

Here are the contents of org.chrisg.daily.rsync_data.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>org.chrisg.daily.rsync_data</string>
  <key>ProgramArguments</key>
  <array>
    <string>/Users/chrisg/ShellScripts/rsync_data.sh</string>
  </array>
  <key>StartCalendarInterval</key>
  <dict>
    <key>Hour</key>
    <integer>20</integer>
    <key>Minute</key>
    <integer>05</integer>
  </dict>
</dict>
</plist>

This will run /Users/chrisg/ShellScripts/rsync_data.sh daily at 20:05.

See here for some plist recipes.

Use launchctl to get the automation working immediately instead of waiting for the next reboot.

/Library/LaunchDaemons$ launchctl load org.chrisg.daily.rsync_data.plist