Manually specify location of .vagrant folder in Vagrantfile - build

The folder where I have Vagrantfile is being auto-generated during the build, so it gets cleaned up, but I'd like to still be able to use the created machines. The easiest way would be to put .vagrant folder somewhere outside the auto-generated folder. Is this possible?

You have (at least) two options:
Use VAGRANT_DOTFILE_PATH to set the the location where the project specific data is stored (defaults to .vagrant as you already know). Note that the path has to be project/Vagrantfile specific.
cd to a directory where you want the .vagrant directory to be created, and use VAGRANT_VAGRANTFILE to specify the path to the generated Vagrantfile.

I know this is an old question, but for anyone arriving here via Google, there is a workaround if you really want to specify the metadata directory without mucking about with environment variables each time. Just put this in the top of your Vagrantfile:
VAGRANT_DOTFILE_PATH = 'custom/dotfile/path'
if(ENV['VAGRANT_DOTFILE_PATH'].nil? && '.vagrant' != VAGRANT_DOTFILE_PATH)
puts 'changing metadata directory to ' + VAGRANT_DOTFILE_PATH
ENV['VAGRANT_DOTFILE_PATH'] = VAGRANT_DOTFILE_PATH
puts 'removing default metadata directory ' + FileUtils.rm_r('.vagrant').join("\n")
system 'vagrant ' + ARGV.join(' ')
ENV['VAGRANT_DOTFILE_PATH'] = nil #for good measure
abort 'Finished'
end

I wanted each provider to use a separate Vagrant directory to easily be able to swap between them. I could not get #hairraisin's solution to work, but based on that I ended up with the following:
Vagrant.configure('2') do |config|
config.vm.provider :lxd do |lxd, override|
if ENV['VAGRANT_DOTFILE_PATH'].nil?
ENV['VAGRANT_DOTFILE_PATH'] = '.vagrant-lxd'
puts 'Removing default metadata directory ' + FileUtils.rm_r('.vagrant').join("\n")
exec 'vagrant ' + ARGV.map{|arg| Shellwords.escape arg}.join(' ')
end
…
This avoids endless recursion or aborting too early. exec rather than system avoids a non-zero exit code from every vagrant command.

Related

How to perform a quick check if the file directory for a script in matlab is correct?

I have a script which relies on different files located in specific folders which are important to run the script without errors. In order to define the path location I decided to create many variables with the according path location name as string:
file directory var file directory location % default entries which
% only work with my computer
fd_1 = '\C:\Testrun\pathfinder.xls\';
fd_2 = '\C:\Testrun\pathfilter.slx\';
fd_3 = '\C:\Testrun\splinegenerator.xls\';
fd_4 = '\C:\Testrun\loftcreator.xls\';
fd_5 = '\C:\Testrun\surface_to_volume.xls\';
fd_6 = '\C:\Testrun\stp_creator.xls\';
fd_7 = '\C:\Testrun\CAD_file.stp\';
fd_8 = '\C:\Testrun\CAD_support_1.atm\';
fd_9 = '\C:\Testrun\CAD_support_2.atm\';
fd_10 = '\C:\Testrun\CAD_support_3.atm\';
This allowed me to use my script on my computer. However this was a pretty static solution which only works for one pc. Hence I need the following dynmamic routine to be coded:
0.) I created a while loop in order to rerun my script with the switch case/expression:
<<<here is the missing code for the file directory check>>>
%(I wanted to use the "strcmp" command to compare the strings with each other?)
<<<Here is my code with the specific while loop to rerun it>>>
1.) Before I enter this loop need to perform a quick check, if the files are correctly located.
2.) If the file directory cannot be assigned to the specific variables responsible for the file
directory name (e.g directory could not be found), a new file directory will be choosen by the
user
3.) The newly choosen file directory will be stored with the default file directory in a list
4.) The variable responsible for the file directory changes according to the list index which the
user choose from the list of stored file directory names
5.) The selection of the specific list index as well as the changes in the list will be permenantly
stored (The changes in the list should be saved and recalled again in the script upon rerunning
or exiting/reopening the script)
6.) The list index can be deleted if the user is unsatisfied with the file directory (e.g due the
file directory corruption)
Is it possible to write such a code and how would it be structered?
I think to put all those folders and files in the same path of main program, by this way, no need to mention drive letter like c:\ or d:, just mentiob folder name and its subfolders, and you can copy the main folder and run your program in another computer without changing anything, just run the main program.

Trace32 Write directory location to file

