Automatic Apache Virtual Hosts pt2

I’ve added the 3 following things to my Automatic Apache Virtual Host Applescript discussed (part one of this post here).

  1. A vbscript for a VMware Fusion virtual machine
  2. An index page of all virtual hosts
  3. Root directory browsing of the webserver

First the vbscript which I’ve called updateHosts.vbs, for this I’ve used these libraries.  The general idea is the ghost applescript will check is my virtual windows machine is running and if so run the vbscript inside of the virtual machine using the vmware vmrun command.  I also run the vbscript on windows vm login as well, just incase I last ran the applescript whilst the VM was off.

 

option Explicit
Dim hostip,root ,domain, clients, client, projects, project, projectSubFolders, projectSubFolder,oFSO
hostip="172.16.214.1"
root = "W:\Projects"

Dim o_h : Set o_h = New std_host_file

Call o_h.Load( "C:\Windows\System32\drivers\etc\hosts" , False )
Call o_h.DeleteHostEntry( hostip )

set oFSO = CreateObject("Scripting.FileSystemObject") 
ofso.getfolder(root)
for each client in ofso.getfolder(root).subfolders
	For each project in client.SubFolders
		If Left(project.Name,1) <> "_" then
			For Each projectSubFolder in project.SubFolders
				if  projectSubFolder.Name = "web" then
					Call o_h.AddHostEntry( hostip, project.name & "." & client.name )
				end if
			Next
		End if
	next
Next
Call o_h.Save("C:\Windows\System32\drivers\etc\hosts")

