FOG deployment in remote office

  • Hi all

    I am considering deploying a FOG server in a remote office. I read about a storage node and then I saw that it does not do DHCP, TFTP and PXE by default but there is a [URL=‘’]guide[/URL] to enable it.

    Is it not possible just to have a master node in main office and storage node in remote office and change the DHCP scope on a Domain Controller to look at my main FOG server for PXE boot? If I did this would clients in my remote office pull images from the storage node or from the main FOG server?

    Thx in advance

  • Good luck! Sorry for the wall of text.

    If you feel like getting in to it, in order to get the boot package to get sent to the right location, you could take a look at the following lines (for example, inside function createInventoryPackage() in functions.include.php):

    $ftp = ftp_connect(getSetting( $conn, “FOG_TFTP_HOST” ));
    $ftp_loginres = ftp_login($ftp, getSetting( $conn, “FOG_TFTP_FTP_USERNAME” ), getSetting( $conn, “FOG_TFTP_FTP_PASSWORD” ));

    If you feel like getting in to a more “correct” way of doing this, I think the issue with getting the boot files pushed to the correct locations is that $conn is (correctly) looking at the master node since that’s where MySQL lives, so the “FOG_TFTP_HOST” information it receives are the master node settings. I [I]think[/I]. I’m not positive on that. I was thinking of switching it so it gets its information from the config.php file located on the service, but there are a [I]lot[/I] of calls to the MySQL based getSetting function. It might take a lot of changes to rework that.

  • OKay, I will take a look, make backups and test.

  • Alright. Got home from classes, and switched computers so I could grab my notes. Of course I have to say be really careful with all of this: if something goes wrong, it will most likely make your production system not functional. Try to do all this on a test system instead of a production system, if at all possible. At least make backups/take notes of what you all changed.

    I have attached the list of my notes of what I all had to change to get it working. I’d attach the files themselves… but I have a lot of other changes inside these files as well, so I tried pulling out the only changes you’d need to get subnet / location based image push.

    Couple of things:

    []The subnets I’m working with are, 192.168.14., and 192.168.24.* – make sure you change the instances of this to match your subnets.
    []When FOG determines where to put the boot file named after the client’s MAC address, it is still placed on the master node. With the synchronization methods put forward by that guide, it will be duplicated across all nodes and this isn’t technically an issue.
    ]Any changed files need to be sync’d (or at least copied) to the remote nodes from the main node.
    []Here’s the part I feel could be done better: Inside functions.include.php the line “$command=”/sbin/ifconfig eth0 | grep ‘inet addr:’ | cut -d: -f2 | awk ‘{ print $1}’";" is actually executed on the server side. When I started working on this, I thought it would execute on the client side. The end result is that it still finds the correct subnet, but there has to be a better way to do this. At the very least, all of the array functions wouldn’t be necessary. You could probably just compare full IPs. I have a couple ideas for more sophisticated changes, but I haven’t gotten to test them yet. The joys of being a full time student and trying to do all this in the middle of an IT support internship…
    ]So, in order to get this to run correctly, I ran into a few problems – since the folder containing the boot file “default” is being mounted on remote nodes, and since the boot files for specific MAC addresses are also in this location on the main node, I had to keep this mounted. The change involving overriding the “web” variable in S99fog inside init.gz is a workaround. A bit strange, but it works. I need to work out a solution to unmount those drives, and get the specific boot files placed in the right location in the first place. Shouldn’t be too difficult, but I haven’t had the time.
    Let me know if you run into any issues, and I’ll help you the best I can. I’m definitely not a FOG expert, by any means, but I’ll try.


  • Okay, that is basically what I want to do. I have the multiple TFT/ PXE servers setup, one per location and a master at the main campus. I would like the local PXE server (storage node) to service the image like you suggested. I will be looking forward to your changes/ suggestions. Thanks.

  • Yup! … Well, sort of. I don’t really do the delegation - it just picks it automatically based on the subnet. I’m actually at school right now, and all my FOG notes / custom changelogs are stored on my work computer which I don’t have with me. It actually ended up being slightly more complicated than just a few changes.

    [url][/url] <---- this is a good place to start. I have two remote nodes that both started with this setup (almost - my rsync setup is slightly different as I have more files I want to synchronize than suggested).

    Off the top of my head, I know it’ll take edits of about 3-4 PHP files, as well as a change somewhere to ensure that the bash WEB= variable set by the boot files is correct. Maybe. Currently I have it set up so the node you PXE boot through is the node that gets chosen, but it gets chosen in a strange roundabout sort of way. I might actually do some rework to get it working in a way that makes more sense, now that I actually know what’s going on.

  • So are you saying that you have a Master and two Storage Nodes and can delegate which Storage Node pushes out the image? I have a Master and two Nodes in Separate subnets and physical locations. We really want to have the multisite working for .32 and I don’t want to revert back to .31 at this time…any thoughts?

  • Got it. I’ll have to do more testing to verify that I haven’t broken anything going on behind the scenes, but if anyone is interested, drop a post here, and I can put together what I had to change to get this working.

    On a side note, question for someone who knows more about PHP than I do (which doesn’t take much at all, haha) - what’s the purpose of using the underscore in echos? As in the underscore in the following line after the echo:

    [PHP]echo _(“Error attempting to start imaging process”);[/PHP]

  • No bites yet, huh? 🙂

    Okay, more digging!
    I found that the item fog.tasks.taskNFSMemberID in MySQL (which corresponds to the StorageNode, if I understand it correctly) [I]is[/I] being set correctly. I added in some var_dump() and some sleep() into functions.include.php so it wouldn’t fly by and I could actually see this.

    Essentially, the correctly overwritten storage node is being placed in fog.tasks.taskNFSMemberID – [I]but! [/I]-- when the computer to be imaged is restarted and booted to pxe again, the taskNFSMemberID changes. Looks like some code somewhere (probably Pre_Stage1.php) is overriding the taskNFSMemberID. I’ll have to spend more time looking when I get a chance.

  • Well. Did some digging. So far no luck. I [I]thought[/I] I had a solution – but maybe someone here on the forums can help me out.

    The file auto.register.php calls the function getImageMemberFromHostID (from functions.include.php) which in turn creates and returns a $member object. $member is created with parameters that include $nodeid (which comes from the MySQL database -> fog.nfsGroupMembers.ngmID).

    After some testing, I know I have the logic behind my IP collection / string splitting / etc working correctly. I originally thought that was the problem.

    My question is this: Is the $nodeid variable stored inside $member functional, or has it been depreciated? As in, is that where FOG determines which node pushes the image to the computer?

  • Thanks for the link Kevin – I had taken a look at that, and I was hoping to get away without completely overhauling the MySQL databases. Wishful thinking, I’m sure, haha. I was going to attempt another route, after looking at the number of files that got changed. I’m currently running FOG 0.32, and I believe that patch only works with 0.31 (or that’s what users were reporting in the thread, anyways).

    I was considering doing it that way, Bryce. Or alternatively, just working with two FOG servers and using rsync or something to push the image files back and forth (or changing the fog replicator service to grab more than just the /images/ folder). But that way just seems like way more of a hassle in the long run, haha.

    I might dig to see if I can find where the group selection is in the code, and see if I can hack it apart – assuming I can find the time.

  • There was at one time a member of the FOG community that wrote a location patch to do something like that.

    When you set up a normal FOG installation and you create an image definition it gets tied to a Storage Group. You can set up multiple Storage Groups and multiple Storage Nodes as members of Storage Groups. When you upload an image it writes to the primary Node of the Group, and when you multicast it pushes from the primary Node of the Group; apart from that it’s all about load balancing. I don’t know the logic off the top of my head, but I think FOG just loads up one Node with deployments until its full and then checks the Group for the next Node.

    Without using the location patch, you can set FOG up to do what you want, but it gets a little ugly… Using one master Storage Group you add your remote Node to it, and create your master image pointing to the master Group, this way FOGSync will replicate the image between the master Node and the remote Node. Then you set up a remote Group and a second Node definition that matches the first remote Node except it uses the remote Group instead of the master Group. Then you set up a second image definition that matches the first image except it uses the remote Group. So now when you set up a host at the remote location you assign it to the remote image and it will only pull from the remote Group, and because the remote Node is in both Groups the image is just a copy of the image you first created on the master Group. Not the easiest setup, but it works.

  • This should be what you are looking for, however, I have not personally tried it.


  • I have a question to add on to this thread (which is related) – What about if the images for the remote office are the same as the images for the local office?

    How does FOG handle which storage node gets selected to push the image out? Would there be a way to, say, force the client to connect to the remote storage node which is on the same subnet as the client?

    I’m sure I could put together the code to determine IP/Subnet on the client, but I don’t know enough about how the storage node gets selected to move forward at that point, or if it’s even a reasonable possibility.

  • Hi BryceZ

    Thank you very much. I will go down that route then. Thank you


  • You [I]can [/I](assuming certain network configurations) have the remote office PXE boot off of your main FOG server, but unless this remote office is across the street, and you’re running at least 100Mb between the buildings, I wouldn’t suggest it. It’ll give you fairly poor performance.

    [url][/url] is probably the best advice without knowing a whole lot more about your environment. This way you’re still managing things from the main FOG server, but with the benefit of having all the heavy network access localized.

    As long as you configure your Storage Groups and Images correctly (meaning the remote office storage node is in a different storage group, and your images for the remote office use that storage group), in theory it’ll work like a charm.