Friday, March 22, 2013

Installing (but not configuring) the broker service by hand

I'm working through a totally(?) manual installation of the OpenShift Origin service on Fedora 18. The last post on this topic was about building the RPMs on your own Yum repository. This time I'm going to install the broker service and make a few tweaks that are still required.

One seriously major thing to note is that I don't recommend actually doing this. I'm doing it to shed some light on some of the things still going on in the development process and to highlight the ways in which you can get some visibility into the installation and monitoring of the service.

If you're interested in building and running your own development environment or service for real, I suggest starting by reading through Krishna Raman's article on creating a development environment using Vagrant and Puppet and the puppet script sources themselves to see what's involved.  Finally there's a comprehensive document that describes the procedure with fewer warts.


Ingredients

As usual, I start with a clean minimal install of Fedora 18.  In addition this time I also have a yum repository filled with a bleeding-edge build from source as I described previously.  Finally I have a prepared MongoDB server waiting for a connection.

I'm replacing my real URLs and access information with dummies for demonstration purposes.


  • Yum repo URL
    http://myrepo.example.com/origin-server
  • MONGO_HOST_PORT="mydbhost.example.com:27017"
  • MONGO_USER="openshift"
  • MONGO_PASSWORD="dontuseme"
  • MONGO_DB="openshift"

Preparation

Since I'm building my own packages from source and placing them in a Yum repository, I need to add that repo to the standard set. I'll add a new file to /etc/yum.repod.d referring to my yum server.

Even if you're building from your own sources, there are still some packages you need to get that aren't in either the stock Fedora repositories or in the OpenShift sources. These are generally packages with patches that are in the process of moving upstream or are in the acceptance process for Fedora. Right now a set is maintained by the OpenShift build engineers. I need to add the repo file for that too:

[origin-server]
name=OpenShift Origin Server
baseurl=http://myrepo.example.com/openshift-origin
enable=1
gpgcheck=0
[origin-extras]
name=Custom packages for OpenShift Origin Server
baseurl=https://mirror.openshift.com/pub/openshift-origin/fedora-18/x86_64/
enable=1
gpgcheck=0
At this point you can install the openshift-origin-broker package.
yum install openshift-origin-broker
...
  urw-fonts.noarch 0:2.4-14.fc18                                                
  v8.x86_64 1:3.13.7.5-1.fc18                                                   
  xorg-x11-font-utils.x86_64 1:7.5-10.fc18                                      

Complete!


There are a set of Rubygems that are not yet packaged as RPMs. I need to install these as gems for now.

gem install mongoid
Fetching: i18n-0.6.1.gem (100%)
Fetching: moped-1.4.4.gem (100%)
Fetching: origin-1.0.11.gem (100%)
Fetching: mongoid-3.1.2.gem (100%)
Successfully installed i18n-0.6.1
Successfully installed moped-1.4.4
Successfully installed origin-1.0.11
Successfully installed mongoid-3.1.2
3 gems installed
Installing ri documentation for moped-1.4.4...
Building YARD (yri) index for moped-1.4.4...
Installing ri documentation for origin-1.0.11...
Building YARD (yri) index for origin-1.0.11...
Installing ri documentation for mongoid-3.1.2...
Building YARD (yri) index for mongoid-3.1.2...
Installing RDoc documentation for moped-1.4.4...
Installing RDoc documentation for origin-1.0.11...
Installing RDoc documentation for mongoid-3.1.2...
There are a number of gem version restrictions in the broker Gemfile which are not met by the current rubygem RPMs.  I have to remove the version restrictions so that the broker application will use what is available. This risks breaking things due to interface changes, but will at least allow the broker application to start.

sed -i -f - <<EOF /var/www/openshift/broker/Gemfile
/parseconfig/s/,.*//
/minitest/s/,.*//
/rest-client/s/,.*//
/mocha/s/,.*//
/rake/s/,.*//
EOF


For some reason, even with the --without clause for :test and :development, bundle still wants the mocha rubygem.  This should not be required for production, but right now you need to install it so that the Rails application will start.

yum install rubygem-mocha
...
Installed:
 rubygem-mocha.noarch 0:0.12.1-1.fc18

Dependency Installed:
  rubygem-metaclass.noarch 0:0.0.1-6.fc18

 Verifying The Dependencies

Now that all of the software dependencies have been installed (mostly by RPM requirements through Yum, and finally through gem requirements and some version tweaking of the Gemfile) I can check that all of them resolve when I start the application. Rails will call bundler when the application starts so I'll call it explicitly before hand. I'm only interested in the production environment, so I'll explicitly exclude development and test.

cd /var/www/openshift/broker
bundle --local
Using rake (0.9.6) 
Using bigdecimal (1.1.0)
....
Using systemu (2.5.2)
Using xml-simple (1.1.2)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

If I try to start the rails console now, though, I'll be sad. It won't connect to the database.

Configure MongoDB access/authentication

The OpenShift broker is (right now) tightly coupled to MongoDB. Recently it switched to using the rubygem-mongoid ODM module (which is a definite plus if you have to work on the code).

The last thing I need to do before I can fire up the Rails console with the broker application is to set the database connectivity parameters. One side effect of using an ODM is that it establishes a connection to the database the moment the application starts.

NOTE: when this is done I will not have a complete working broker server. I still need to configure the other external services: auth, dns and messaging.

Set the values listed in the Ingredients into /etc/openshift/broker.conf.

/etc/openshift/broker.conf
...
# Eg: MONGO_HOST_PORT="<host1:port1>,<host2:port2>..."
MONGO_HOST_PORT="mydbhost.example.com:27017"
MONGO_USER="openshift"
MONGO_PASSWORD="dontuseme"
MONGO_DB="openshift"
MONGO_SSL="false"
...

Now I can try starting the rails console. It should connect to the mongodb and offer an irb prompt:


To verify the database connectivity, take a look at this recent blog post.

Next up is configuring each plugin, one by one.

Gist Scripts

I'm trying something new.  Rather than including code snippets inline, I'm going to post them as Github Gist entries.

References

Thursday, March 21, 2013

Verifying the MongoDB DataStore with the Rails Console: Mongoid Edition

A few months ago I did several posts about how to verify the operation of the back end services of an OpenShift Origin broker service.   Today I discovered that this one (mongod) is obsolete.

The data store behind the broker is a MongoDB.  That one back end service isn't pluggable.  It's actually been made more tightly coupled to Mongo, but in this case that's a good thing.  What changed is that all of the Rails application model objects have been converted to use the Mongoid ODM rubygem.  All of the object persistence is now managed in the background and all of the logic can just deal with the objects as... well... objects.