Class std_host_file
	Private Sub Class_Initialize()
		Set m_lines = CreateObject("Scripting.Dictionary")
		Set m_ip_map = CreateObject("Scripting.Dictionary")
		Set m_alias_map = CreateObject("Scripting.Dictionary")
		m_alias_map.CompareMode = vbTextCompare
	End Sub
	Private sub Class_Terminate()
		Set m_lines = Nothing
		Set m_ip_map = Nothing
		Set m_alias_map = Nothing
	End Sub
	' Function returns the ip and data
	Private Sub parse_line( ByVal line , ByRef comment , ByRef ip , ByRef aliases  ) 
		Dim rx : Set rx = New RegExp
		Dim r
		rx.Global = False
		rx.IgnoreCase = True
		rx.Pattern = "\s*(#.*)\s*"
		' Parse Comment
		If rx.Test( line ) Then
			Set r = rx.Execute( line )
			comment = r.Item(0).subMatches.Item(0)
			line = rx.Replace( line , "" )
		End If		
		rx.Pattern = "\s*((\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)|(\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*))\s*"
		' Parse IP
		If rx.Test( line ) Then
			Set r = rx.Execute( line )
			ip = r.Item(0).subMatches.Item(0)
			aliases = rx.Replace( line , "" )
		End If
	End Sub
	' Function returns the ip and data
	Private Function getip( ByRef str , ByRef ip  ) 
		getip = False 
		Dim rx_ip : Set rx_ip = New RegExp
		rx_ip.Global = False
		rx_ip.IgnoreCase = True
		rx_ip.Pattern = "\s*((\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)|(\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*))\s*"
		If rx_ip.Test( str ) Then
			Dim r : Set r = rx_ip.Execute( str )
			ip = r.Item(0).subMatches.Item(0)
			str = rx_ip.Replace( str , "" )
			getip = True
		End If
	End Function
	' Internal function used to validate IPV4 addresses
	Private Function isipv4( ByVal ip )
		Dim rx_ipv4 : Set rx_ipv4 = New RegExp
		rx_ipv4.Global = false
		rx_ipv4.IgnoreCase = True
		rx_ipv4.Pattern = "^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$"
		isipv4 = rx_ipv4.Test( ip )
	End Function
	' Internal function used to validate IPV6 addresses
	Private Function isipv6( ip )
		Dim rx_ipv6 : Set rx_ipv6 = New RegExp
		rx_ipv6.Global = false
		rx_ipv6.IgnoreCase = True
		rx_ipv6.Pattern = "^\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$"			
		IsIPV6 = rx_ipv6.Test( ip )
	End Function
	' Internal function used to generate unique IDs
	Private Function genguid()
		Dim guidgen : Set guidgen = CreateObject("Scriptlet.TypeLib") 
		genguid = Mid(guidgen.Guid, 2, 36)
	End Function
	' Function returns true on success, otherwise false if the ip doesn't exist
	Public Function GetHostEntryAliases( ByVal ip , ByRef aliases )
		GetHostEntryAliases = False
		aliases = Array
		If m_ip_map.Exists( ip ) Then 
			aliases = m_lines.Item( m_ip_map.Item(ip) )(1).Keys
			GetHostEntryAliases = True
		End If
	End Function 
	' Function returns true on success, otherwise false if alias doesn't exist
	Public Function GetHostEntryAliasAddresses( ByVal alias , ByRef ips )
		GetHostEntryAliasAddresses = False
		ips = Array
		If m_alias_map.Exists( alias ) Then 
			ips = m_alias_map.Item( alias ).Keys
			GetHostEntryAliasAddresses = True
		End If
	End Function 
	' Removes a host entry by IPV4 or IPV6 address, return true
	' on success, otherwise false if the IP is doesn't exist
	Public Function DeleteHostEntry( ByVal ip )
		DeleteHostEntry = False
		If m_ip_map.Exists( ip ) Then 
			Dim a
			Dim uid : uid = m_ip_map.Item(ip)
			' Remove the ip's from the associated aliases
			For Each a In m_lines.Item(uid)(1).Keys 
				If m_alias_map.Item( a ).Exists( ip ) Then
					m_alias_map.Item( a ).Remove( ip )
				End If
				' If there are no more assoicated IPs remove the alias
				If m_alias_map.Item(a).Count = 0 Then
					m_alias_map.Remove( a )
				End If 
			Next
			' This *should* exist since we manage the entries and mappings
			m_lines.Remove( uid )
			m_ip_map.Remove( ip )
			DeleteHostEntry = True
		End If
	End Function
	' Removes a host alias by IPV4 or IPV6 address
	Public Function DeleteHostEntryAlias( ByVal ip , ByVal alias )
		DeleteHostEntryAlias = False
		' If the IP is valid
		If m_ip_map.Exists( ip ) Then
			Dim uid : uid = m_ip_map.Item(ip)		
			' If the alias exists remove the ip and if no more ip's are mapped to the alias remove the alias	
			If m_alias_map.Exists( alias ) Then
				If m_alias_map.Item( alias ).Exists( ip ) Then
					m_alias_map.Item( alias ).Remove( ip )
				End If
				If m_alias_map.Item(alias).Count = 0 Then
					m_alias_map.Remove( alias )
				End If
			End If
			' If IP no longer has aliases associated with it remove it
			Call delalias( uid , alias )
			If m_lines.Item( uid )(1).Count = 0 Then
				m_lines.Remove( uid )
				m_ip_map.Remove( ip )
			End If
			DeleteHostEntryAlias = True
		End If
	End Function
	' Adds a host entry by IPV4 or IPV6 address, alias should be 
	' the text alias for the address. Returns true on success
	Public Function AddHostEntry( ByVal ip , ByVal alias )		
			AddHostEntry = False 		
			Dim rx : Set rx = New RegExp
			rx.Global = true
			rx.IgnoreCase = True
			rx.Pattern = "\s*"
			alias = rx.Replace( alias , "" )
			ip = rx.Replace( ip , "" )
			' Validate IP
			If isipv6( ip ) Or isipv4( ip ) Then 
				' Check for alias in the alias mapping
				If Not m_alias_map.Exists( alias ) Then	Call m_alias_map.Add( alias , CreateObject("Scripting.Dictionary") )
				If Not m_alias_map.Item( alias ).Exists( ip ) Then Call m_alias_map.Item( alias ).Add( ip , "" )
				' Map IP -> alias 
				If m_ip_map.Exists( ip ) Then 
					' Lookup the index by ip then add aliases
					Call addalias( m_ip_map.Item(ip) , alias )
				Else
					' Store File Line
					Dim uid : uid = genguid
					Call m_lines.Add( uid , Array( ip , CreateObject("Scripting.Dictionary") , vbNullString ) )
					Call addalias( uid , alias )
					Call m_ip_map.Add( ip , uid )
				End If
				AddHostEntry = True
			End If	
	End Function
	' Should be used for debugging the data
	Public Sub DumpData( )
		Dim id, a, ip, a_map
		' Debug dump host file out to text
		WScript.Echo( "-------------------------------------------------------------------" )
		For Each id In m_lines.Keys
			If TypeName( m_lines.Item(id) )  = "String" Then
				WScript.Echo m_lines.Item(id)
			ElseIf TypeName( m_lines.Item(id) ) = "Variant()" Then
				WScript.StdOut.Write lpad( m_lines.Item(id)(0) & "" , " " , 16 )  & Space(8)
				For Each a In m_lines.Item(id)(1).Keys
					WScript.StdOut.Write a & " " 
				Next
					WScript.StdOut.Write m_lines.Item(id)(2) & vbCrLf
			End If 
		Next
		WScript.Echo( "-------------------------------------------------------------------" )

		For Each ip In m_ip_map.Keys
			For Each a In m_lines.Item( m_ip_map.Item(ip) )(1).Keys
				WScript.Echo "IP [" & ip & "] ID Map {" & m_ip_map.Item(ip)	& "} --> alias [" & a & "]"
				If m_alias_map.Exists( a ) Then 
					For Each a_map In m_alias_map.Item( a ).Keys
						WScript.Echo "alias Key [" & a & "] IP --> [" & a_map & "]"
					Next
				End If
			Next
		Next	 
	End Sub 
	' Internal formattig function for padding host data
	Private Function lpad ( str , padch , padlen ) 
		If padlen - Len(str) >= 0 Then 
			Lpad = String(padlen - Len(str),padch) & str 
		Else
			Lpad = str	
		End If 	
	End Function
	' Returns all the IP addresses defined in the host file
	' Returns true on success, otherwise false
	Public Function GetAllHostEntryAddresses( ByRef ips )
		GetAllHostEntryAddresses = False
		ips = Array
		If m_ip_map.Count > 0 Then 
			ips = m_ip_map.Keys
			GetAllHostEntryAddresses = True
		End If
	End Function
	' Returns all the aliases defined in the host file
	' Returns true on success, otherwise false
	Public Function GetAllHostEntryAliases( ByRef aliases )
		GetAllHostEntryAliases = False
		aliases = Array
		If m_alias_map.Count > 0 Then 
			aliases = m_alias_map.Keys
			GetAllHostEntryAliases = True
		End If
	End Function

	' Write host file returns true if file could be opened for writing
	Public Function Save( ByVal hostfile )		
		On Error Resume Next
		Save = False
		Dim id, a
		Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
		Dim oFile : Set oFile = Nothing
		Set oFile = objFSO.OpenTextFile( hostfile , 2 , True )
		If Not oFile Is Nothing Then 
			For Each id In m_lines.Keys
				If TypeName( m_lines.Item(id) ) = "String" Then
					Call oFile.WriteLine( m_lines.Item(id) )
				ElseIf TypeName( m_lines.Item(id) ) = "Variant()" Then
					Call oFile.Write( lpad( m_lines.Item(id)(0) & "" , " " , 16 )  & Space(8) )
					For Each a In m_lines.Item(id)(1).Keys
						Call oFile.Write( a & " " )
					Next
					Call oFile.Write( m_lines.Item(id)(2) & vbCrLf )
				End If 
			Next
			Save = True
		End If
		Set objFSO = Nothing
	End Function

	' Write host file returns true if file could be opened for reading
	Public Function Load( ByVal hostfile , ByVal bmergecomments )
		On Error Resume Next		
		Load = False
		m_lines.RemoveAll()
		m_ip_map.RemoveAll()
		m_alias_map.RemoveAll()
		Dim rx : Set rx = New RegExp
		rx.Global = true
		rx.IgnoreCase = True
		rx.Pattern = "\s+"
		Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
		Dim oFile : Set oFile=Nothing
		Set oFile = objFSO.OpenTextFile( hostfile , 1 )
		If Not oFile Is Nothing Then 
		While Not oFile.AtEndOfStream
			Dim pos : pos = 0
			' Data will not be modified to preserve the file context
			Dim data : data = Trim(oFile.ReadLine())
			' Remove all the extra whitespace so we have a single spacing	
			' Line will be chopped up to see valid information exists
			Dim line : line = Trim(rx.Replace(data, " "))
			Dim ip : ip = vbNullString
			Dim comment : comment = vbNullString
			Dim aliases : aliases = vbNullString
			' Check if the line is empty
			If line <> vbNullString Then					
				Call parse_line( line , comment , ip , aliases )
				If isipv4( ip ) Or isipv6( ip ) Then 	
					Dim a, uid
					' Map alias -> IPs
					For Each a In Split(aliases)
						If Not m_alias_map.Exists( a ) Then 
							Call m_alias_map.Add( a , CreateObject("Scripting.Dictionary") )
						End If
						If Not m_alias_map.Item( a ).Exists( ip ) Then Call m_alias_map.Item( a ).Add( ip , "" )
					Next
					' Map IP -> alias 
					If m_ip_map.Exists( ip ) Then
						uid = m_ip_map.Item(ip)
						' Lookup the index by ip then add aliases
						For Each a In Split(aliases)
							Call addalias( uid , a )
						Next
						If bmergecomments Then 
							' Overkill (should be first # )
							pos = InStr( 1, comment , "#" , vbTextCompare )
							If pos <> 0 Then 
								' Replace leading # from dual comment
								comment = Mid( comment , pos + 1 )
								' Merge comments
								Call setcomment( uid , m_lines.Item( uid )(2) & "," & comment )
							End If
						End If
					Else
						' Store File Line
						uid = genguid
						Call m_lines.Add( uid , Array( ip , CreateObject("Scripting.Dictionary") , comment ) )
						For Each a In Split(aliases)
							Call addalias( uid , a )
						Next
						Call m_ip_map.Add( ip , uid )
					End If
				Else 
                                        ' Unknown IP format or malformed file
					Call m_lines.Add(genguid,data)
				End If
			Else
				Call m_lines.Add(genguid,data)
			End If
		Wend
		Load=True
		End If
		Set objFSO = Nothing
	End Function
	Private Function setip( uid , ip )
		setip = False
		If m_lines.Exists( uid ) Then
			m_lines.Item(uid) = Array( ip , m_lines.Item(uid)(1) , m_lines.Item(uid)(2) ) 
			setip = True
		End If
	End Function
	Private Function setcomment( uid , comment )
		setcomment = False
		If m_lines.Exists( uid ) Then
			Dim a : a = m_lines.Item(uid)
			m_lines.Item(uid) = Array( m_lines.Item(uid)(0) , m_lines.Item(uid)(1) , comment )  
			setcomment = True
		End If
	End Function
	Private Function addalias( uid , alias )
		addalias = False
		If m_lines.Exists( uid ) Then
			If Not m_lines.Item(uid)(1).Exists( alias ) Then 
				Call m_lines.Item(uid)(1).Add( alias , "" )
				addalias = True
			End If
		End If
	End Function
	Private Function delalias( uid , alias )
		delalias = False
		If m_lines.Exists( uid ) Then
			If m_lines.Item(uid)(1).Exists( alias ) Then 
				Call m_lines.Item(uid)(1).Remove( alias )
				delalias = CBool( Not m_lines.Item(uid)(1).Exists( alias ) )
			End If
		End If
	End Function
	Private m_lines
	Private m_ip_map
	Private m_alias_map
