Thursday, August 16, 2012

Openshift Broker: Writing a Plugin Pt 2 - Skeleton

Welcome back.

In the first installment I established a build workspace for a new plugin for the Openshift Origin broker.

In this one, I'm going to create the skeleton of the new plugin in the source code tree.

Building the Scaffolding

There's a lot more to an Openshift Origin plugin than the Ruby source code. (That goes for any well produced modern software actually).  There's a raft of boilerplate for testing, packaging and documentation.
In this installment I'm going to create the skeleton of the new plugin package.  It will include everything but the source code.

The first thing to do is to identify the proper location withing the source tree.  The existing DnsService plugin is in uplift/bind.  The logical location for the new plugin is uplift/dnsmasq. Create the directory and change to it

  mkdir uplift/dnsmasq
  cd uplift/dnsmasq

The next step is to populate the initial boilerplate for a package.  Take a look in the adjacent bind plugin.

  ls ../bind
  COPYRIGHT lib    
  doc                 LICENSE  uplift-bind-plugin.gemspec
  Gemfile           Rakefile      uplift-bind-plugin.spec

doc and lib are directories. The rest of the files are typical for a package or plugin.  Several of the files can be copied as-is.  Most require some editing to reflect the new package they describe. For now, copy the normal files.  We'll customize them before committing them for the first time.

  cp ../bind/* .
  mv uplift-bind-plugin.gemspec uplift-dnsmasq-plugin.gemspec
  mv uplift-bind-plugin.spec uplift-dnsmasq-pluging.spec
And remove any of the code from the original plugin.  We'll add the real plugin code later.

rm -rf lib/*

Informational Files

There are three purely informational (or legal) files.  These can be edited to suit your needs:

  • - describe the package or plugin
  • COPYRIGHT - declare the ownership of the code
  • LICENSE - indicate the terms of use

Edit the to describe the purpose and use of your new package. (I'm not sure what to do about the US export language.  We'll see when someone puts in a pull-request without it).

The Openshift Origin source code which exists so far is all copyrighted by Red Hat Inc. and is licensed under the Apache license version 2.0.  You can keep the copyright yourself (though Red Hat has lawyers).  The license must be compatible with Apache 2.0 if you hope to have your code merged back.

Build/Test Code (Rakefile)

Rake is the Ruby equivalent of the venerable Make utility.  Rakefiles are often much simpler than Makefiles for common tasks because Rake includes a large library of pre-defined tasks.  This module will use Rake and RSpec to control unit testing.  You will need to modify the copied file to match the text below.

#require "bundler/gem_tasks"
require 'rake'
require 'rake/testtask'
require 'rspec/core/rake_task' 
desc "Run RSpec unit tests" do |t|
  t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.

You will also need to create at least the skeleton of one spec file:

mkdir spec/unit
echo "# RSpec test placeholder" > spec/unit/uplift_bind_spec.rb
Check that your simple test will run:

rake spec
/usr/bin/ruby -S rspec ./spec/unit/uplift_bind_spec.rb
No examples found.

Finished in 0.00004 seconds
0 examples, 0 failures

Package Description Files

The remainder of the files are used to control testing and packaging.

  • Gemfile - the standard Rubygem specification file: just includes the gemspec
  • uplift-dnsmasq-plugin.gemspec - the Rubygem package spec.
  • uplift-dnsmasq-plugin.spec - the RPM package spec
These last two files will require extensive editing.  Obviously you want to change the package naming.  Scan the Requires and BuildRequires. If you're not sure you need something, take it out.  You can always add it back later. Update the description, author info, sources etc. Finally you want to strip out all of the old change-logs.  If you want to get your package accepted into Fedora and or RHEL you'll want to compare it against the Fedora Packaging Guidelines.

Add and Check-In new Plugin Files

Once the package skeleton is complete, and before you can attempt to build the package, the new files must be added to your git workspace.

  git add .
  git commit -m 'create skeleton of dnsmasq plugin' .

Test Build Empty Plugin

Now that the plugin files are created you can attempt to build the (admittedly empty) plugin package for the first time. The --test --rpm  options indicate that tito should build a complete RPM and it should use the sources after the most recent tag.  When you're ready to release a new version, you'll re-run tito tag again to update the RPM version.

Be ready.  tito and rpmbuild aren't quiet about what they're doing.  If you scan though this LONG output you should be able to track the creation of a build space, the configuration and package build and buried in their the rake spec tests.  The last couple lines inform you where your new packages reside.

If what you see indicates errors, you'll have to track them down and correct them and try again.  Remember tito only works with checked in files.  Read up on it from the References at the end.
tito tag
tito build --test --rpm
 Building package [rubygem-uplift-dnsmasq-plugin-0.1.2-1]
Wrote: /tmp/tito/rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96.tar.gz
-e:1: Use RbConfig instead of obsolete and deprecated Config.
-e:1: Use RbConfig instead of obsolete and deprecated Config.
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.k2eDj1
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ export LANG
+ unset DISPLAY
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ rm -rf rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ /usr/bin/gzip -dc /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/SOURCES/rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96.tar.gz
+ /usr/bin/tar -xf -
+ '[' 0 -ne 0 ']'
+ cd rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.dTur4m
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ cd rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ export LANG
+ unset DISPLAY
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.WfABPI
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ '[' /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64 '!=' / ']'
+ rm -rf /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
++ dirname /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
+ mkdir -p /home/bos/mlamouri/rpmbuild/BUILDROOT
+ mkdir /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
+ cd rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ export LANG
+ unset DISPLAY
+ rm -rf /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
+ mkdir -p /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/home/bos/mlamouri/.gem/ruby/1.9.1
+ mkdir -p /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/usr/local/share/ruby/site_ruby
+ gem build uplift-dnsmasq-plugin.gemspec
WARNING:  no homepage specified
  Successfully built RubyGem
  Name: uplift-dnsmasq-plugin
  Version: 0.1.2
  File: uplift-dnsmasq-plugin-0.1.2.gem
+ gem install --local --install-dir /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/home/bos/mlamouri/.gem/ruby/1.9.1 --force uplift-dnsmasq-plugin-0.1.2.gem
NOTE: Gem.available? is deprecated, use Specification::find_by_name. It will be removed on or after 2011-11-01.
Gem.available? called from /home/bos/mlamouri/.rubygems/gems/sdoc-0.2.20/lib/sdoc/json_backend.rb:9.
/usr/share/rubygems/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
Successfully installed uplift-dnsmasq-plugin-0.1.2
1 gem installed
Installing ri documentation for uplift-dnsmasq-plugin-0.1.2...
Installing RDoc documentation for uplift-dnsmasq-plugin-0.1.2...
+ ln -s /home/bos/mlamouri/.gem/ruby/1.9.1/gems/uplift-dnsmasq-plugin-0.1.2/lib/uplift-dnsmasq-plugin /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/usr/local/share/ruby/site_ruby
+ ln -s /home/bos/mlamouri/.gem/ruby/1.9.1/gems/uplift-dnsmasq-plugin-0.1.2/lib/uplift-dnsmasq-plugin.rb /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/usr/local/share/ruby/site_ruby
+ mkdir -p /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/usr/share/doc/rubygem-uplift-dnsmasq-plugin-0.1.2/
+ cp -r doc/README.config /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64/usr/share/doc/rubygem-uplift-dnsmasq-plugin-0.1.2/
+ /usr/lib/rpm/ --strict-build-id /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD/rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.8scFt6
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ cd rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ unset DISPLAY
+ rake spec
/usr/bin/ruby -S rspec ./spec/unit/uplift_bind_spec.rb
No examples found.

Finished in 0.00004 seconds
0 examples, 0 failures
+ exit 0
Processing files: rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch
warning: File listed twice: /home/bos/mlamouri/.gem/ruby/1.9.1/gems/uplift-dnsmasq-plugin-0.1.2
warning: File listed twice: /home/bos/mlamouri/.gem/ruby/1.9.1/gems/uplift-dnsmasq-plugin-0.1.2/Gemfile
Provides: rubygem(uplift-dnsmasq-plugin) = 0.1.2
Requires(interp): /bin/sh
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires(post): /bin/sh
Processing files: ruby-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch
Provides: ruby(uplift-dnsmasq-plugin) = 0.1.2
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
warning: Could not canonicalize hostname: markllama
Wrote: /tmp/tito/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.src.rpm
Wrote: /tmp/tito/noarch/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch.rpm
Wrote: /tmp/tito/noarch/ruby-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.EDFbsH
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ cd rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ rm -rf /home/bos/mlamouri/rpmbuild/BUILDROOT/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.x86_64
+ exit 0
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.jVXQh6
+ umask 022
+ cd /tmp/tito/rpmbuild-rubygem-uplift-dnsmasq-plugin-c3e4f96ad4090bc7b6990725eb6972c23f28ebbfhDa71G/BUILD
+ rm -rf rubygem-uplift-dnsmasq-plugin-git-4.c3e4f96
+ exit 0
Successfully built: /tmp/tito/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.src.rpm /tmp/tito/noarch/rubygem-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch.rpm /tmp/tito/noarch/ruby-uplift-dnsmasq-plugin-0.1.2-1.git.4.c3e4f96.fc17.noarch.rpm

Next Time: Putting some Meat on the Bones

In the next installment we'll start adding some real code and the tests to verify it.


No comments:

Post a Comment