So I finally decided to bite the bullet and rewrite my company's terrible Trace32 scripts. I'm trying to use a data file to save the pertinent information between runs so we can just run a Redo script to repeat any action without having to navigate a mess of dialog boxes and select our workspace files after every power cycle. In order to do this, I will need to save the user defined variables from the previous run (including file locations) to file so I have them in the next run. For reference, here is a part of my menu script.
; File: Do.cmm
GLOBAL &WORKSPACE
GLOBAL &FILETOLOAD
GLOBAL &TARGETSELVAL
&WORKSPACE="//tsclient\Z\Product_trunk_MS" ; Not the ideal solution
PRINT "Workspace is &WORKSPACE"
DIALOG
(
HEADER "Do one of the following"
POS 0. 0. 23.
COMMAND.PREVIOUS: CHOOSEBOX "Repeat Last Command" ""
POS 24. 0. 23.
COMMAND.WORKSPACE: CHOOSEBOX "Change Workspace Location" ""
POS 0. 3. 25.
TEXT "Connect To an R7 Proc:"
POS 0. 4. 6.
COMMAND.IP0: CHOOSEBOX "IP0" ""
POS 8. 4. 7.
COMMAND.IP1: CHOOSEBOX "IP1" ""
; And a lot more of the same...
POS 17. 16. 15.
DEFBUTTON "OK" "continue"
)
DIALOG.SET COMMAND.PREVIOUS
STOP
IF DIALOG.BOOLEAN(COMMAND.IP0)
(
&TARGETSELVAL=0x00030000
&FILETOLOAD="&WORKSPACE\CPUs\IP0\build\output\IP0.axf"
)
IF DIALOG.BOOLEAN(COMMAND.IP1)
(
&TARGETSELVAL=0x0003001
&FILETOLOAD=&WORKSPACE\CPUs\IP1\build\output\IP1.axf
)
... And so on
The problem with this is that I have to edit the script every time I change workspaces. I want to be able to set this in the script above by selecting COMMAND.PREVIOUS and then selecting my new workspace root with the Windows selection dialog. I don't have a working implementation for that function, but I want it to look something like this:
IF DIALOG.BOOLEAN(COMMAND.WORKSPACE)
(
PRINT "Select the new root directory that you would like to work out of."
OPEN #1 workspace.dat /Create
&WORKSPACE= C/*/ ; I don't know how to do this here.
WRITE #1 &WORKSPACE
CLOSE #1
ENDDO
)
Obviously, Data.load.binary "*.bin" is able to load a file to memory, but I don't need the file loaded yet, I just want the path. I did find that symbol.SOURCEPATH.SETBASEDIR c:\* will open a dialog box, but I am still having trouble getting at that information.
Additional Info
I have read through a lot of this and this while trying to find a solution. If there is a built in path variable that I should be using (like the aforementioned SOURCEPATH.SETBASEDIR, I wouldn't mind doing that instead. This is my first day writing Trace32 scripts, so I apologize in advance for my naivete. If it matters, I am using Trace32 Powerview for ARM Release Feb 2017 SP2 (32 bit) (So, the latest)
TRACE32 has the concept of a working directory. The command ChDir can be used to change the current directory:
ChDir <path>
The current working directory can be retrieved with the PRACTICE function OS.PWD():
&WORKSPACE=OS.PWD()
The script example above could be extended like this:
IF DIALOG.BOOLEAN(COMMAND.WORKSPACE)
(
PRIVATE &old_directory
&old_directory=OS.PWD() // Save current directory
ChDir * // Open directory selection dialog
&WORKSPACE=OS.PWD() // Update working directory
OPEN #1 workspace.dat /Create
WRITE #1 &WORKSPACE
CLOSE #1
ChDir &old_directory // Restore previous directory selection
)
I ended up finding a solution to my problem that was a little different than xasc's, so I thought I'd share it.
IF DIALOG.BOOLEAN(COMMAND.WORKSPACE)
(
PRINT "Select the new root directory that you would like to work out of."
DIALOG.DIR *
ENTRY %LINE &WORKSPACE
OPEN #1 workspace.dat /Create
WRITE #1 "&WORKSPACE"
CLOSE #1
)
This was a little cleaner for my purposes because it didn't require me to change the working directory.
DIALOG seems to be the interface I was looking for, with the ability to open files, directories, and more and save them into variables.

Windows up one directory from current path

I have been searching for hours but cant find a solution to this as yet. Apologies it is probably really simple.
My program is using CreateDirectory to create a new directory and then set the path to it to receive a number of data files:
if (CreateDirectory(dateTime.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError())
{
SetCurrentDirectory(dateTime.c_str());
}
Once all the data files have been generated I would like to move back up one directory without specifying the absolute path. Something equivalent to cd.. or ../ Does anyone know the best way to do this?
One possible approach is to get the current directory (GetCurrentDirectory) before changing to a new one and once complete, then change back the desired directory; akin to a push/pop.
In the sample I've left out error checking and buffer size requirements for simplicity.
TCHAR resetDir[1024] = {};
GetCurrentDirectory(1024, resetDir);
//... Do some work, change directories etc...
// Reset the directory
SetCurrentDirectory(resetDir);
Side note: the current directory when the process is launched is not necessarily the same as the directory the process image is in (the exe path).
Relative changes can be done with a simple
SetCurrentDirectory(_T(".."));
Although basing the relative from the current directory would also work (and may be preferable);
SetCurrentDirectory((currentDir + _T("\\..")).c_str());
Internally, cd command ends using SetCurrentDirectory. So to get something equivalent to cd.. or cd ../ you can simply use:
cr = ::SetCurrentDirectory("..");
cr should be non zero if it succeded and 0 if it failed. In the latter case use GetLastError to get further information.

vimrc to detect remote connection

At the moment I have to hard code the names of servers on my vimrc in order to either make it different on the remote machine. This is done by conditional statement using hostname() function in vim. I want to make the conditional to be based on the status of remote connection and not on the hostname. So...
The first possible solution I found was using the following bash command in system():
cat /proc/$PPID/status | head -1 | cut -f2
This does not work because I use GNU screen and this will not detect my connection status properly.
The second possible solution I am exploring right now is using who am i This reliably shows whether or not remote connection has been made from which client, but I have trouble getting it working with system()
if substitute(system('who am i'), "theclient", ????, "") == ""
...
How could I get ???? to extract my client name somehow??
Even if the second solution works, allowing me to use .vimrc for many different remote machines, it is still tied to one client. I want the conditional to work in all remote session, regardless of the client name. So I am wondering, is this possible?
The following line allows me to create a variable that detects the remote connection status:
let g:remoteSession = ($STY == "")
Now you can surround the lines that you want to be ignored in the remote connection via:
if g:remoteSession
...
endif
On a side note, I do not know how expensive it is look up the environment variable compared to the global variable, but I am guessing the difference is negligible. The system call in an environment like cygwin where fork() is inefficient, it is worth doing the optimization.
Instead of adding conditional logic to a shared ~/.vimrc, you could alternatively source system-local settings. I use the following:
" Source system-specific .vimrc first.
if filereadable(expand('~/local/.vimrc'))
source ~/local/.vimrc
endif
" Stop sourcing if inclusion guard exists.
if exists('g:loaded_vimrc')
finish
endif
" Common settings of .vimrc here...
I find this more scalable than trying to maintain an ever-changing list of hostnames in a central location.

Using getenv function in Linux

I have this following simple program:
int main()
{
char* v = getenv("TEST_VAR");
cout << "v = " << (v==NULL ? "NULL" : v) << endl;
return 0;
}
These lines are added to .bashrc file:
TEST_VAR="2"
export TEST_VAR
Now, when I run this program from the terminal window (Ubuntu 10.04), it prints v = 2. If I run the program by another way: using launcher or from Eclipse, it prints NULL. I think this is because TEST_VAR is defined only inside bash shell. How can I create persistent Linux environment variable, which is accessible in any case?
On my system (Fedora 13) you can make system wide environment variables by adding them under /etc/profile.d/.
So for example if you add this to a file in /etc/profile.d/my_system_wide.sh
SYSTEM_WIDE="system wide"
export SYSTEM_WIDE
and then open a another terminal it should source it regardless of who the user is opening the terminal
echo $SYSTEM_WIDE
system_wide
Add that to .bash_profile (found in your home directory). You will need to log out and log back in for it to take effect.
Also, since you are using bash, you can combine the export and set in a single statement:
export TEST_VAR="2"
Sorry if I'm being naive but isn't .bash_profile useful only if you are running bash as your default shell ?
I 'sometimes' use Linux and mostly use ksh. I have .profile so may be you should check for .*profile and export the variable there.
Good luck :)
There is no such thing as a system-wide environment variable on Linux. Every process has its own environment. Now by default, every process inherits its environment from its parent, so you can get something like a system-wide environment by ensuring that a var is set in an ancestor of every process of interest. Then, as long as no other process changes that var, every process of interest will have it set.
The other answers here give various methods of setting variables early. For example, .bash_profile sets it in every login process a user runs, which is the ultimate parent of every process they run after login.
/etc/profile is read by every bash login by every user.