End Class

Note the variables you may need to tweak here are hostip and root. I run my vm in NAT network mode which gives my windows machine access to my mac via the ip 172.16.214.1. The root variable is a shared vm folder here all my projects are stored.

The next addition is a handy little index page that returns all my virtual hosts. For this I’ve added the folder templates/index/web in order for me to get a domain of http://index.templates/. In here I’ve generated a hosts.txt which is an export of all the hosts generated by ghost using the following export command:

do shell script "ghost export > '" & unixRoot & "/templates/index/web/hosts.txt'" user name theUserName password thePassword with administrator privileges

I then parse this with the following index.php:

<!DOCTYPE HTML>
<html>
<body>
<?php
$masterList = array();
foreach (file("hosts.txt") as $name) {
	//get rid of ip address part of line
	$hosts = explode(" ",$name); 
	
	//Work out top level domain
	$subs = explode(".",$hosts[0]); 
	$topLevel = $subs[count($subs)-1];
	
	//construct array of top-level and full domain name
	$masterList[] = array($topLevel,$hosts[0]); 
}

//sort by top level
foreach ($masterList as $key => $row) {
    $tops[$key]  = $row[0];
}
array_multisort($tops, SORT_DESC, $masterList);

//output html links
$header = "";
foreach ($masterList as  $row) {
	if ($header!=$row[0]){
		$header= $row[0];
		
		echo "<h2>".$header."</h2>";
		
	}
    echo "<a href='http://" .$row[1] . "'>".$row[1]. '</a><br>';
   }
