Vagrant destroy execute ruby - ruby

I would like to execute a custom ruby code after doing vagrant destroy.
That's the code:
class OnDestroyMiddleware
def initialize(app, env)
#app = app
end
def call(env)
env["config"].vm.provisioners.each do |provisioner|
env.ui.info "Attempting to remove client #{provisioner.config.node_name}"
`knife client show #{provisioner.config.node_name}`
if $?.to_i == 0
env.ui.info "Removing client #{provisioner.config.node_name}"
`knife client delete #{provisioner.config.node_name} -y`
end
env.ui.info "Attempting to remove node #{provisioner.config.node_name}"
`knife node show #{provisioner.config.node_name}`
if $?.to_i == 0
env.ui.info "Removing node #{provisioner.config.node_name}"
`knife node delete #{provisioner.config.node_name} -y`
end
end
#app.call(env)
end
end
I'm trying this but isn't working:
Vagrant::Action[:destroy].use(OnDestroyMiddleware)
All of this code is from https://gist.github.com/skippy/1010660
I've got this error on Vagrant::Action[:destroy]
Message: NoMethodError: undefined method `[]' for Vagrant::Action:Module

You can look at the vagrant trigger plugin. It allows you to run code after a specific vagrant command.
First you need to install the plugin
$ vagrant plugin install vagrant-triggers
You'll add the code directly in your Vagrantfile, like
Vagrant.configure("2") do |config|
# Your existing Vagrant configuration
...
# run some script before the guest is destroyed
config.trigger.after :destroy do
info "Attempting to remove client..."
run "knife client show .."
end

Related

Expected "execute[Enable RHEL rhel7-x86_x64-linux-custom]" with action :run to be in Chef run

I have two Chef resource blocks that look like this within my recipe install_packages:
%w[rhel7-x86_x64-linux-custom rhel7-x86_x64-linux-latest].each do |repo|
execute "Enable RHEL #{repo}" do
command "yumtool -a #{repo}"
not_if { :: File.file?("/etc/yum.repos.d/#{repo}.repo") }
end
end
PACKAGES.each do |pkg_entry|
parts = pkg_entry.split('#')
pkg_name = parts[0]
pkg_version = parts[1]
yum_package pkg_entry do
allow_downgrade true
package_name pkg_name
version pkg_version
action: install
end
end
How would the corresponding spec unit test blocks look like? For the first block I've tried:
it 'executes command' do
expect(chef_run).to run_execute('Enable RHEL rhel7-x86_x64-linux-custom')
expect(chef_run).to run_execute('Enable RHEL rhel7-x86_x64-linux-latest')
end
but my Chef run fails with the error message:
expected "execute[Enable RHEL rhel7-x86_x64-linux-custom]" with action :run to be in Chef run. Other execute resources:
execute[Enable RHEL rhel7-x86_x64-linux-custom]
execute[Enable RHEL rhel7-x86_x64-linux-latest]
I'm unsure how to fix this, any ideas what the test blocks should look like?
I think your execute resources are not run, and that's why ChefSpec does not recognize run_execute(, but will recognize nothing_execute, I think).
Probably you have /etc/yum.repos.d/rhel7-x86_x64-linux-custom.repo file on your machine, and that's why the resource is not run. You need to stub the call before the ChefSpec::SoloRunner converges the recipe.
let :subject do
allow(::File).to receive(:file?).with('/etc/yum.repos.d/rhel7-x86_x64-linux-custom.repo').and_return(false)
allow(::File).to receive(:file?).with('/etc/yum.repos.d/rhel7-x86_x64-linux-latest.repo').and_return(false)
ChefSpec::Runner.new.converge described_recipe
end
If your PACKAGES constant is assigned like this:
# assignment real recipe:
PACKAGES = get_user_data_config('packages', [])
you can stub it in specs:
allow(Chef::Recipe).to receive(:get_user_data_config).and_return(<some value>)

Mina Deploy uses wrong user

I got some issue with the gem 'mina'. If I do set :user, 'username', he tries to connect to the server via Username#xxx.... wich is not working if the user is not existing. My PC is name Username. So mina setup and mina deploy are not working.
Does someone know a solution?.
Thanks
Best regards
Matze
EDIT:
Gemfile:
gem 'mina'
After that I run bundle install and mina init
deploy.rb:
require 'mina/rails'
require 'mina/git'
# require 'mina/rbenv' # for rbenv support. (https://rbenv.org)
require 'mina/rvm' # for rvm support. (https://rvm.io)
# Basic settings:
# domain - The hostname to SSH to.
# deploy_to - Path to deploy into.
# repository - Git repo to clone from. (needed by mina/git)
# branch - Branch name to deploy. (needed by mina/git)
set :user, "user"
set :application_name, 'appname'
set :domain, 'xx.xxx.xxx.xxx'
set :deploy_to, '/var/www/user/appname'
set :repository, 'user#xx.xxx.xxx.xxx:/home/user/git/appname.git'
set :branch, 'master'
# Optional settings:
# set :user, 'user' # Username in the server to SSH to.
# set :port, '30000' # SSH port number.
# set :forward_agent, true # SSH forward_agent.
# Shared dirs and files will be symlinked into the app-folder by the 'deploy:link_shared_paths' step.
# Some plugins already add folders to shared_dirs like `mina/rails` add `public/assets`, `vendor/bundle` and many more
# run `mina -d` to see all folders and files already included in `shared_dirs` and `shared_files`
# set :shared_dirs, fetch(:shared_dirs, []).push('public/assets')
set :shared_files, fetch(:shared_files, []).push('config/database.yml', 'config/secrets.yml')
# This task is the environment that is loaded for all remote run commands, such as
# `mina deploy` or `mina rake`.
task :remote_environment do
# If you're using rbenv, use this to load the rbenv environment.
# Be sure to commit your .ruby-version or .rbenv-version to your repository.
# invoke :'rbenv:load'
# For those using RVM, use this to load an RVM version#gemset.
# invoke :'rvm:use', 'ruby-1.9.3-p125#default'
end
# Put any custom commands you need to run at setup
# All paths in `shared_dirs` and `shared_paths` will be created on their own.
task :setup do
# command %{rbenv install 2.3.0 --skip-existing}
end
desc "Deploys the current version to the server."
task :deploy do
# uncomment this line to make sure you pushed your local branch to the remote origin
# invoke :'git:ensure_pushed'
deploy do
# Put things that will set up an empty directory into a fully set-up
# instance of your project.
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
on :launch do
in_path(fetch(:current_path)) do
command %{mkdir -p tmp/}
command %{touch tmp/restart.txt}
end
end
end
# you can use `run :local` to run tasks on local machine before of after the deploy scripts
# run(:local){ say 'done' }
end
# For help in making your deploy script, see the Mina documentation:
#
# - https://github.com/mina-deploy/mina/tree/master/docs
set :execution_mode, :exec if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
When I run now mina setup he print that:
$ mina setup
User#xx.xxx.xxx.xxx's password:
SSH Auth key working fine and git working fine he just puts User instead of user before the ip, what is not working because the user just exists with small letter. But my working machine is named User.

Rspec test failing against Docker container

DISCLAIMER: I am new to ruby,rspec etc. I am trying to find a test framework for my docker containers
I have a docker container that runs the aws cli. I have tested this manually and it work, as part of my tests I want to get the AWS version and check it.
I have created this test
it "aws is the correct version" do
expect(aws_version).to include("aws")
end
def aws_version
command("aws --version").stdout
end
When I run it I get which shows the exepected as blank, it looks like it is not running and returning anything
1) Dockerfile aws is the coorect version
Failure/Error: expect(aws_version).to include("aws")
expected "" to include "aws"
# ./tests_spec.rb:37:in `block (2 levels) in <top (required)>'
All my other tests run against the container correctly. I have included both my dockerfile and test_spec below
Dockerfile:
FROM ubuntu:16.04
ENV LAST_UPDATE=09-04-2017
#####################################################################################
# Current version is aws-cli/1.11.83 Python/2.7.12 Linux/4.4.0-75-generic botocore/1.5.46
#####################################################################################
RUN apt-get update && apt-get -y upgrade
RUN apt-get install python-pip -y
RUN pip install --upgrade pip
RUN pip install --upgrade awscli s3cmd python-magic
RUN export PATH=~/.local/bin:$PATH
RUN mkdir /root/.aws
COPY config /root/.aws
#COPY credentials /root/.aws
WORKDIR /root
ENTRYPOINT ["aws"]
CMD ["--version"]
test_spec.rb:
require "docker"
require "serverspec"
describe "Dockerfile" do
before(:all) do
#image = Docker::Image.build_from_dir('.')
set :os, family: :ubuntu
set :backend, :docker
set :docker_image, #image.id
#container = Docker::Container.create(
'Image' => #image.id,
)
#container.start
end
it "installs the right version Name of Ubuntu" do
expect(os_version).to include("xenial")
end
it "installs the right version of Ubuntu" do
expect(os_version).to include("Ubuntu 16.04.2")
end
it "installs required packages" do
expect(package("python-pip")).to be_installed
end
it "aws is the coorect version" do
expect(aws_version).to include("aws")
end
def aws_version
command("aws --version").stdout
end
def os_version
command("cat /etc/lsb-release").stdout
end
after(:all) do
#container.kill
#container.delete(:force => true)
end
end
Pretty simple (but took me a while to spot): for some reason the aws --version command pumps it's output onto stderr rather than stdout. So do this instead:
def aws_version
command("aws --version").stderr
end
Also, it's worth noting that all your container does by default is run the aws --version command and then exits. So as long as your specs run fast enough you'll be okay, but if they don't then they're going to fail randomly.
In your specs I'd override your image's default entrypoint/cmd and put in a simple while true; do sleep 100; done so that it stays alive until your after blocks kills the container.

Create aliases on host during vagrant up using vagrant-triggers

Hoping someone can help me out here.
I am wanting to create aliases on my local machine (host) when running vagrant up. Through my search for vagrant run command on host, I came across the vagrant-triggers plugin. From the surface it appears to do exactly what I want (executing a script/command on the host machine during the vagrant provisioning process), however I have not been able to get it working successfully.
Below is my example code. I don't receive any errors, but the aliases are not available on the host.
Vagrant.configure("2") do |config|
# Your existing Vagrant configuration
...
# start vagrant-triggers example code
{
:up => [
'alias runscript="$(PWD)/script"',
'alias runscript2="$(PWD)/script2"'
],
[:halt, :destroy] => [
'unalias runscript',
'unalias runscript2'
]
}.each do |trigger, commands|
config.trigger.after trigger, :stdout => true do
commands.each do |command|
run command
end
end
end
...
end

vagrant: how to add GUI to vagrant by modifying Vagrantfile?

I need to see the GUI when I do "vagrant up --provision" because I believe the box was shutdown improperly and now simply time-outs when I try to start it. I see from the [documentation] that I can add a block to my Vagrantfile to enable me to debug the startup process. This post says if the system was shutdown improperly it will ask me if I want to boot up in safe mode (only visible from the GUI). So I am trying to modify the Vagrantfile and have tried two ways (I'm not very familiar with Ruby or modifying config files). When I try this:
VAGRANTFILE_API_VERSION = "2"
path = "#{File.dirname(__FILE__)}"
require 'yaml'
require path + '/scripts/homestead.rb'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
Homestead.configure(config, YAML::load(File.read(path + '/Homestead.yaml')))
config.vm.provider "virtualbox" do |v|
vb.gui = true
end
end
I get the following error message:
Path: <provider config: virtualbox>
Message: undefined local variable or method `vb' for main:Object
Could anyone please tell me what I am doing wrong? How do I modify the file properly so that I can get the vagrant box up and running again. I am trying to use Homestead for Laravel, by the way. Thank you very much!

Resources