There are a couple of implications for broker service verification.

  1. The broker connects to the database on startup
    This means that if the database access/auth information is wrong, the rails app will fail to start.
  2. The only simple way to test the connection is to create an object and observe the database.
    This is both simpler to do, and potentially more difficult to diagnose on failure.

I think the second point won't be as much of a downside as I would fear at first.  I suspect that if connectivity is good, the rest will be.  If it's not, it will be fairly clear why.

Configuring the Broker Data Store


Configuring the datastore access information hasn't changed.  The configuration information is still stored in /etc/openshift/broker.conf. The settings all have the MONGO_ prefix:

MONGO_HOST_PORT="data1.example.com:27017"
MONGO_USER="openshift"
MONGO_PASSWORD="dontuseme"
MONGO_DB="openshift"
MONGO_SSL="false"

Adjust these for your mongodb implementation. Remember to open the firewall for the broker on your database host.  Configure the database to listen and test the connectivity locally.

Verifying Simple Connectivity


You also want to check the connectivity from your broker host before trying to fire up the broker itself.

broker> echo "show collections" | mongo --username openshift --password dontuseme data1.example.com:27017/openshift
MongoDB shell version: 2.2.3
connecting to: data1.example.com:27017/openshift
system.indexes<
system.users
bye

You can do this repeatedly and observe the mongodb log on the database host.

Observing the Mongo Database Logs

On the database host, take a look at the mongodb logs. You should see a new entry (successful or failed) each time a client connects.

data1> tail /var/log/mongodb/mongodb.log
Thu Mar 21 20:24:26 [conn15] authenticate db: openshift { authenticate: 1, nonce: "20d6f85f33f03dee", user: "openshift", key: "60639c7ce56851a25be56bcebd98c3ed" }

Starting the Rails Console


Now that you're sure that the database is running and accessible from your broker host you can try firing up the Rails console. This assumes that you've resolved all of the gem requirements. If not, the Rails console will complain about them and exit.

broker> cd /var/www/openshift/broker
broker> rails console
Loading production environment (Rails 3.2.8)
irb(main):001:0>

If you go this far you should have seen one more authentication log record on the mongodb server. (see above)

Create a Database Object


Now we can create a CloudUser object and watch it appear in the database

irb(main):001:0> user = CloudUser.create(login: "testuser")
=> #<CloudUser _id: 514b6f6cf3da7fa491000001, created_at: 2013-03-21 20:37:00 UTC, updated_at: 2013-03-21 20:37:00 UTC, login: "testuser", capabilities: {"subaccounts"=>false, "gear_sizes"=>["small"], "max_gears"=>100}, parent_user_id: nil, plan_id: nil, pending_plan_id: nil, pending_plan_uptime: nil, usage_account_id: nil, consumed_gears: 0>

You can see that this is more than your typical Ruby object. The ID and created_at and updated_att fields are artifacts of the ODM persistence.  You won't see another log message because the database connection is persistent using the ODM.  You will find that there's now a document in the openshift.cloud_user collection.

data> echo "db.cloud_users.find()" | mongo --username openshift --password dbsecret localhost/openshift
MongoDB shell version: 2.2.3<
connecting to: localhost/openshift
{ "_id" : ObjectId("514b6f6cf3da7fa491000001"), "consumed_gears" : 0, "login" : "testuser", "capabilities" : { "subaccounts" : false, "gear_sizes" : [ "small" ], "max_gears" : 100 }, "updated_at" : ISODate("2013-03-21T20:37:00.546Z"), "created_at" : ISODate("2013-03-21T20:37:00.546Z") }
bye


Removing the Test Object


Cleaning up is just as easy

irb(main):002:0> user.delete<
=> true

And to verify that it's been removed:

echo "db.cloud_users.find()" | mongo --username openshift --password dbsecret localhost/openshift
MongoDB shell version: 2.2.3
connecting to: localhost/openshift
bye

At this point you know both that your database is running and that the broker application can connect and read and write it.

Much simpler with an ODM.

References:


Friday, March 15, 2013

Lessons about Default Values

I have lots of "Rules of System Administration".  Some day I'll write them all down and publish a book.

Today I got a reminder about the nuance of one:

Always provide reasonable defaults.

I happen to have been building an OpenShift Broker on Fedora 18, but it applies elsewhere.  The OpenShift broker service is configured with the /etc/openshift/broker.conf file. The configuration file is a traditional line-oriented set of key/value pairs.  That is, each pair is on one line, separated by an equals sign (=).

I was trying to set custom values to the Mongo database, but when I tried starting the broker application it would try to connect to the data store and fail.  It indicated that it was trying to use the default value, ignoring my settings.

I fished around in the Rails environments files and several other places where I saw the same value until I figured out which one it was coming from (the right one, config/environments/production.rb).

I knew I'd set the values in my configuration file right, so why weren't they showing up?

It turns out that the reason was that I hadn't set them right.  I'd left the equal sign out when I made the substitutions.  That's my problem.  And that's not the real issue.

In looking at that default which looked like a real, good, usable value, I realized it shouldn't.

For most settings a "reasonable default value" is one that will nominally work.  For access information and authentication, the reasonable default is "you didn't tell me what to do. I'm going to sit on my hands until you do".  The system shouldn't work until you successfully set your own values.

There's one other thing.  The system should not just spew garbage if you haven't set the values.  It should very politely inform you that you're not done yet and what needs to be done.

So, that's something I'm going to be thinking about for OpenShift next week.

Wednesday, March 6, 2013

The Bleeding Edge: Building the OpenShift RPMs from source

While the OpenShift Online service has been up for... sheesh almost 2 years now? (corrections welcome) the  development activity has only accelerated over time.  More than ever the admin tasked with implementing an On-Premise OpenShift Origin service is shooting at a moving target.  There are released RPMs in the Fedora 18 distribution and updates, but even the updates aren't keeping pace with the source changes. (This is good, it gives *some* stability).

The experimenter will often find now that the tiny feature she needs is already in the source tree but hasn't yet made it to the released packages.  They may even find the need (desire?) to make changes and contribute them back to the base.  In both of those cases she will have to be prepared to create local builds of the OpenShift packages for development and testing.

There is a build toolset also on github for the origin-server package set.  It's in a separate repository named origin-dev-tools.  This follows the model of the original internal build and test environment. It's an all-in-one wrap-it-to-go kind of toolset.  But this is the Under the Hood blog, so I'm going to crack the case open and see what's inside.

