I'm running a vagrant provisioning script and I'm trying to set the desktop background, but I can't get gsettings to take. It works fine at the command line, just not from the script. Everything else in the Vagrantfile works fine.
config.vm.provision "file", source: "image.jpg", destination: "~/image.jpg"
I use the file provision to move the file over, and then call gsettings from the non-sudo bootstrap.sh.
config.vm.provision :shell, path: "sudo-bootstrap.sh"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
In bootstrap.sh:
gsettings set org.gnome.desktop.background picture-uri file:///home/vagrant/image.jpg
I read about there not being a DBUS Session bus address, but adding the line to get the PID didn't work in the provisioning script. Also found it was perhaps missing schemas, but I don't have any schemas in .local.
Been hammering at this for a few hours now, no idea what I'm missing.
While the accepted answer to the DBUS Session question didn't work for me, the linked answer under it did, Run DBUS.
dbus-launch gsettings set ...
Related
I have a fairly vanilla Vagrant setup running trusty64. It's being configured by a single shell file. Among others, it contains an aliasing of python3 to python and pip3 to pip, respectively:
echo "Writing aliases to profile:"
echo "alias python=\"python3\"" >> ~/.profile
echo "alias pip=pip3" >> ~/.profile
. ~/.profile
For some mysterious reason, these lines never make it into ~/.profile. There is no error message, nor any other commotion, it's just that nothing happens. This being 2am, I am fairly sure I'm doing something wrong, I just can't figure out what it is.
I am pretty sure you're calling the provisioner with something like
config.vm.provision "shell", path: "bootstrap.sh"
This works well but its executed as root user so all the lines are added for this user only. You want to use the privileged option
privileged (boolean) - Specifies whether to execute the shell script
as a privileged user or not (sudo). By default this is "true".
config.vm.provision "shell", path: "bootstrap.sh", privileged: "false"
will execute as your vagrant user and will add lines in to /home/vagrant/.profile file
I installed StackEdit on Vagrant. I would like to start Vagrant and StackEdit by one click.
I created bash script:
#!/bin/bash
vagrant up
#ssh -p 2222 -i /d/stackedit/.vagrant/machines/default/virtualbox/private_key vagrant#127.0.0.1 -t '/home/vagrant/Code/start_server.sh'
start "C:\Program Files\Mozilla Firefox\firefox.exe" http://stackedit.app:5000
and start_server.sh in VM
if [ $(ps -e|grep node|wc -l) = "0" ] ; then
(export PORT=5000 && node Code/Project/public/stackedit/server.js) &
fi
sleep 5
exit 0
If I run start_server.sh via ssh manualy everything works, but when I try it with ssh in start script - now commented line - server doesn't run.
I tried copy this script to /ect/rc.local, but the result is same.
I tried add #reboot /home/vagrant/Code/start_server.sh to crontab -e too, but without success.
Can anyone help me?
My system is Windows 10. I use Git Bash.
you should put everything in your Vagrantfile
#Run provisioning
You can run your script from Vagrantfile using a shell provisioner
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh"
end
check, you have some options by default it will run as root so you can change if you want to run your script as vagrant user
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh", privileged: false
end
and also you can make sure you run your script everytime you boot the VM (by default it runs only once or when calling specifically the provision parameter)
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh", run: "always"
end
#opening the website after the system is running
Vagrantfile is a ruby script so you can call any command from the file, but it will run the command immediately and in any occasion.
Then, if you want to run after the box is started, you can use the vagrant trigger and do something like
Vagrant.configure(2) do |config|
.....
config.trigger.after :up do |trigger|
trigger.run = {inline: 'system("open", "http://stackedit.app:5000"')
end
end
I have the following line in my Vagrantfile:
config.vm.provision :shell, path: "provisioning/myscript.sh"
I would like to toggle running that script based on an environment variable being set in the host (which may not be present). If the value is present and equals true I want the script skipped, otherwise it should run e.g.
if [ ENV[SKIP_MY_SCRIPT] != 'true' ]
config.vm.provision :shell, path: "provisioning/myscript.sh"
end
Or is there a better way (e.g. pass env into the script somehow)?
As Vagrantfile is mainly a ruby script, there's no bad to have conditional statement in the file.
To answer the specific question How to pass host environment variable to provisioning script (can help for other use cases) you can pass arguments like
username = `whoami`.chomp
config.vm.provision "shell", privileged: false, path: "provisioning/config-git.sh", args: "#{username}"
and in your script, you read as
#!/usr/bin/env bash
username=$1
I was reading a tutorial in bash where they said to restart the machine, there was no option to restart a service directly, it was a matter of restarting the machine, and then there were more commands after that that still needed to be run when provisioning.
So is there any way to restart a box amid provisioning and then pick up where you left off after that?
As far as I know you can't have a single script/set of commands that would carry on where it left off if it attempts to restart the OS, such as:
config.vm.provision "shell", inline: <<-SHELL
echo $(date) > ~/rebootexample
reboot
echo $(date) >> ~/rebootexample
SHELL
In this example the second echo call would not be carried out.
You could split the script/commands up and use a plugin such as vagrant reload.
An example snippet of a Vagrantfile to highlight its possible use:
# execute code before reload
config.vm.provision "shell", inline: <<-SHELL
echo $(date) > ~/rebootexample
SHELL
# trigger reload
config.vm.provision :reload
# execute code after reload
config.vm.provision "shell", inline: <<-SHELL
echo $(date) >> ~/rebootexample
SHELL
I've never done this, but if I had to I would split the script into two pieces, one before restart that includes the restart command, then another that's post install.
The first one would also create a lock file.
The overall script would run the first script if the lock file didn't exist or run the second one if the file exists. This overall script would be set up for startup.
One trick you can employ is to send restart signal and save rest of the provisioning work as a script to be run on boot:
config.vm.provision "shell", inline: <<-SHELL
echo "Do your thing... DONE"
cat <<-RCLOCAL | sed -s 's_^ __' > /etc/rc.local
#!/bin/bash
echo "This will be run once on next boot and then it's destroyed and never run again"
rm /etc/rc.local
RCLOCAL
chmod o+x /etc/rc.local
shutdown -r now #restart
SHELL
This was tested to work on debian 9, so you may need to enable services or find another way to get your code bootsrapped to run on the next boot if you're running something else.
Unfortunately you can't simply do:
config.vm.provision "shell", inline: "shutdown -r now"
config.vm.provision "shell", inline: "echo 'hello world'"
results in ==>
The SSH connection was unexpectedly closed by the remote end. This
usually indicates that SSH within the guest machine was unable to
properly start up. Please boot the VM in GUI mode to check whether
it is booting properly.
Vagrant has a reboot option for provisioning, however, the reboot guest capabilities is currently not support for Linux.
You can check my plugin out here, https://github.com/secret104278/vagrant_reboot_linux/tree/master , I've implement the function for Linux to reboot.
This can be done like so:
config.vm.provision 'shell', path: 'part1.sh'
config.vm.provision 'shell', reboot: true
config.vm.provision 'shell', path: 'part2.sh'
https://developer.hashicorp.com/vagrant/docs/provisioning/shell#reboot
I'm on a Windows host using Git Bash to run the .sh files.
There are 4 components to my current project. To start up it on localhost, I have to:
webdriver-manager start since I'm the QA and need that running anyway
vagrant up in the project's parent folder, then close out that window (or just start the VM myself via VirtualBox UI)
vagrant ssh cd /vagrant cd "component's folder" docker-compose up x 4
grunt serve
Right now, I have a .sh file each for 1, 2, and 4, but I cannot find how to pass along multiple commands to vagrant ssh, especially since docker-compose up needs to be constantly running.
Is there a way to pass along those cds and the docker-compose?
I found the ssh documentation from vagrant which mentions something about needing to do fancy things to get it running background processes, but I have no idea what it's doing or how to implement that in a .sh file since the wording is so wishy-washy.
Also, I'm new to shell scripts in general, so if there's a smarter way to go about this to solve the issue, I'd appreciate it, too. These scripts aren't necessary, I just don't want to have to type it repeatedly every day when I'm running my tests locally.
From your Vagrantfile, have something like this
$script = <<SCRIPT
echo "running script in the VM"
cd /vagrant
cd "component's folder"
docker-compose up
cd "component's folder 2"
docker-compose up
# and add all other commands you would run from the VM
SCRIPT
Vagrant.configure(2) do |config|
....
config.vm.provision "shell", inline: $script
....
end
Note: this will run the commands as sudo (from your VM) if you want to run them as your vagrant user, just do
config.vm.provision "shell", inline: $script, privileged: "false"
If the commands needs to be invoked on vagrant up, you can provide provisioning script available on the host machine by:
config.vm.provision "shell", path: '/vagrant/scripts/provision.sh'
so Vagrant will then upload this script into the guest and execute it (using URL instead of path would also work),
Alternatively you may use inline shell syntax:
config.vm.provision "shell", inline: "echo Hello, World"
Or to run the script within VM, then try:
config.vm.provision "shell", inline: %Q(/usr/bin/env VAR=1 bash /vagrant/script.sh)
To run one-time off commands in VM, you may use vagrant ssh command for that, for example:
vagrant ssh -c "cd /vagrant && echo Hello, World"