?>
</body>
</html>

I now have a handy http://index.templates/index page bookmarked on both my mac and virtual windows machine.

The final addition is not that notable really, it’s just getting the normal http://localhost to work in apache so I can browse around. My virtual hosts section of httpd.conf now looks like this:

<VirtualHost *>
    VirtualDocumentRoot /Users/stu/Projects/%-1/%-2+/web
	ServerName *
</VirtualHost>
<VirtualHost *>
    ServerName localhost
   DocumentRoot /Users/stu/Projects	
</VirtualHost>

So here’s my final ghoster.scpt applescript

set root to "Macintosh HD:Users:stu:Projects"
set unixRoot to POSIX path of root
set domain to ""
--Get mac credentials from a keychain entry called MAMP
set theUserName to do shell script ("security  find-generic-password -gl MAMP | grep \"acct\" | cut -c 19-99 | sed 's/\"//g'")
set thePassword to do shell script ("security 2>&1 >/dev/null find-generic-password -gl MAMP | cut -c 11-99 | sed 's/\"//g'")
--get rid of current hosts entries in hosts, we're gonna create fresh ones
do shell script "ghost empty" user name theUserName password thePassword with administrator privileges
--add entries based of filesystem structure
tell application "Finder"
	set clients to every folder of alias root
	repeat with client in clients
		set folderName to name of client
		if first character of folderName is not "_" then
			set projects to every folder of client
			repeat with project in projects
				set projectSubFolders to every folder of project
				repeat with projectSubFolder in projectSubFolders
					if name of projectSubFolder is "web" then
						set domain to name of project & "." & name of client
						do shell script "ghost add " & domain user name theUserName password thePassword with administrator privileges
					end if
				end repeat
			end repeat
		end if
	end repeat
end tell
--export what we've just made in a text file for the index.php to parse
do shell script "ghost export > '" & unixRoot & "/templates/index/web/hosts.txt'" user name theUserName password thePassword with administrator privileges
--get credentials for the windows VM
set winUserName to do shell script ("security  find-generic-password -gl win | grep \"acct\" | cut -c 19-99 | sed 's/\"//g'")
set winPassword to do shell script ("security 2>&1 >/dev/null find-generic-password -gl win | cut -c 11-99 | sed 's/\"//g'")
--get a list of running vmware machines
set test to do shell script "'/Applications/VMware Fusion.app/Contents/Library/vmrun' list"
--see if my windows dev machine is running
set search to offset of "win.vmx" in test
if search is greater than 0 then
	--if it's running fire the vbscript inside the guest instance
	do shell script "'/Applications/VMware Fusion.app/Contents/Library/vmrun' -T fusion -gu " & winUserName & " -gp " & winPassword & " runProgramInGuest '/pathtovmshere/win.vmx' -interactive 'c:\\windows\\system32\\cscript.exe' 'c:\updateHosts.vbs'"
end if

This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *