How do I run the chef knife plugin? - ruby

I would like to use a knife plugin. e.g. KnifeSpork I got the plugin installed. But I get errors when I try to run it.
First try
Install KnifeSpork:
$ gem install knife-spork
Run KnifeSpork:
$ knife spork info
Output:
FATAL: Cannot find subcommand for: 'spork info'
Available subcommands: (for details, knife SUB-COMMAND --help)
** CHEF ORGANIZATION MANAGEMENT COMMANDS **
knife org create ORG_SHORT_NAME ORG_FULL_NAME (options)
knife org delete ORG_NAME
knife org edit ORG
knife org list
knife org show ORGNAME
knife org user add ORG_NAME USER_NAME
knife org user remove ORG_NAME USER_NAME
....
Second try
Create a Gemfile
source 'https://rubygems.org'
gem 'knife-spork'
Install the dependencies
$ bundle install
Run KnifeSpork:
$ bundle exec knife spork info
Output:
Could not find ffi-1.15.4, ffi-yajl-2.4.0, libyajl2-2.1.0, json-2.6.1 in any of the sources
Run `bundle install` to install missing gems.
Additional info
$ rvm -v
rvm 1.29.12-next (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
$ ruby -v
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-darwin20]
$ chef -v
Chef Workstation version: 21.11.679
Cookstyle version: 7.25.9
Chef Infra Client version: 17.7.29
Chef InSpec version: 4.49.0
Chef CLI version: 5.4.2
Chef Habitat version: 1.6.420
Test Kitchen version: 3.1.1
$ bundle show knife-spork
/Users/name/.rvm/gems/ruby-2.7.4/gems/knife-spork-1.7.3
$ bundle show json
/Users/aseitz/.rvm/gems/ruby-2.7.4/gems/json-2.6.1

Related

How to find native extension gems installed in ./vendor/bundle with "bundle doctor"

We use a Docker image to run CI builds. The Docker image has a system-installed Ruby. The Docker container has the content of gem env and bundle env as indicated in the gist linked files:
[root#045ce9939883 code]# which ruby
/usr/local/bin/ruby
[root#045ce9939883 code]# ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
[root#045ce9939883 code]# bundle -v
Bundler version 2.0.2
We ran the following commands in the Docker container to install the gems at ./vendor/bundle:
bundle config --local path vendor/bundle
bundle install --jobs 5 --retry 3
We then tarred the entire directory, including ./vendor/bundle so that we can deploy the contents later using capistrano. On the deployment machines, we first untarred the tar file and then ran the cap deploy commands.
bundler on the deployment machines can't seem to locate gems which are built with native extensions in ./vendor/bundle. It seems to find all the other gems just fine:
[jenkins#tel-web-sob-r01-n01 2.1.10]$ bundle doctor
The following gems are missing
* nokogiri (1.10.9)
* nio4r (2.5.2)
* websocket-driver (0.7.2)
* bindex (0.5.0)
* byebug (9.0.6)
* puma (3.9.1)
* ffi (1.9.18)
Install missing gems with `bundle install
[jenkins#tel-web-sob-r01-n01 2.1.10]$ ls -l ./vendor/bundle/ruby/2.5.0/gems/ | grep nokogiri
drwxr-xr-x 7 jenkins jenkins 157 Jun 22 13:05 nokogiri-1.10.9
The deployment machine's gem env and bundle env contents are as linked
What I know so far:
I found that all the extensions are installed in ./vendor/bundle/ruby/2.5.0/extensions/x86_64-linux/2.5.0-static/. If I rename that directory to 2.5.0, it works.
Might be related to this issue.
The Dockerfile with which we are setting up ruby & bundler is similar to this one.
The machines where we deploy the bundled gems are RHEL machines and install ruby from the software collections repositories.
It seems like the deployment machines ruby is built with the --enable-shared=yes flag.
We changed our Dockerfile to configure the ruby build the same way, ./configure --enable-shared=yes. That solved our issue.

RVM Ruby Install Breaks Chef-Client On Bootstrapped Node

I have a Red Hat Enterprise Linux Server release 6.7 node that I have bootstrapped with CHEF. I've successfully executed multiple cookbooks/recipes on this node. Now I need to setup this node to run Ruby On Rails applications.
I have a cookbook with recipes that successfully ::
installs RVM
installs Ruby v2.2
The Problem
After RVM installs Ruby, the CHEF-Client on the bootstrapped node no longer works. Regardless of what Cookbook/Recipe(s) I try to run, I get the following output ::
PS C:\Users\JW031544\workspace\CHEF\chef-repo> knife ssh dh2vrtooldev01 "chef-client -o recipe[MY_COOKBOOK::default]" --manual-list --ssh-user MY_USER --ssh-password "MY_PASS"
dh2vrtooldev01 Ignoring executable-hooks-1.3.2 because its extensions are not built. Try: gem pristine executable-hooks --version 1.3.2
dh2vrtooldev01 Ignoring gem-wrappers-1.2.7 because its extensions are not built. Try: gem pristine gem-wrappers --version 1.2.7
dh2vrtooldev01 Ignoring nokogiri-1.6.8.1 because its extensions are not built. Try: gem pristine nokogiri --version 1.6.8.1
dh2vrtooldev01 /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/dependency.rb:308:in `to_specs': Could not find 'addressable' (= 2.4.0) among 45 total gem(s) (Gem::MissingSpecError)
dh2vrtooldev01 Checked in 'GEM_PATH=/usr/local/rvm/gems/ruby-2.2.4:/usr/local/rvm/gems/ruby-2.2.4#global', execute `gem env` for more information
dh2vrtooldev01 from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/dependency.rb:320:in `to_spec'
dh2vrtooldev01 from /opt/chef/embedded/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_gem.rb:65:in `gem'
dh2vrtooldev01 from /usr/bin/chef-client:4:in `<main>'
If I go onto the node and tell RVM to remove that version of Ruby, then the CHEF-Client will begin working again just fine.
The Question
Does anyone have any idea why CHEF-Client suddenly forgets how to run once RVM installs a version of Ruby?
Source Code
(default.rb)
include_recipe 'abl_rails::rvm_install'
include_recipe 'abl_rails::ruby_install'
(rvm_install.rb)
# Install RVM (if it doesn't already exist)
execute 'install_rvm' do
cwd '/root/'
command 'curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -; curl -L get.rvm.io | bash -s stable'
not_if {::File.exists?('/etc/profile.d/rvm.sh')}
end
(ruby_install.rb)
# Install Ruby
bash 'install_ruby' do
cwd '/root/'
code <<-EOH
source /etc/profile.d/rvm.sh;
rvm install #{node['ruby_version']};
EOH
not_if "source /etc/profile.d/rvm.sh; ruby --version | grep #{node['ruby_version']}", :cwd => '/root'
notifies :run, "bash[set_default_rvm_ruby]", :immediately
end
# Set the default Ruby version in RVM
bash "set_default_rvm_ruby" do
cwd '/root'
code <<-EOH
source /etc/profile.d/rvm.sh;
rvm use #{node['ruby_version']} --default;
EOH
action :run
end
rvm overrides the cd internal function with a custom function, and that is causing the error. Try removing rvm and use a different ruby manager such as rbenv.
Check this blog post for other differences between rvm and rbenv : http://jonathan-jackson.net/rvm-and-rbenv
I'll be honest, I had the same issue before (but not with chef), read a bit more about rvm and decided that it was not the right tool for me. I'm sure there must be a way to make rvm play nicely, but I decided it was not worth the effort.
This may be fixed in chef-client 12.17.x so that chef-client correctly breaks out of the RVM environment:
Related Chef bugs:
https://github.com/chef/appbundler/pull/24
https://github.com/chef/chef/issues/5589
If it is still broken after 12.17.x (when ::Gem.clear_paths exists in the /opt/chef/bin/chef-client appbundler binstub) then a new issue should get cut against appbundler.
(As an RVM user, though, I would not recommend using it for running production services, but I find it very nice to use in a dev workstation kind of environment -- but YMMV).

Installing a dev version of Vagrant but bundler doesn't seem to be installing the vagrant gem from source

I am trying to get a hackable installation of vagrant working on my machine. It uses bundler, and in its Gemspec it refers to the remote "." to add itself as a gem. The bundle install command seems to be working, but the "vagrant" gem doesn't seem to appear in gem list:
alexandma#ALEXANDMA-1-MBP ~/Projects/vagrant_ (master)
bundle install | grep "vagrant "
Using vagrant 1.6.4.dev from source at .
alexandma#ALEXANDMA-1-MBP ~/Projects/vagrant_ (master)
gem list | grep -c vagrant
0
Installing a gem from a file path or Git repository with Bundler will not install an actual gem file that can be seen by the gem command. Only Bundler is aware of the gem, so you'll need to run Bundler-aware commands to use it. In this case, running bundle list will show the entire list of dependencies including the line you see from the output of bundle install (Using vagrant 1.6.4.dev from source at .). To invoke the bundled version of Vagrant, you'll need to run bundle exec vagrant.

Ruby: How to install a specific version of a ruby gem?

Using the command-line gem tool, how can I install a specific version of a gem?
Use the -v flag:
$ gem install fog -v 1.8
Use the --version parameter (shortcut -v):
$ gem install rails -v 0.14.1
…
Successfully installed rails-0.14.1
You can also use version comparators like >= or ~>
$ gem install rails -v '~> 0.14.0'
…
Successfully installed rails-0.14.4
With newer versions of rubygems you can tighten up your requirements:
$ gem install rails -v '~> 0.14.0, < 0.14.4'
…
Successfully installed rails-0.14.3
Since some time now you can also specify versions of multiple gems:
$ gem install rails:0.14.4 rubyzip:'< 1'
…
Successfully installed rails-0.14.4
Successfully installed rubyzip-0.9.9
But this doesn't work for more than one comparator per gem (yet).
For installing
gem install gemname -v versionnumber
For uninstall
gem uninstall gemname -v versionnumber
for Ruby 1.9+ use colon.
gem install sinatra:1.4.4 prawn:0.13.0
As others have noted, in general use the -v flag for the gem install command.
If you're developing a gem locally, after cutting a gem from your gemspec:
$ gem install gemname-version.gem
Assuming version 0.8, it would look like this:
$ gem install gemname-0.8.gem
You can use the -v or --version flag. For example
gem install bitclock -v '< 0.0.2'
To specify upper AND lower version boundaries you can specify the --version flag twice
gem install bitclock -v '>= 0.0.1' -v '< 0.0.2'
or use the syntax (for example)
gem install bitclock -v '>= 0.0.1, < 0.0.2'
The other way to do it is
gem install bitclock:'>= 0.0.1'
but with the last option it is not possible to specify upper and lower bounderies simultaneously.
[gem 3.0.3 and ruby 2.6.6]
Linux
To install different version of ruby, check the latest version of package using apt as below:
$ apt-cache madison ruby
ruby | 1:1.9.3 | http://ftp.uk.debian.org/debian/ wheezy/main amd64 Packages
ruby | 4.5 | http://ftp.uk.debian.org/debian/ squeeze/main amd64 Packages
Then install it:
$ sudo apt-get install ruby=1:1.9.3
To check what's the current version, run:
$ gem --version # Check for the current user.
$ sudo gem --version # Check globally.
If the version is still old, you may try to switch the version to new by using ruby version manager (rvm) by:
rvm 1.9.3
Note: You may prefix it by sudo if rvm was installed globally. Or run /usr/local/rvm/scripts/rvm if your command rvm is not in your global PATH. If rvm installation process failed, see the troubleshooting section.
Troubleshooting:
If you still have the old version, you may try to install rvm (ruby version manager) via:
sudo apt-get install curl # Install curl first
curl -sSL https://get.rvm.io | bash -s stable --ruby # Install only for the user.
#or:# curl -sSL https://get.rvm.io | sudo bash -s stable --ruby # Install globally.
then if installed locally (only for current user), load rvm via:
source /usr/local/rvm/scripts/rvm; rvm 1.9.3
if globally (for all users), then:
sudo bash -c "source /usr/local/rvm/scripts/rvm; rvm 1.9.3"
if you still having problem with the new ruby version, try to install it by rvm via:
source /usr/local/rvm/scripts/rvm && rvm install ruby-1.9.3 # Locally.
sudo bash -c "source /usr/local/rvm/scripts/rvm && rvm install ruby-1.9.3" # Globally.
if you'd like to install some gems globally and you have rvm already installed, you may try:
rvmsudo gem install [gemname]
instead of:
gem install [gemname] # or:
sudo gem install [gemname]
Note: It's prefered to NOT use sudo to work with RVM gems. When you do
sudo you are running commands as root, another user in another shell
and hence all of the setup that RVM has done for you is ignored while
the command runs under sudo (such things as GEM_HOME, etc...). So to
reiterate, as soon as you 'sudo' you are running as the root system
user which will clear out your environment as well as any files it
creates are not able to be modified by your user and will result in
strange things happening.
Prior to installing, you can check the available versions with the list command.
gem list ^[gemname]$ --remote --all
gem install [gemname] -v [version]

How to prevent the second "gem install XXX" from reinstalling?

gem install XXX seems to run the installation process even if the package is already installed. i.e. if I do
$ gem install chef
...
$ gem list | grep chef
chef (0.9.8)
$ gem install chef
...
the second gem install chef seems to install chef again!
How can I get this to result in a noop and the message "chef is already installed", or similar, the way most package management tools work?
I can achieve what I want via
$ gem list | grep chef > /dev/null || gem install chef
but there must be a better way that I'm missing.
According to the /lib/rubygems/commands/install_command.rb file of the RubyGems sources, there is no other, "legal", way to do that, so your own is the best.

Resources