Several small fixes to aeolus-conductor initscript
by James Laska
Greetings,
While debugging some problems with thin startup, I made some minor adjustments
to the initscript to improve readability and status reporting.
> GIT: [PATCH 1/2] Whitespace cleanup
> GIT: [PATCH 2/2] Minor cleanup to initscript
Comments encouraged+welcome.
Thanks,
James
12 years, 5 months
I18N HOWTO
by Tomas Sedovic
Hello all,
With Jozef's tremendous effort we now have all UI strings in a dictionary.
Here's a couple of points that you may find relevant about keeping it
that way forward. Please do at least skim it all -- it's quite possible
there are some tricks in the I18n API that you're not aware of.
String Placement
----------------
From now on, strings that are visible in the UI should not be put
directly into the Conductor code.
They go to the dictionary located at:
conductor/src/config/locales/en.yml
It's a YAML file which for the most part follows the structure of our views.
For example, a "Pool Name" text that would find on the New Pool page
goes here:
pools:
new:
pool_name: Pool Name
Note that there is no need to put quotes around the string.
In the Code
-----------
To use a localized string in the code, you use the `I18n::t` (shorthand
for `translate`) function that comes in the I18n module with Rails.
The function takes the dictionary key and produces the appropriate string:
>> t('pools.new.pool_name')
=> "Pool Name"
You can drop the path in the views:
%p= t('.pool_name')
Rails will know that you're in the pools/new.haml.html view and it will
guess the location in the dictionary correctly.
Models don't have the I18n module included by default so you'll have to
specify it manually:
raise I18n::t('pools.errors.fatal_error')
Note that in models and controllers you *have* to specify the full path
in the dictionary. In views you can use the relative path.
Using Parameters
----------------
When it comes to localization, you can't rely on using code to modify
the strings.
For instance:
t('pool') + pools.count > 1 ? 's' : ''
Will work in English (it'll return "pool" for a single pool and "pools"
for multiples) but it will not work in a lot of other languages.
Different languages have quite different pluralization rules. Some of
them differ based on counts other than (count == 1) and (count > 1).
You have to specify these in the dictionary like so:
deleted:
one: The pool was deleted.
other: All the pools were deleted.
Now you can call:
>> t('deleted', :count => 1)
=> "The pool was deleted."
>> t('deleted', :count => 20)
=> "All the pools were deleted"
Now the translators can put all the different versions into the
dictionary and we won't have to pollute our code with pluralization logic.
Similarly, it's not safe to just combine strings and variables together.
This is bad:
%p= t('confirm_deletion') + @pool.name + t('pool_question')'
It may work in English ("Are you sure you want to delete the Default
pool?") but not in other languages that have a different word order.
I18n allows you to put parameters into the dictionary:
pools:
index:
confirm_deletion: Are you sure you want to delete %{name} pool?
You can then pass the parameters to the `t` function:
%p= t('.confirm_deletion', :name => @pool.name)
And you'll get the desired result with a much cleaner code which also
happens to be more friendly to all the other languages.
Reviewers
---------
As we're nearing the release, we'll have the UI translated to a lot of
different languages.
We must make sure that we don't regress to putting strings back into the
code or building the strings in some weird untranslatable way.
I would like to ask all reviewers to look out for this stuff from now on
as well.
All new or modified code must follow proper internationalization
practices. If you see a patch that doesn't, please point it out and
don't let it go in without being fixed first.
For more details, you can look at the Rails Guides document that covers
the I18n API we're using:
http://guides.rubyonrails.org/i18n.html
I've also put this document on our wiki. Do share and update it as needed:
https://www.aeolusproject.org/redmine/projects/aeolus/wiki/Internationali...
Cheers,
Thomas
--
No trees were killed to send this message, but a large number of
electrons were terribly inconvenienced.
12 years, 5 months
Faster Rails Testing
by Martyn Taylor
Hi Gents,
I recently attended a Rails event in Newcastle. One of the topics that
was brought up was how to increase the speed of Rails tests. Here is a
link from one of the talks in the Manchester Rails Conference (which I
did not attend) but was the focus of some discussion at the Newcastle
event.
http://tom-clements.com/blog/2011/10/23/4-steps-to-faster-rails-tests/
It's certainly not a comprehensive guide, but highlights 4 ways to help
speed up our suite.
Thanks
Martyn
12 years, 6 months
[PATCH conductor] Force dc:oauth_keys command to run in production environment
by Richard Su
This command failed in testing because under non-production environment
it was attempting to find rspec-rails, which may not be installed.
---
aeolus-conductor.spec.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/aeolus-conductor.spec.in b/aeolus-conductor.spec.in
index f353ef1..0d9c648 100644
--- a/aeolus-conductor.spec.in
+++ b/aeolus-conductor.spec.in
@@ -235,7 +235,7 @@ touch %{buildroot}%{_localstatedir}/log/%{name}/dbomatic.log
# if the user had broken the symlinks and put data in here, it would have been
# completely ignored *anyway*
# Generate OAuth configuration:
-pushd %{app_root}; rake dc:oauth_keys --trace; popd
+pushd %{app_root}; export RAILS_ENV=production; rake dc:oauth_keys --trace; popd
%{__ln_s} -f %{app_root}/config/environments/development.rb %{_sysconfdir}/%{name}
%{__ln_s} -f %{app_root}/config/environments/production.rb %{_sysconfdir}/%{name}
--
1.7.6.4
12 years, 6 months
Eucalyptus/Open Stack
by Kevin Fox
I just installed Fedora 16 Beta to give some cloud tech a try.
I then installed Open Stack and got it working properly.
Next up was to give Aeolus a try. Aeolus's website references Eucalyptus
support, which is one of the API's that Open Stack says it supports.
But, in the Aeolus UI I am not finding any way to configure Eucalyptus
Cloud Providers. I only see "Mock, Amazon EC2, GoGrid, Rackspace,
RHEV-M, OpenNebula, Condor Cloud, VMware vSphere". Maybe the
X-Deltacloud-Provider box is what I want to use? Any ideas?
Thanks,
Kevin
12 years, 6 months
[PATCH configure] BZ 749254 - running configure for multiple providers causes oauth issues.
by Richard Su
The problem was aeolus-configure generated new uuids each time it is invoked.
Matt has created a patch for conductor to have the rpm generate and install
a oauth.json file which will be the canonical source for the keys.
This patch augments configure to read oauth.json and to produce custom facts
replacing the auto generated uuids in aeolus-configure.
---
bin/aeolus-configure | 5 ---
recipes/aeolus/lib/facter/oauth.rb | 48 +++++++++++++++++++++++++++++
recipes/aeolus/manifests/image-factory.pp | 2 +-
3 files changed, 49 insertions(+), 6 deletions(-)
create mode 100644 recipes/aeolus/lib/facter/oauth.rb
diff --git a/bin/aeolus-configure b/bin/aeolus-configure
index 7123226..16a1bc0 100755
--- a/bin/aeolus-configure
+++ b/bin/aeolus-configure
@@ -68,11 +68,6 @@ echo "Launching aeolus configuration recipe..."
export FACTER_AEOLUS_ENABLE_HTTPS=true
export FACTER_AEOLUS_ENABLE_SECURITY=false
-export FACTER_IWHD_OAUTH_USER=`uuidgen`
-export FACTER_IWHD_OAUTH_PASSWORD=`uuidgen`
-export FACTER_IMAGEFACTORY_OAUTH_USER=`uuidgen`
-export FACTER_IMAGEFACTORY_OAUTH_PASSWORD=`uuidgen`
-
NODE_ARRAY=(`echo $PUPPET_NODE | tr "," "\n"`)
for x in "${NODE_ARRAY[@]}"
do
diff --git a/recipes/aeolus/lib/facter/oauth.rb b/recipes/aeolus/lib/facter/oauth.rb
new file mode 100644
index 0000000..e5caa7d
--- /dev/null
+++ b/recipes/aeolus/lib/facter/oauth.rb
@@ -0,0 +1,48 @@
+# Copyright 2011 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Read oauth values from /etc/aeolus-conductor/oauth.json and create facts
+# for them. The file is generated by aeolus-conductor rpm.
+
+require 'rubygems'
+require 'json'
+
+file = File.open("/etc/aeolus-conductor/oauth.json", 'r') or raise "Could not open file\
+"
+contents = file.read
+oauthconfig = JSON.parse(contents)
+
+Facter.add("imagefactory_oauth_user") do
+ setcode do
+ oauthconfig['factory']['consumer_key']
+ end
+end
+
+Facter.add("imagefactory_oauth_password") do
+ setcode do
+ oauthconfig['factory']['consumer_secret']
+ end
+end
+
+Facter.add("iwhd_oauth_user") do
+ setcode do
+ oauthconfig['iwhd']['consumer_key']
+ end
+end
+
+Facter.add("iwhd_oauth_password") do
+ setcode do
+ oauthconfig['iwhd']['consumer_secret']
+ end
+end
diff --git a/recipes/aeolus/manifests/image-factory.pp b/recipes/aeolus/manifests/image-factory.pp
index c386c1c..f4b4221 100644
--- a/recipes/aeolus/manifests/image-factory.pp
+++ b/recipes/aeolus/manifests/image-factory.pp
@@ -64,7 +64,7 @@ class aeolus::image-factory inherits aeolus {
file {"/etc/imagefactory/imagefactory.conf":
content => template("aeolus/imagefactory.conf"),
mode => 755,
- require => Package['imagefactory'] }
+ require => [Package['imagefactory'],Package['aeolus-conductor']] }
$requires = [Package['imagefactory'],
File['/var/tmp/imagefactory-mock',
--
1.7.6.4
12 years, 6 months
Search and filtering
by Angus Thomas
There was some discussion earlier around a set of achievable targets for
functionality behind the UI's global search text field, and around the
filtering controls which are part of the filter table which is used
across the app to present sets of data.
Attempting to get a balance between a design which is sufficiently
simple to implement quickly, and one which is sophisticated enough to be
useful, this is what we came up with:
- The global search bar
* Users will only enter a string which they wish to search for, and not
select a set of object types to search across etc.
* There is a finite list of objects in which that text could match (an
instance, an image template, an application template etc.)
* We'll have a single select query for each object which searches for
the user's string in a suitable set of the text fields of each instance
of that object
* We need a new UI page which will represent the query's results, with
some grouping of object types (the running instances grouped, then the
application templates etc.)
* Selecting an entry in the results will open up that instance in the
appropriate details page
- Filtering results in a table
* Users will enter a string into the text box which is in the header of
each instance of the filter table
* The record set contained in the table will be reduced, to only show
those records where the user's text was found amongst the text shown in
the table
* Note that we're filtering within the record set contained in the table
- *not* searching for the user's text in additional attributes of the
underlying objects which a row in the table refers to.
* As an additional approach to filtering the records in a table, we'll
add a drop-down list of options to filter on, which will be populated
depending on the object type which is being listed.
* We'll define a set of options to populate the drop-down list with for
each object type which is listed in the filter table.
* For example, when the table contains a list of instances, the
drop-down list will enable filtering based on the state of the instance
i.e. Pending, Running etc.
* The user will be limited to selecting a single entry from the drop
down list to filter the result sets on.
Questions, amendments, etc. gratefully received.
Angus
12 years, 6 months