How to handle files in case-sensitive way in Vagrant on Windows host - linux

On My Windows 8 I've installed VirtualBox + Vagrant. I used Laravel Homestead (with Ubuntu) as box. When running site on this VM or running command line I would expect it is being run on Linux and not on Windows. But I found some strange issue:
First my folder mappings:
folders:
- map: D:\DaneAplikacji\easyphp\data\localweb\projects\testprovag\strony
to: /home/vagrant/code
sites:
- map: learn.app
to: /home/vagrant/code/my-first-app/public
When I run in my browser http://learn.app:8000 I got correct output - page from /home/vagrant/code/my-first-app/public what is the same as code from D:\DaneAplikacji\easyphp\data\localweb\projects\testprovag\strony\my-first-app/public just to be clear.
Now the problem:
In my public folder I've created 2 simple files:
File with name test (it's empty) and file index.php with content:
<?php
if (file_exists('TEST')) {
echo "file exists";
}
else {
echo "file NOT exists";
}
So now I run http://learn.app:8000 in browser and I get output file exists. This is the result I wouldn't expect. As far as I know in Linux (my box is Ubuntu) you may have files with different case in names (in opposite to Windows) so I would expect I got file NOT exists.
I've tested it in my VM running php index.php and I get exact same result file exists what is again unexpected.
Now what I did I copied those 2 files to other directory on my VM /home/vagrant/TESTS - this directory is not mapped using Vagrant. Now when I run php index.php I get file NOT exists what is expected result.
To be honest I completely doesn't understand it. Question - does PHP when using Vagrant mapping operating on VM filesystem (in this case Ubuntu) or on Virtual BOX host filesystem (in my case Windows). Is there any way to make it work to get desired result? I know this question might be a bit software related but it's really connected to PHP and Laravel and maybe I miss something here.

I think this issue can be solved not using Samba or too much work.
In Windows cmd I run:
vagrant plugin install vagrant-winnfsd
It installed a plugin for NFS for Windows although at http://docs.vagrantup.com/v2/synced-folders/nfs.html you have clear info that NFS doesn't work for Windows:
Windows users: NFS folders do not work on Windows hosts. Vagrant will ignore your request for NFS synced folders on Windows.
I modified my Homestead.yaml file mapping from:
folders:
- map: D:\DaneAplikacji\easyphp\data\localweb\projects\testprovag\strony
to: /home/vagrant/code
to:
folders:
- map: D:\DaneAplikacji\easyphp\data\localweb\projects\testprovag\strony
to: /home/vagrant/code
type: "nfs"
(probably if not using Homestead.yaml you can add type: nfs, something like that: config.vm.synced_folder ".", "/vagrant", type: "nfs" in your Vagrantfile)
Now when I run
vagrant up
I got 2 or 3 notices for admin password (probably some Windows configuration of NFS - it will appear only when I run vagrant up first after adding NFS type) but now both for using url http://learn.app:8000 I got for the case from question file NOT exists and the same when I run php index.php in box commandline.
Note: this solution doesn't make you can create test and TEST files in the same directory and you will have them in your file system. It seems to handle file in case sensitive way, so if you create a file in wrong case in your app (and later in your code you want to load it/require) you will notice that it doesn't work on your Vagrant Linux box (and it would work on Windows WAMP and you would be suprised when moving on production).

With the default vagrant share that you use the mounted folder still provided by the underlying file system. It won't handle linux ACLs properly either.
One solution we found for this is instead of sharing the host's folder with the client, we set up samba on the guest and shared it back to the host. It's more cumbersome and you have to do more configuration but at least you app runs in an environment as it should be

Interesting. I use Windows 7 with Homestead - and I also assumed that the case sensitivity file issue would be handled by Vagrant. But I ran some similar tests - and you are correct - it is actually case insensitive.
I can confirm the issue is not to do with PHP at all - the issue actually occurs inside Vagrant on the command line itself:
touch EXAMPLE
rm example
That passes on the Vagrant box when I am SSH into it. But on a real Ubuntu box (I tested it on my server) - that command fails.
The reason is that Vagrant is calling to Windows to check if the file exists for the mapped folders. But if you make a virtual non-mapped folder inside of Vagrant - then the 'call' to see if the file exists remains inside of Vagrant and thus handled only by Ubuntu - and that is why your other test passed.
I tried turning on Case Sensitivity for Windows 7 as documented here - but it didnt solve the problem

Related

Can you help me access Mac SMB share from Ubuntu using smbclient? (NT_STATUS_ACCESS_DENIED error)

I've been working on a file server product that uses smbcilent to transfer files between client computers and the server. It's been working great so far with our LAMP (Ubuntu) server and Windows machines.
I'm currently trying to expand the setup to include Mac's, but am having trouble with the server accessing the share on the Mac.
Here's my command and error (bracketed descriptions replace private info):
# smbclient //10.101.0.7/[share-file] -U [username]%[password] -c ls
WARNING: The "syslog" option is deprecated
NTLMSSP packet check failed due to short signature (0 bytes)!
NTLMSSP NTLM2 packet check failed due to invalid signature!
session setup failed: NT_STATUS_ACCESS_DENIED
Things I've tried:
✓ Accessing share using a Windows machine to ensure the share is setup properly - check! Works fine there.
✓ Invoking -S off or --signing=off in the command - no change.
✓ Just looking at the shares first using smbclient -L 10.101.0.7 -U [username]%[password] - same error.
✓ Googling for an answer - check! Several people with similar problems, but no working solutions so far.
The most promising thing I've see so far involves compiling smbclient 4.4 from sources and running that with no authentication (-U ""%""), but that seems like a temporary solution based on a bug rather than a solid plan that will work for a long time. (But I'll try that next if I can't find any better ideas...)
Thanks for reading and trying to help!
Try adding --option="ntlmssp_client:force_old_spnego = yes" to the smbclient command as suggested on the samba-technical mailing list.
For me, this now lists shares on a Mac OSX server:
smbclient -U$user%$password -L $mac_host --option="ntlmssp_client:force_old_spnego = yes"
For mounting, you may need to add the nounix,sec=ntlmssp options as in
sudo mount -t cifs //$mac_host/$share $mountpoint -o nounix,sec=ntlmssp,username=$user,password=$password
On recent versions of MacOS (e.g. Monterey) it is necessary to do several configuration steps to enable smb access from Linux:
Open System Preferences.
Select Sharing.
Select File Sharing.
Ensure that the directory is listed in Shared Folders.
Right-click/two-finger click on the share directory.
Click on Advanced Options
Ensure Only allow SMB encrypted connections is checked.
Click OK
Click on Options
Click on the checkbox for Share files and folders using SMB.
Under Windows File Sharing ensure the appropriate user is checked.
Type the user's password in the 'Authenticate' dialog bo and press 'OK'.
Click 'Done'.
You should now be able to connect from Linux to the MacOS share using the commands given by #mivk.

Ansible doesn't work when user home directory mounted on NFS volume

Here is the situation. I got a number of hosts that I'd like to maintain via Ansible. The baseline configuration of the hosts like logins/users/etc is controlled by corporate IT overlords, so I can only change things that are related to application not general host setup. Some of the tasks related to application require running as 'root' or some other privileged user.
I do have a password-less sudo access on all the hosts, however all user home directories are located on NFS mounted volume. From my understanding how ansible works it first logs in into the target host as a regular user and places some files into $HOME/.ansible directory, then it switches to root user using sudo and tries to run the stuff from that directory.
But here is the problem. As I mentioned above the home directories are on NFS volume, so after ansible process on the target machine becomes root it can no longer access the $HOME/.ansible directory anymore due to NFS restrictions. Is there a way to tell ansible to put these work files outside of home directory on some non-NFS volume.
There were two parameters for the ansible.cfg configuration file introduced in Ansible 2.1 which allow specifying the location of temporary directory on target and control machines:
remote_tmp
Ansible works by transferring modules to your remote machines, running them, and then cleaning up after itself. In some cases, you may not wish to use the default location and would like to change the path. You can do so by altering this setting:
remote_tmp = ~/.ansible/tmp
local_tmp
When Ansible gets ready to send a module to a remote machine it usually has to add a few things to the module: Some boilerplate code, the module’s parameters, and a few constants from the config file. This combination of things gets stored in a temporary file until ansible exits and cleans up after itself. The default location is a subdirectory of the user’s home directory. If you’d like to change that, you can do so by altering this setting:
local_tmp = $HOME/.ansible/tmp

Vagrant shared folder without sync

How can I have a shared folder (access to the same folder from both host and guest machines) WITHOUT any syncing method running? (I want to use my own rsync script which is exactly what I need without the Vagrant file sharing performance penalties).
I have tried
config.vm.synced_folder ".", "/vagrant", disabled: true
but it disables the entire share.
I'm using Vagrant 1.8.1 on Windows 7 (host) with Virtualbox 5.0.12 and guest OS is Ubuntu 12.04.
You can indeed share a folder simply using the VirtualBox Manager.
Disable the Vagrant synced folder (in the vagrantfile):
config.vm.synced_folder ".", "/vagrant", disabled: true
Install Guest Additions to VirtualBox
Open VirtualBox Manager and select Settings > Shared Folders > Adds new shared folder (sic)
Add your host path in "Folder Path:" and your guest name (eg FolderName) in "Folder Name:"
Your guest name will appear in the guest linux in /media/sf_FolderName
Give your preferred guest user access to the folder. I did sudo adduser vagrant vboxsf and sudo chmod 777 /media/sf_FolderName and it DID NOT WORK for me - vagrant user still gets permission denied. Those commands seem to have worked for others, but I have ended up just working as root, which does have access.
Incidentally, here's my rsync formula (with a watch that polls every second) which works really well for me.
sudo watch -n 1 rsync -avh --delete --exclude-from=/media/sf_FolderName/FOLDERTOCOPY/rsync-exclude.txt /media/sf_FolderName/FOLDERTOCOPY /path/to/destination
NOTE: It works only if you're making changes on the host (eg developing using editor in Windows in my case). If you're making changes on the guest (eg git pull) you're gonna wanna stop this the watch/rsync from running and manually copy back in the other direction. Not ideal, but at least developing with this setup is fast.
Thanks to Frederic Henri for nudging me in this direction.

Synced folders lost when rebooting a Vagrant machine using the Ansible provisioner

Vagrant creates a development environment using VirtualBox and then provisions it using ansible. As part of the provisioning, ansible runs a reboot and then waits for SSH to come back up. This works as expected but because the vagrant machine is not being started from a "vagrant up" command the synced folders are not mounted properly when the box comes back up from the reboot.
Running "vagrant reload" fixes the machine and mounts the shares again.
Is there a way of either telling vagrant to reload the server or to do all the bits 'n bobs that vagrant would have done after a manual restart?
Simply running "sudo reboot" when SSH-ed into the vagrant box also produces the same problem.
There is no way for Vagrant to know that the machine is being rebooted during the provisioning.
If possible, the best would be to avoid rebooting here altogether. For example kernel updates should be already done when building the base box.
Another easy (but not very convenient) way is to handle it with log output or documentation, or with a wrapper script which invokes vagrant up && vagrant reload.
And finally, you could write a plugin which injects all the needed mounting etc. actions to Vagrant middleware stack after the provisioning, but you would still need to think how to let the plugin know that the machine has been booted. Other challenge is that this easily gets provider specific.
You should be able to add the filesystems to /etc/fstab to mount on boot.
Here's my example:
vagrant /vagrant vboxsf defaults 0 0
home_vagrant_src /home/vagrant/src vboxsf defaults 0 0
home_vagrant_presenter-src /home/vagrant/presenter-src vboxsf defaults 0 0
Your vagrant directory should have a .vagrant hidden directory in it, and in there you should find a path to the "synced_folders" file (in my case: /vagrant/.vagrant/machines/default/virtualbox/synced_folders).
That file should help you figure out what the labels are and their mount points:
{"virtualbox":{"/home/vagrant/src":{"guestpath":"/home/vagrant/src","hostpath":"/home/rkomorn/src","disabled":false,"__vagrantfile":true},"/home/vagrant/presenter-src":{"guestpath":"/home/vagrant/presenter-src","hostpath":"/home/presenter/src","disabled":false,"__vagrantfile":true},"/vagrant":{"guestpath":"/vagrant","hostpath":"/home/rkomorn/vagrant","disabled":false,"__vagrantfile":true}}}
It's not the easiest to read but, using python terminology, the labels appear to be the inner dictionary's keys, with / translated to _ (eg: the /home/vagrant/presenter-src key became the home_vagrant_presenter-src label).
I'm actually not sure why vagrant doesn't just use /etc/fstab for shared folders but I'm guessing there's a good reason.
Split your provisioners into two separate steps and use the vagrant-reload plugin as additional provisioner between.
Example Vagrantfile:
config.vm.provision "Step 1 - requires reboot", type: "shell", path: "scripts/part1.sh"
config.vm.provision :reload
config.vm.provision "Step 2 - happens after reboot", type: "shell", path: "scripts/part2.sh"
In case anyone else runs into this issue and finds this question like I did here's how I worked around the issue:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "..."
# create a shared folder for the top-level project directory at /vagrant
# normally already configured but for some reason it isn't on these boxes
# https://www.vagrantup.com/docs/synced-folders/virtualbox.html#automount
# http://www.virtualbox.org/manual/ch04.html#sf_mount_auto
config.vm.synced_folder ".", "/mnt/vagrant", id: "vagrant", automount: true
config.vm.provision "shell", inline: "usermod -a -G vboxsf vagrant"
config.vm.provision "shell", inline: "ln -sfT /media/sf_vagrant /vagrant"
# More settings omitted...
end
There's a few parts to this solution:
The first line assigns a specific id of vagrant to the shared folder. This is important because the automatic mount functionality in VIrtualBox uses /mnt/sf_<id> by default. It also mounts the folder at /mnt/vagrant to keep it out of the way. Ideally you'd pick a more obscure location that's present on all of your VMs or just document not to use it there.
The third line creates a symbolic link from the automatic mount location at /mnt/sf_vagrant to the usual place users expect the shared folder at /vagrant.
The second line adds the vagrant user in the virtual machine to the vboxsf group. This is necessary to access files inside /mnt/sf_vagrant because the guest utilities mount the folder with root:vboxsf ownership. They also set appropriate file and directory modes so it works fine in practice but you do need to be a member of the vboxsf group.
This solution has the following benefits:
The mount at /mnt/sf_vagrant is automatically mounted by the virtualbox guest utilities after a reboot so /vagrant should always be available.
It does not require installing plugins or using any outside tools.
It has the following drawbacks:
Potential for unexpected behavior if users find and use the /mnt/vagrant mount. That mount will only be present if the virtual machine was most recently booted / rebooted through the vagrant console client otherwise it will not be present.
It requires a relatively recent version of VirtualBox and Vagrant.
EDIT: Added -T option to ln to avoid the corner case where it creates /vagrant/sf_vagrant as a symlink.
I had a same issue. This is what I had in my /etc/fstab.
#VAGRANT-BEGIN
# The contents below are automatically generated by Vagrant. Do not modify.
vagrant_data /vagrant_data vboxsf uid=1000,gid=1000,_netdev 0 0
vagrant /vagrant vboxsf uid=1000,gid=1000,_netdev 0 0
#VAGRANT-END
So if you see fstab entry is still there, all you have to do is run sudo mount -a to trigger mount again. Or you can copy this lines.

Cygwin home directory on target system inconsistent

I am having difficulty connecting to a remote Windows system running cygwin.
When I connect from a linux box to cygwin, it connects fine and "sees" the
remote home directory as /home/userID
When I connect from Windows cygwin to the remote windows cygwin, it sees
the home directory as /cygdrive/c/Documents and Settings/UserID
Finally, when I am logged onto the remote Windows machine (the one with the problem)
home is /home/UseID but the value for cygpath -H is
$ echo $(cygpath -H)
/cygdrive/c/Documents and Settings
This seems to be causing my connection problem from windows to windows
and no problem from linux to windows
Any ideas how to fix it?
Since you have the correct path in /etc/passwd, one possibility is that perhaps the SSH client you are using from your Windows systems is sending custom environment values.
If you're using PuTTY, before connecting, look in the tree panel on the left hand side of the dialog. There should be an entry called Connection and a sub-entry called Data which will bring you to an option screen that has a section called Environment variables. Check if the HOME var is being overridden there and if so, remove it.
If you're using a different SSH client, check its configuration to see if its using the SendEnv option. More info on that here: http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config.
Or you could try blocking off custom environments on the destination/server side by disabling AcceptEnv in the SSHd configuration on the system you're connecting to. More info on that here: http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config.
Hope this helps.

Resources