This post uses Fedora 18 but should be applicable to RHEL6+ as well.

Building a Build Site

If you're customizing the OpenShift Origin software, whether because you want to work with committed but pre-release software or because you're making changes on your own, the best way to manage the software life cycle is to create a proper build server.  To start with I'll describe how to create the build server and to make the RPM repo available to server boxes.  There are tools to automate the build/test/publish process as well but I won't deal with them yet.

The goal of this post is to outline the requirements and process for creating your own build 

Building on a Base

As usually I start on a minimal system.  I add the software I need explicitly and let yum manage the dependencies.  The build system will need a fixed IP address and a well known DNS name so that you can reach it later from your OpenShift Origin servers.

When configured for my work environment (including Kerberos 5, and LDAP authentication) I start with about 245 packages.

The Tool Box of Modern Software Development

There's a lot of stuff that goes into making software packages appear automatically.  The development and build process today commonly includes remote repository updating, automated testing, software tagging on top of the compilers, interpreters and language libraries.

Note that the first set of tools listed below are just those needed to manage the build and packaging process.  Each package will also have additional build requirements, but those will be dealt with later.

Once, long ago building software meant having a compiler (which you built yourself from source code), and tar for unpacking it and make to automate the process.  Today the same tasks apply but there's a lot more formalism to the process.  Collaboration has required the creation of distributed software revision control tools.  Software testing has become everyone's job.  People have recognized that software is never finished, it evolves and grows over time.  Users need to be able to know what they're running and where to get updates.  The modern tool set reflects these needs.

While most of the time these tools will just work it's often important to know what tools are doing what jobs and how they interact.  This is critical either when things don't go as planned, or when contributing new software packages to the set.  First I'll take a look at which tools OpenShift uses and then demonstrate how to install them (which is actually pretty trivial)

Software Revision Control: Git and Github

A distributed project today requires some kind of remote software revision control system.  This allows developers to work together without having to be in one place.  The Revision Control System (RCS) manages changes and flags conflicts.  It allows tagging of releases.

The OpenShift Origin project uses git for revision control.   It uses the Github service to hold the master repository and development forks and branches.  You can pull down a cloned copy of the source tree without having an account on Github.  To manage your local changes and to contribute back you'll need an account of your own.  There are a number of good books or sites on how to use git.  See the Github site itself for help learning how to create your own development fork and branches.

Task Automation: Ruby, Rubygems and Rake

To automate the unit testing OpenShift uses a rubygem called rake after the original GNU make.  Rake implements dependencies and tasks in a way similar in behavior (but syntactically entirely different) from make.

Rake is implemented as a rubygem which is in turn a module packaging mechanism for Ruby code.

Unit Testing: Rspec 2

Many OpenShift components include unit tests written using the RSpec framework. RSpec is another rubygem.  It has components for writing special expectations, mocks and hooks for testing Rails applications. rubygem-rspec-rails  requires all of the other components, so we can install that and let yum handle the dependencies.

Build, Packaging and Release: Tito and rpm-build and rubygem-bundler

All of the software in OpenShift must be packaged for delivery in RPM format.  This is both a requirement for inclusion in Fedora and RHEL releases as well as good general practice (use the native software packaging format).   A number of components are also packaged as Rubygems. This adds the requirement for the rubygem-bundler package for building but these are not the deliverable format.

OpenShift uses a tool called tito to manage package builds and revision tags.  Tito works with the standard RPM spec files and with rpmbuild and createrepo. When it runs successfully, tito not only builds the requested package, it increments the package version number and inserts it in a yum repository.

Documentation: rubygem-yard

The ruby community have created a set of tools which allow documentation to be automatically generated.  The author of the code inserts specially formatted markup comments which the documentation generator uses to produce HTML or other documentation formats.

OpenShift is using the yard documentation tool to markup and auto-generate documentation for the ruby packages.  Yard is installed with the rubygem-yard RPM

Publication: thttpd

Once the packages are built they're useless if your OpenShift Origin servers can't reach them.  I typically use Apache2 for web service but these are static, so a light weight server like lighttpd or thttpd are in order.  I'm going to use thttpd because I can configure it to serve the default yum repo location with a single sed command.

If you don't want to share the builds from the build server you can instead use a tool like rsync to push them where you need them to be for publication.

Installing The Software

I can compose the list now:

  • git  - revision control
  • rake
    • ruby
    • rubygems
    • rubygems-devel
    • rubygem-rake
    • rubygem-bundler
  • rubygem-yard
  • rspec
    • rubygem-rspec-core
    • rubygem-rspec-mocks
    • rubygem-rspec-expectations
    • rubygem-rspec-rails
  • tito
  • rpm-build
  • lighttpd
Note that RPM package dependencies make the actual install list fairly small if you pick carefully:

Now that I have my list, installing the toolset is easy enough:

yum install -y git rubygems-devel rubygem-rake rubygem-yard rubygem-rspec-rails tito rpm-build lighttpd

This will actually cause the installation of almost 100 more packages due to dependencies.

When this software is all installed on my build system, the next step is get myself a copy of the source code.

Getting the Source from Github

Git was created by Linus Torvalds himself to replace a proprietary software revision control system which had been used for years to manage the Linux kernel source tree.   Since then a number of services have sprung up to offer a place for people to host their projects.  OpenShift Origin is hosted on Github.

You can get the git URL for the OpenShift Origin service software without an account, but if you want to make modifications or contributions you'll need to register and then create your own project fork.  Github has some greate help and tutorials here:

https://help.github.com/

You will probably also want to look at the process for setting up SSH keys for Github so you don't have to type a password for every operation.

The OpenShift Origin server source code is here:


Cloning the Source Code Repository(s)

Once you've created your account and forked the origin-server project you should find a git@github.com: URL on your fork page.  You can cut-and-paste that and use it to clone a local copy of your workspace. (In the example below, replace the URL with your own)

git clone git@github.com:/openshift/origin-server.git --tags

Now you've got everything that the build process needs, but not what the software you're building needs.

Task Automation

The current official process uses the origin-dev-tools and has a certain amount of overhead. It's made for rigourous exhaustive build/test/release cycles.

What we need here is much simpler and self-contained.

The exploration that follows is captured in a Rakefile script I put on gist.github.com. When it's placed at the top of the origin-server source tree and set executable, it will execute the tasks described below.

NOTE: the oo-rake script is not part of the official origin-server sources. It will likely not be maintained and comes with no warranty. Use at your own risk.

cd origin-server
wget http://gist.github.com/markllama/5225912/raw/abcbeebed584bc1aae56b9091fa977e8636c316c/oo-rake
chmod a+x oo-rake
./oo-rake --tasks
rake all:builddep[answer]       # install all build requirements
rake all:rpm[repodir,test,yum]  # generate all RPMs and create yum repository
rake all:testrpm[repodir,yum]   # generate all test RPMs and create yum rep...
rake all:yard[destdir]          # generate comprehensive documentation

Package Build Requirements


Building most software requires more than just the build tools.  Most software depends on other tools or libraries for its own build process.  Because OpenShift is set up to build into packages and because the RPM mechanism has a feature to allow developers to call out the dependencies, we can find out what's needed and install it.

Packages and ".spec" files


Every component of OpenShift Origin must be packaged as an RPM.  It's just the way things are.  This gives   us a hook to help identify each package and ultimately, to find the set of build prerequisites for each package.

The contents of each package must reside in a directory within the source code tree.  Each package must have exactly one RPM .spec file.  We can search the directory tree for these files and we'll know both the names of the packages and their locations within the source tree.

Assuming you've just cloned the origin-server repository into your current working directory you can find the list of packages with a little shell snippet like this:

find origin-server -name \*.spec

Build Requirements


Among other things,  a package .spec file defines a set of packages that must be installed before the new package can be built.   The required packages are specified with BuildRequires lines.

The yum-builddep program which is part of the yum-utils package will install the build requirements for a package:

yum-builddep <specfile> [<specfile>...]

This will install all of the build requirements for the listed packages.

The oo-rake script offers the all:builddeps target. Invoking this task will install all of the build requirements for the packages under the tree.

Building the Packages


The packages (and yum repository) are built by tito. Tito has to run in the root directory for each package (where the .spec file resides.) Since we already know how to find all the spec files we can find the directories which contain them fairly simply:

find origin-server -name \*.spec | xargs -i {} dirname {}

This will produce a list of directories which contain potential packages.  We can just loop over that and call tito in each one to build the packages.

for PKGDIR in $(find origin-server -name \*.spec | xargs -i {} dirname {}) ; do 
    (cd $PKGDIR ; tito build --rpm)
done

This will change to each directory, build the RPM and place it in a yum repository at /tmp/tito.  You can change where the output goes either by adding -o <directory> to the tito command or by setting a variable named PREBUILD_BASEDIR in the build user's ~/.titorc file.

The oo-rake provides a target: all:rpm which will build all of the packages in the tree below it.  You can provide arguments to rake targets.  The first argument to the all:rpm task is the destination for the packages.

Git Tags and Test RPMs


Tito depends on git and specifically on release tags. If you get any messages indicating that a tag is missing for a package, fetch the tags from your git repository as well

cd origin-server ; git fetch origin --tags

When you run the all:rpm target tito will build tagged release packages.  That is, it will build from the last tagged commit.  If you have checked in new versions of files, they will not be used.

To build packages from the head of the current branch, you want to build test packages.

The oo-rack script provides another target all:testrpm which will build test packages for the entire tree (and place them in the yum repository).  Test packages get hashed names so that yum update will install the newer packages from the repository.

Publishing the Yum Repository


You don't have to publish the RPMs in the yum repository but you have to make the RPMs available somehow. I'm going to add a step here to make the yum repo available by HTTP using a lightweight http server, thttpd.

By default thttpd serves the contents of /var/www/thttpd. I want it to serve /tmp/tito. A single line sed command makes the adjustment:

sed -i -e 's|^dir=.*$|dir=/tmp/tito|'

Fedora 18 comes with the firewall daemon limiting remote access. We have to open access to port 80 so that thttpd can answer queries.

firewall-cmd --zone public --add-service http

We just have to enable the thttpd and we'll be able to have servers pull from it.

systemctl enable thttpd
systemctl start thttpd

If you have a web server established you could instead use rsync or something like it to move the build results to the web server.

What this doesn't include?


This is just the barest minimum information to build OpenShift Origin RPMs on Fedora 18.  There are a bunch of tasks that aren't handled:

  • Triggering automatic re-build on developer commit
  • Running unit tests
  • Interpreting and handling build errors
  • Handling new package build requirements
  • Installing and configuring OpenShift servers
This should be enough though for someone who wants to extend or contribute to the OpenShift Origin project and needs to build their own packages.

References

Thursday, December 6, 2012

Verifying the MongoDB DataStore with the Rails Console

UPDATE: The broker data model has switched to using the Mongoid ODM rubygem.  This significantly improves the consistency of the broker data model and simplifies coding broker objects.  It also obsoletes this post.

See the new one on Verifying the Mongod DataStore with the Rails Console: Mongoid Edition


In the last post I showed how I'd verify the configuration of the OpenShift Bind DNS plugin using the Rails console.  In this one I'll do the same thing for the DataStore  back end service. (not strictly a plugin, but hey...).

DataStore Configuration


Right now the DataStore back end service is not pluggable.  The only back end service available is MongoDB. I've posted previously on how to prepare a MongoDB service for OpenShift.  Now I'm going to work it from the other side and demonstrate that the communications are working.

Since the DataStore isn't pluggable, it isn't configured from the /etc/openshift/plugins.d directory.  Rather it has it's own section in the /etc/openshift/broker.conf (or broker-dev.conf).

This is just the relevant fragement from broker.conf

...
#Broker datastore configuration
MONGO_REPLICA_SETS=false
# Replica set example: "<host-1>:<port-1> <host-2>:<port-2> ..."
MONGO_HOST_PORT="data1.example.com:27017"
MONGO_USER="openshift"
MONGO_PASSWORD="dbsecret"
MONGO_DB="openshift"
...

These are the values that will be used when the broker application creates an OpenShift::DataStore (and OpenShift::MongoDataStore) object.

The DataStore: Abstract and Implementation

At one point the OpenShift::DataStore was intended to be pluggable.  At some point the concept of an abstracted interface was dropped and the tightly bound MongoDB interface was allowed to grow organically. The remains of the original pluggable interface are still there.  Both source files live now in the openshift-origin-controller rubygem package.


The OpenShift::DataStore class still follows the plugging conventions.  It implements the provider=() and instance() methods.  The first takes a reference to a class that "implements the datastore interface" and the second provides an instance of the implementation class all pre-configured from the configuration file.

Observing MongoDB


Unlike named MongoDB writes to its own log by default.  The logs reside in /var/log/mongodb/mongodb.log. (as controlled by the logpath setting in /etc/mongodb.conf.) Verbose logging is controlled in the mongodb.conf as well.  For this demonstration I'm going to enable that by uncommenting the line in /etc/mongodb.conf and restarting the mongod service.

MongoDB also has a command line tool that can be used to interact with the database as well.  The CLI tool is called mongo. I can invoke it like this:

mongo --username openshift --password dbsecret data1.example.com/openshift
MongoDB shell version: 2.0.2
connecting to: data1.example.com/openshift
> show collections;
system.indexes
system.users

This shows an initialized database, but no OpenShift data has been stored yet. The two existing collections are the system collections.  OpenShift will add collections as needed to store data.

With these two mechanisms I can observe and verify access and updates from the broker to the database through the OpenShift::DataStore object.

Creating an OpenShift::DataStore Object


I'm going to create the OpenShift::DataStore object in the same way I did with the OpenShift::DnsService object.  I call the instance() method on the OpenShift::DataStore object.

cd /var/www/openshift/broker
rails console
Loading production environment (Rails 3.0.13)
irb(main):001:0> store = OpenShift::DataStore.instance
=> #<OpenShift::MongoDataStore:0x7f9e42ed4918
 @host_port=["data1.example.com", 27017], @db="openshift", @user="openshift",
 @replica_set=false, @password="dbsecret",
 @collections={:application_template=>"template", :user=>"user", :district=>"district"}>
irb(main):002:0>

Now I have a variable named db which contains a reference to an OpenShift::MongDataStore object. I can see from the instance variables that it is configured for the right host, port, database, user etc.

Checking Communications: Read


Now that I have something to work with its time to see if it will talk to the database.

The interface to the DataStore is much more complex than the DnsService interface is.  Since we're only checking connectivity that's not a problem.  Once I've checked connectivity, I can craft more checks of the DataStore methods themselves later.

The DataStore has a couple of methods that expose the Mongo::DB class that's underneath.  With that I can force a query for the list of collections currently available in the database. If the broker service has not yet been run and users and applications created then only the system collections will exist.  In the example below there are only two collections.


rails console
Loading production environment (Rails 3.0.13)
irb(main):001:0> store = OpenShift::DataStore.instance
=> #<OpenShift::MongoDataStore:0x7f1ac50ac698
 @host_port=["data1.example.com", 27017], @db="openshift",
 @user="openshift", @replica_set=false, @password="dbsecret",
 @collections={:application_template=>"template", :user=>"user", :district=>"district"};gt;
irb(main):002:0> collections = store.db.collections
=> [#<Mongo::Collection:0x7f1ac5096ac8 @cache_time=300, 
...
 @pk_factory=BSON::ObjectId>]
irb(main):003:0> collections.size
=> 2
irb(main):004:0> collections[0].name
=> "system.users"
irb(main):005:0> collections[1].name
=> "system.indexes"

On the MongoDB host I can confirm that there are indeed two collections.

mongo --username openshift --password dbsecret data1.example.com/openshift
MongoDB shell version: 2.0.2
connecting to: data1.example.com/openshift
> show collections
system.indexes
system.users

Finally I can check that the broker app really did issue that query and get a response:


...
Thu Dec  6 14:06:29 [conn2] Accessing: openshift for the first time
Thu Dec  6 14:06:29 [conn2]  authenticate: { authenticate: 1, user: "openshift",
 nonce: "d2083e4185cb7d22", key: "c7c3628fe64eb1aedaaf4c87a4d5e723" }
Thu Dec  6 14:06:29 [conn2] command openshift.$cmd command: { authenticate: 1, u
ser: "openshift", nonce: "d2083e4185cb7d22", key: "c7c3628fe64eb1aedaaf4c87a4d5e
723" } ntoreturn:1 reslen:37 5ms
Thu Dec  6 14:06:29 [conn2] query openshift.system.namespaces nreturned:3 reslen
:142 0ms
...

Checking Communications: Write


Now that I'm convinced that I'm connecting to the right database and I'm able to make queries, the next check is to be sure I can write to it when needed.

Since the database has not yet been used, it's empty.  I want to be careful regardless not to mess with any real OpenShift collections. I'll create a test collection, write a record to it, read it back and drop the collection again.  If I do this in a consistent way I can use this test at any time to check connectivity without danger to the service data.

 I'm using the ruby Mongo classes underneath the OpenShift::MongoDataStore class, so I'll have to look there for the syntax. The Mongo::DB class has a create_collection() method which will do the trick.  I'll issue the command in the rails console, then check the MongoDB logs and view the list of collections using the mongo CLI tool.

Create a Collection


First, the create query (entered into an existing rails console session):

irb(main):005:0> store.db.create_collection "testcollection"
=> #<Mongo::Collection:0x7f76567e9ae0 @cache_time=300,...
...
 @name="testcollection", @logger=nil, @pk_factory=BSON::ObjectId>
irb(main):006:0>

Next I'll check logs:

...
Thu Dec  6 14:37:13 [conn4] run command openshift.$cmd { authenticate: 1, user: 
"openshift", nonce: "665cedb4baf82b0d", key: "eec7b08761151c858c14058c2629dee6" 
}
Thu Dec  6 14:37:13 [conn4]  authenticate: { authenticate: 1, user: "openshift",
 nonce: "665cedb4baf82b0d", key: "eec7b08761151c858c14058c2629dee6" }
Thu Dec  6 14:37:13 [conn4] command openshift.$cmd command: { authenticate: 1, u
ser: "openshift", nonce: "665cedb4baf82b0d", key: "eec7b08761151c858c14058c2629d
ee6" } ntoreturn:1 reslen:37 0ms
Thu Dec  6 14:37:13 [conn4] query openshift.system.namespaces nreturned:3 reslen
:142 0ms
Thu Dec  6 14:37:13 [conn4] run command openshift.$cmd { create: "testcollection
" }
Thu Dec  6 14:37:13 [conn4] create collection openshift.testcollection { create:
 "testcollection" }
Thu Dec  6 14:37:13 [conn4] New namespace: openshift.testcollection
Thu Dec  6 14:37:13 [conn4] adding _id index for collection openshift.testcollec
tion
Thu Dec  6 14:37:13 [conn4] build index openshift.testcollection { _id: 1 }
Thu Dec  6 14:37:13 [conn4] external sort root: /var/lib/mongodb/_tmp/esort.1354
804633.1660751058/
Thu Dec  6 14:37:13 [conn4]   external sort used : 0 files  in 0 secs
Thu Dec  6 14:37:13 [conn4] New namespace: openshift.testcollection.$_id_
Thu Dec  6 14:37:13 [conn4]   done building bottom layer, going to commit
Thu Dec  6 14:37:13 [conn4]   fastBuildIndex dupsToDrop:0
Thu Dec  6 14:37:13 [conn4] build index done 0 records 0.001 secs
Thu Dec  6 14:37:13 [conn4] command openshift.$cmd command: { create: "testcolle
ction" } ntoreturn:1 reslen:37 1ms
...

Finally I'll connect and query the database locally to check for the presence of the new collection.

mongo --username openshift --password dbsecret data1.example.com/openshift
MongoDB shell version: 2.0.2
connecting to: data1.example.com/openshift
> show collections
system.indexes
system.users
testcollection

This is really enough to demonstrate that the MongoDataStore object is properly configured and has the ability to read and write the database.  Just for completeness I'll go one step further and create a document.

Add a Document to the testcollection


Since the testcollection is the most recently added, it should be the last one in the collections list in the Rails console Mongo::DB object.  I can check by looking at the name attribute of that collection

irb(main):007:0> store.db.collections[2].name
> "testcollection"

Now that I know I have the right one, I can add a document to it using the Mongo::Collection insert() method:

irb(main):008:0> store.db.collections[2].insert({'testdoc' => {'testkey' => 'testvalue'}})
=> BSON::ObjectId('50c0c2016892df2d56000001')

The logs show the insert like this:

Thu Dec  6 16:04:36 [conn11] run command openshift.$cmd { getnonce: 1 }
Thu Dec  6 16:04:36 [conn11] command openshift.$cmd command: { getnonce: 1 } nto
return:1 reslen:65 0ms
Thu Dec  6 16:04:36 [conn11] run command openshift.$cmd { authenticate: 1, user:
 "openshift", nonce: "19ca25a92ca483ee", key: "f7ac36d2e36a3a00a91d234a59a559e3"
 }
Thu Dec  6 16:04:36 [conn11]  authenticate: { authenticate: 1, user: "openshift"
, nonce: "19ca25a92ca483ee", key: "f7ac36d2e36a3a00a91d234a59a559e3" }
Thu Dec  6 16:04:36 [conn11] command openshift.$cmd command: { authenticate: 1, 
user: "openshift", nonce: "19ca25a92ca483ee", key: "f7ac36d2e36a3a00a91d234a59a5
59e3" } ntoreturn:1 reslen:37 0ms
Thu Dec  6 16:04:36 [conn11] query openshift.system.namespaces nreturned:5 resle
n:269 0ms
Thu Dec  6 16:04:36 [conn11] insert openshift.testcollection 0ms

And a quick CLI query to confirm that the document has been created:

mongo --username openshift --password dbsecret data1.example.com/openshift
MongoDB shell version: 2.0.2
connecting to: data1.example.com/openshift
> db.testcollection.find()
{ "_id" : ObjectId("50c0c2016892df2d56000001"), "testdoc" : { "testkey" : "testvalue" } }

Read a Document from the testcollection


In traditional database style, when you make a query, you don't get  back the single thing you asked for.  You get a Mongo::Cursor object which collects all of the documents which match your query.  Cursors respond to a next() method which does what you would think, returning each match in turn and nil when all documents have been retrieved.  The Mongo::Cursor also has a method which converts the entire response into an array. I'll use that to get just the one I want.

irb(main):035:0> store.db.collections[2].find.to_a[0]
=> #<BSON::OrderedHash:0x3fbb2b27fea4
 {"_id"=>BSON::ObjectId('50c0c2016892df2d56000001'),
 "testdoc"=>#<BSON::OrderedHash:0x3fbb2b27fd50 {"testkey"=>"testvalue"}>}>

I won't take up space showing the log entries for this query.  I know how to find them now if there's a problem.

Cleanup: Remove the testcollection


The final step in a test like this is always to remove any traces.  I can drop the whole collection with a single command.  This one I will confirm with the local CLI query, but the logs I'll leave for an exercise unless something goes wrong.

irb(main):037:0> store.db.collections[2].drop
=> true

You may notice that this was WAY too easy. Do be careful when you're working on production systems. Prepare and test backups OK?

When I look now on the CLI and ask for the list of collections, I only see two:

mongo --username openshift --password dbsecret data1.example.com/openshift
MongoDB shell version: 2.0.2
connecting to: data1.example.com/openshift
> show collections
system.indexes
system.users

Summary

In this post I showed how to access the OpenShift broker application using the Rails console.  I created an OpenShift::MongoDataStore object (using the OpenShift::DataStore factory).  I showed how to access the database from the CLI and where to find the MongoDB log files.  With these I was able to confirm that the OpenShift broker DataStore configuration was correct and that the database was operational.

References






Wednesday, December 5, 2012

Verifying the DNS Plugin using Rails Console

Each of the OpenShift broker plugins provides an interface implementation class for the  plugin's abstract behavior.   In practical terms this means that I can fire up the rails console, create an instance of the plugin class and then use it to manipulate the service behind the plugin.

Since the DNS plugin has the simplest interface and Bind has the cleanest service logs, I'm going to demonstrate with that.  The technique is applicable to the other back-end plugin services.

Preparing Logging


To make life easy I'm going to configure logging on the DNS server host so that the logs from the named service are written to their own file.

A one line file in /etc/rsyslog.d will do the trick:

if $programname == 'named' then /var/log/named.log

Write that into /etc/rsyslog.d/00_named.conf and restart the rsyslog service.  Then restart the named service and check that the logs are appearing in the right place.

If I didn't filter out the named logs, I could still use grep on /var/log/messages to extract them.

Configuring the Bind DNS Plugin


As indicated in previous posts, the OpenShift DNS plugin is enabled by placing a file in /etc/openshift/plugins.d with the configuration information for the plugin.  The name of the file must be the name of the rubygem which implements the plugin with the suffix .conf. The Bind plugin is configured like this:

/etc/openshift/plugins.d/openshift-origin-dns-bind.conf

BIND_SERVER="192.168.5.11"
BIND_PORT=53
BIND_KEYNAME="app.example.com"
BIND_KEYVALUE="put-your-hmac-md5-key-here"
BIND_ZONE="app.example.com"

When the Rails application starts, it will import a plugin module for each .conf file and will set the config file values.

The Rails Console


Ruby on Rails has an interactive testing environment.  It it started by invoking rails console from the root directory of the application.  If I start the rails console at the top of the broker application I should be able to instantiate and work with the plugin objects.

The rails console command runs irb to offer a means of manual testing.  In addition to the ordinary ruby script environment it imports the Rails application environment which resides in the current working directory. Among other things, it processes the Gemfile which, in the case of the OpenShift broker, will load any plugin gems and initialize them. I'm going to use the Rails console to directly poke at the back end service objects.

I'm going to go to the broker application directory.  Then I'll check that bundler confirms the presence of all of the required gems.  Then I'll start the Rails console and check the plugin objects manually.

cd /var/www/openshift/broker
bundle --local
....
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
rails console
Loading production environment (Rails 3.0.13)
irb(main):001:0> 

The last line above is the Rails console prompt.

Creating a DnsService Object


The OpenShift::DnsService class is a factory class for the DNS plugin modules. It also contains an interface definition for the plugin, though Ruby and Rails don't seem to be much into formal interface specification and implementation.  The plugin interface definitions reside in the openshift-origin-controller rubygem:

https://github.com/openshift/origin-server/tree/master/controller/lib/openshift

The factory classes provide two methods by convention: provider=() sets the actual class which implements the required interface and instance() is the factory method, returning an instance of the implementing class.  They also have a private instance variable which will contain a reference to the instantiating class.  When the plugins are loaded, a reference to the instantiating class is set into the factory class.

Once the broker application is loaded using the rails console I should be able to create and work with instances of the DnsService implementation.

The first step is to check that the factory class is indeed loaded and has the right provider set. Since I can just type at the irb prompt it's easy to see what's there.

irb(main):001:0> OpenShift::DnsService
=> OpenShift::DnsService
irb(main):002:0> d = OpenShift::DnsService.instance
=> #<OpenShift::BindPlugin:0x7f540dfb9ee8 @zone="app.example.com",
 @src_port=0, @server="192.168.5.2",
 @keyvalue="GwhJNLZPghbpTya2M6N+lvcLmBQx6TYbuH7j6TPyetE=",
 @port=53, @keyname="app.example.com",
 @domain_suffix="app.example.com">

Note that the class is OpenShift::BindPlugin and the instance variables match the values I set in the plugin configuration file. I now have a variable d which refers to an instance of the DNS plugin class.

The DnsService Interface


The DNS plugin interface is the simplest of the plugins.  It contains just four methods:
  • register_application(app_name, namespace, public_hostname)
  • deregister_application(app_name, namespace)
  • modify_application(app_name, namespace, public_hostname)
  • publish()
All but the last will have a side-effect which I can check by observing the named service logs and by querying the DNS service itself.

Note that the publish() method is not included in the list with side-effects.  publish() is always called at the end of a set of change calls.  It is there to accommodate batch update processing.  Third party DNS services which use use web interfaces may require batch processing. The OpenShift::BindPlugin submits changes instantly.

Change and Check


The process of testing now will consist of three repeated steps:

  1. Make a change
  2. Check the DNS server logs
  3. Check the DNS server response

I will repeat the steps once for each method. (though I'll only show a couple of samples here)

The logs are time-stamped.  To make it easier to find the right log entry, I'll check the time sync of the broker and DNS server hosts, and then check the time just before issuing each update command.

First I check the date and add an application record.  An application record is a DNS CNAME record which is an alias for the node which contains the application. Here goes:

irb(main):003:0> `date`
=> "Wed Dec  5 15:25:59 GMT 2012\n"
irb(main):002:0> d.register_application "testapp1", "testns1", "node1.example.com"
=> ;; Answer received from 192.168.5.11 (129 bytes)
;;
;; Security Level : UNCHECKED
;; HEADER SECTION
;; id = 25286
;; qr = true    opcode = Update    rcode = NOERROR
;; zocount = 1  prcount = 0  upcount = 0  adcount = 1

OPT pseudo-record : payloadsize 4096, xrcode 0, version 0, flags 32768

;; ZONE SECTION (1  record)
;; app.example.com. IN SOA

The register_application() method returns the Dnsruby::Message returned from the DNS server.  A little digging should indicate that the update was successful.

Next I'll examine the named service log on the DNS server host.

tail /var/log/named.log
...
Dec  5 15:26:41 ns1 named[11178]: client 10.16.137.216#54040/key app.example.com: signer "app.example.com" approved
Dec  5 15:26:41 ns1 named[11178]: client 10.16.137.216#54040/key app.example.com: updating zone 'app.example.com/IN': adding an RR at 'testapp1-testns1.app.example.com' CNAME

Finally, I'll check that the server is answering queries for that name:

dig @ns1.example.com testapp1-testns1.app.example.com CNAME

; <<>> DiG 9.9.2-rl.028.23-P1-RedHat-9.9.2-8.P1.fc18 <<>> @ns1.example.com testapp1-testns1.example.com CNAME
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 10884
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;testapp1-testns1.example.com. IN CNAME

;; AUTHORITY SECTION:
example.com.  10 IN SOA ns1.example.com. hostmaster.example.com. 2011112904 60 15 1800 10

;; Query time: 3 msec
;; SERVER: 192.168.1.11#53(192.168.1.11)
;; WHEN: Thu Dec  5 15:28:41
;; MSG SIZE  rcvd: 108

That's sufficient to confirm that the DNS Bind plugin configuration is correct and that updates are working. In a real case I'd go on and check each of the operations. for Now I'll just delete the test record and go on.


d.deregister_application "testapp1", "testns1"
=> ;; Answer received from 192.168.5.11 (129 bytes)
;;
;; Security Level : UNCHECKED
;; HEADER SECTION
;; id = 26362
;; qr = true    opcode = Update    rcode = NOERROR
;; zocount = 1  prcount = 0  upcount = 0  adcount = 1

OPT pseudo-record : payloadsize 4096, xrcode 0, version 0, flags 32768

;; ZONE SECTION (1  record)
;; app.example.com. IN SOA



dig @ns1.example.com testapp1-testns1.app.example.com CNAME
; <<>> DiG 9.9.2-rl.028.23-P1-RedHat-9.9.2-8.P1.fc18 <<>> @ns1.example.com testapp1-testns1.example.com CNAME
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 50598
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;testapp1-testns1.example.com. IN CNAME

;; AUTHORITY SECTION:
example.com.  10 IN SOA ns1.example.com. hostmaster.example.com. 2011112904 60 15 1800 10

;; Query time: 3 msec
;; SERVER: 192.168.5.11#53(192.168.5.11)
;; WHEN: Thu Dec  5 15:31:20
;; MSG SIZE  rcvd: 108

This is what a negative response looks like. There's a question section but no answer section.
Things are back where I started and I can move on to the next test.

Resources

Monday, December 3, 2012

OpenShift Broker Configuration and Log Files

There are a lot of moving parts in an OpenShift Broker service. There are the four back-end services to start with. Then there's the front end HTTP daemon and the Rails broker application. There's SELinux security and the Passenger Rails accelerator service. Each of these needs some kind of configuration which may need some tweaking. Each of them also has either a specific log file or some other output somewhere that can be used for status checks and diagnostics.

In this post I'm going to run down a list of these configurations and logs and the service components they relate to.  Each of these gets some attention in the Build-Your-Own wiki instructions.

Configuration Directories


The OpenShift broker service (even if you set aside the back-end services) is an amalgam of components.  Each of these may have some customization for for the final working environment.  Each is also an opportunity for something to get broken or tweaked.

Without some understanding of the interactions between the components the set of configurations might seem unfathomable.  Even with some understanding it can be complex, but it does not need to be overwhelming.

These are the places where configuration files are known to lurk.  

OpenShift Broker Configuration Directories
DirectoryPurposeDescription
/etc/openshift Master Location Master configuration directory for all openshift related services
/etc/openshift/plugins.d Broker Plugin Configuration This is where plugin configuration files are placed. These files select the plugins for each back end service. They also contain customization (service location, authentication information etc).
/var/www/openshift/broker Rails Application Root This directory contains the Rails application which is the OpenShift Broker service. At the top level are the Gemfile and Gemfile.lock which control the application rubygems.
/var/www/openshift/broker/config/environments Rails configuration This directory contains the Rails application "environments". Each file here corresponds to a possible run mode for the OpenShift broker service. See also /etc/openshift/development
/var/www/openshift/broker/config/httpd/conf.d Broker HTTPD This directory contains the broker httpd configuration files.
/etc/httpd/conf.d Front end HTTPD This directory is the standard configuration location for the front-end Apache2 daemon.

If you're poking around wondering what goes on behind the scenes and how it's controlled, these are the places to start.

Configuration Files


Each of the locations above can contain a number of different and only marginally related configuration files. The list below contains all of the files that appear to need special attention of some kind during service configuration.  I don't try to mention every possible setting or switch here.  I'm just trying to give you an idea of what you might find in each one.  See the Build-Your-Own wiki page and the official OpenShift Enterprise service documentation for details.

This file defines a number of parameters for the service. This is the development configuration.


OpenShift Broker Configuration Files
FileFormatDescription
/etc/openshift/broker.conf Shell Key/Value This file defines a number of parameters for the service. This is the production configuration.
/etc/openshift/broker-dev.conf Shell Key/Value
/etc/openshift/development none When this file exists the broker service will start in dev mode, using the broker-dev.conf and developement.rb files.
/etc/openshift/server_priv.pem PEM/RSA This key file is used to authenticate optional services.
Generated by openssl
/etc/openshift/server_pub.pem PEM/RSA This key file is used to authenticate optional services
Generated by openssl
/etc/openshift/rsync_id_rsa.* SSH/RSA This key file pair is used to authenticate when moving gears from one node to another.
Generated by ssh-keygen
/etc/openshift/plugins.d/*.conf Shell Key/Value These are magic files. The file name must match the name of a local rubygem and end with .conf.The gem is loaded and the configuration file is parsed and included by the plugin gem
These plugins are loaded as part of the Rails start up process, as specified in the Gemfile
/var/www/openshift/broker/Gemfile Rails/Bundler This file defines the rubygem package requirements for the broker application.
It is used by the bundle command to generate the Gemfile.lock
/var/www/openshift/broker/Gemfile.lock Rails/Bundler This file defines the actual rubygem packages which fullfill the broker application requirements on this system. It is regenerated each time the openshift-broker service is restarted.
/var/www/openshift/broker/httpd/conf.d/*.conf Apache Pick one of the auth conf samples.
This file controls the broker service user identification/authentication when the "remote user" plugin is selected. The "remote user" plugin delegates the authentication to the httpd service which can then use any auth module.
Currently there are example config files for Basic auth, for LDAP and Kerberos.
/etc/openshift/htpasswd Apache If the broker httpd uses the Basic Auth module, this file contains the username/password pairs for the broker service.
/var/www/openshift/broker/config/environments/production.rb Ruby/Rails This file defines the production configuration values for the OpenShift broker service. Debugging stack traces are suppressed.
/var/www/openshift/broker/config/environments/development.rb Ruby/Rails This file defines the development configuration values for the OpenShift broker service. Debugging stack traces are returned in line.
/etc/httpd/conf.d/000000_openshift_origin_broker_proxy.conf Apache2 This file defines the proxy configurations for the Openshift broker and console services. It also sets the ServerName for the system as a whole
/etc/mcollective/client.cfg YAML This file defines the Mcollective client communications parameters. It connects to the underlying message service.  It also can indicate where the client activity is logged and control the logging level.

Broker Plugin Configuration Files


The files in /etc/openshift/plugins.d are a bit magical.  They are loaded when the Gemfile is processed as the Rails application starts.  Each file in that directory that ends in .conf will be processed.  The file name (minus the .conf extension must be the name of a locally installed rubygem.  The named gem is loaded and the config  file is then processed by the gem.  You can't just create a new config file there and put config values in it.  Well you can but it will cause your broker to fail.


Log Files



If things aren't behaving as you think they should, or if you just want to get a sense of how things should look, these are places you can check.

OpenShift Log Files
FileSourceDescription
/var/log/messages syslog System wide log file
/var/log/mcollective-client.log MCollective client Mcollective log file. Location defined in client.cfg. Log level also defined.
/var/log/httpd/access_log httpd Front end proxy httpd
/var/log/httpd/error_log httpd Front end proxy httpd
/var/log/httpd/ssl_access_log httpd Front end proxy httpd
/var/log/httpd/ssl_error_log httpd Front end proxy httpd
/var/log/secure syslog System access
/var/log/audit/audit.log syslog SELinux activity
/var/www/openshift/broker/log/development.log Rails Logs from development mode
/var/www/openshift/broker/log/production.log Rails Logs from production mode
/var/www/openshift/broker/httpd/logs/access_log Apache 2 Broker access
/var/www/openshift/broker/httpd/logs/error_log Apache 2 Broker errors