Gem vs. RPM script
by Chris Lalancette
All,
Here is a useful script that I've been using. It essentially compares
the gems to the RPMs that you have installed, to see which gems you might be
using that are not packaged. It's not all that intelligent, in that it doesn't
handle versioning, but I've found it somewhat useful.
--
Chris Lalancette
12 years, 10 months
1604 - Deployable model and UI
by Jan Provazník
Updated version according to Scott's feedback. It's possible I made a silly
mistake in permissions definitions. This patch depends on #1597 patch.
I'm on PTO half of next week so feel free to update/push patch.
Jan
12 years, 10 months
[PATCH 1/3] augmented IWHD-backed model to add explicit methods to pull latest_build and provider, and to filter on provider+build
by Scott Seago
Signed-off-by: Scott Seago <sseago(a)redhat.com>
---
src/app/models/image.rb | 6 +++++-
src/app/models/provider_image.rb | 22 +++++++++++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 6cb232c..6246969 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -8,7 +8,11 @@ class Image < WarehouseModel
end
end
+ def latest_build
+ ImageBuild.find(@latest_build) if @latest_build
+ end
+
def image_builds
ImageBuild.find_all_by_image_uuid(self.uuid)
end
-end
\ No newline at end of file
+end
diff --git a/src/app/models/provider_image.rb b/src/app/models/provider_image.rb
index d50e622..fb71f80 100644
--- a/src/app/models/provider_image.rb
+++ b/src/app/models/provider_image.rb
@@ -7,4 +7,24 @@ class ProviderImage < WarehouseModel
send(:"#{k}=", v)
end
end
-end
\ No newline at end of file
+
+ def provider
+ Provider.find_by_name(@provider)
+ end
+
+ def self.find_all_by_provider_and_build(provider, build)
+ provider_name = provider.name
+ build_uuid = build.uuid
+ self.set_warehouse_and_bucket if self.bucket.nil?
+ self.bucket.objects.map do |wh_object|
+ if wh_object.attr('provider')[1] == provider_name
+ # FIX ME: We need to add build metadata tag so we don't need
+ # this extra query
+ target_uuid = wh_object.attr('target_image')[1]
+ if TargetImage.find(target_uuid).build == build_uuid
+ ProviderImage.new(wh_object.attrs(wh_object.attr_list))
+ end
+ end
+ end.compact
+ end
+end
--
1.7.4.4
12 years, 10 months
RFC - Use VCR to mock iwhd calls
by Matt Wagner
Hi,
I'm not quite ready to include this, for various reasons, but I wanted to send this out for a preview.
We want to mock out calls to iwhd to enable testing. This uses VCR and overrides Warehouse::Client's do_request to use a 'cassette'. This setup isn't quite ideal right now, as it forces all calls to be served out of the single 'iwhd_connection' file. However, this should at least get us rolling. The use_cassette call will serve requests out of iwhd_connection.yaml if it's available; otherwise it will get them from actual iwhd and save the results to that file. (We'll want to check in iwhd_connection.yaml once this is set up.)
This patch requires the 'vcr' and 'webmock' gems. Sadly, neither is in Fedora yet, so this will introduce two new dependencies (for testing), which isn't so great.
12 years, 10 months
== operator for WarehouseClient
by Matt Wagner
Scott needs Image.find('foo') == Image.find('foo') to not return false in order to write sensible tests. I threw together a quick comparison, and even wrote a few tests.
In the process of working with this, I found myself repeatedly wishing for .first and .last methods like ActiveRecord implements. I ended up duplicating a lot of code from .all, so I factored that out into bucket_objects. (I'd like to add tests for these, but that depends on me having access to the tests Scott's working on...)
12 years, 10 months
[PATCH conductor 1/2] Fix the filter/pretty view toggle
by Tomas Sedovic
From: Tomas Sedovic <tsedovic(a)redhat.com>
---
src/app/controllers/deployments_controller.rb | 8 +---
src/app/controllers/pools_controller.rb | 16 ++++---
src/app/views/deployments/_filter_view_show.haml | 3 +
src/app/views/deployments/_header_show.haml | 5 ++
src/app/views/deployments/_pretty_view_show.haml | 3 +
src/app/views/deployments/show.haml | 3 +-
src/app/views/pools/_header_show.haml | 1 +
src/app/views/pools/index.haml | 5 +--
src/app/views/pools/show.haml | 1 -
src/public/javascripts/application.js | 48 +++++++++++++++------
10 files changed, 60 insertions(+), 33 deletions(-)
create mode 100644 src/app/views/deployments/_filter_view_show.haml
create mode 100644 src/app/views/deployments/_header_show.haml
create mode 100644 src/app/views/deployments/_pretty_view_show.haml
diff --git a/src/app/controllers/deployments_controller.rb b/src/app/controllers/deployments_controller.rb
index 39b36d0..8c5c193 100644
--- a/src/app/controllers/deployments_controller.rb
+++ b/src/app/controllers/deployments_controller.rb
@@ -110,13 +110,9 @@ class DeploymentsController < ApplicationController
@tab_captions = ['Properties', 'Instances', 'Provider Services', 'Required Services', 'History', 'Permissions','Operation']
@details_tab = params[:details_tab].blank? ? 'properties' : params[:details_tab]
save_breadcrumb(deployment_path(@deployment), @deployment.name)
+ @view = filter_view? ? 'filter_view_show' : 'pretty_view_show'
respond_to do |format|
- format.js do
- if @url_params.delete :details_pane
- render :partial => 'layouts/details_pane' and return
- end
- render :partial => @details_tab and return
- end
+ format.js { render :partial => @view }
format.html { render :action => 'show'}
format.json { render :json => @deployment }
end
diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb
index 707d32c..b9c080b 100644
--- a/src/app/controllers/pools_controller.rb
+++ b/src/app/controllers/pools_controller.rb
@@ -37,12 +37,14 @@ class PoolsController < ApplicationController
end
statistics
respond_to do |format|
- format.js { if filter_view?
- render :partial => params[:only_tab] == "true" ? @details_tab[:view] : 'layouts/tabpanel'
- else
- render :partial => 'pretty_list'
- end }
- format.html
+ format.js do
+ if filter_view?
+ render :partial => params[:only_tab] == "true" ? @details_tab[:view] : 'layouts/tabpanel'
+ else
+ render :partial => 'pretty_list'
+ end
+ end
+ format.html { @view = filter_view? ? 'layouts/tabpanel' : 'pretty_list' }
format.json { render :json => @pools }
end
save_breadcrumb(pools_path(:viewstate => @viewstate ? @viewstate.id : nil))
@@ -52,7 +54,7 @@ class PoolsController < ApplicationController
@pool = Pool.find(params[:id])
require_privilege(Privilege::VIEW, @pool)
@statistics = @pool.statistics
- @view = params[:view] == 'filter' ? 'deployments/filter_view' : 'deployments/pretty_view'
+ @view = filter_view? ? 'deployments/filter_view' : 'deployments/pretty_view'
respond_to do |format|
format.js { render :partial => @view, :locals => {:deployments => @pool.deployments} }
format.html { render :action => :show}
diff --git a/src/app/views/deployments/_filter_view_show.haml b/src/app/views/deployments/_filter_view_show.haml
new file mode 100644
index 0000000..8146912
--- /dev/null
+++ b/src/app/views/deployments/_filter_view_show.haml
@@ -0,0 +1,3 @@
+%h3
+ Filter View for
+ = @deployment.name
diff --git a/src/app/views/deployments/_header_show.haml b/src/app/views/deployments/_header_show.haml
new file mode 100644
index 0000000..0cf8729
--- /dev/null
+++ b/src/app/views/deployments/_header_show.haml
@@ -0,0 +1,5 @@
+%header.page-header
+ %h1.deployments
+ = [@deployment.name, "Deployment"].join(' ')
+ = pretty_filter_toggle(deployment_path(@deployment, :view => 'pretty'), deployment_path(@deployment, :view => 'filter'))
+ .corner
diff --git a/src/app/views/deployments/_pretty_view_show.haml b/src/app/views/deployments/_pretty_view_show.haml
new file mode 100644
index 0000000..f8e586d
--- /dev/null
+++ b/src/app/views/deployments/_pretty_view_show.haml
@@ -0,0 +1,3 @@
+%h3
+ Pretty View for
+ = @deployment.name
diff --git a/src/app/views/deployments/show.haml b/src/app/views/deployments/show.haml
index d24154a..3e06c70 100644
--- a/src/app/views/deployments/show.haml
+++ b/src/app/views/deployments/show.haml
@@ -1 +1,2 @@
-= render :partial => 'properties'
\ No newline at end of file
+= render :partial => 'header_show'
+= render :partial => @view
diff --git a/src/app/views/pools/_header_show.haml b/src/app/views/pools/_header_show.haml
index 038ca29..374dad8 100644
--- a/src/app/views/pools/_header_show.haml
+++ b/src/app/views/pools/_header_show.haml
@@ -1,6 +1,7 @@
%header.page-header
%h1.pools
= [@pool.name, "Pool"].join(' ')
+ = pretty_filter_toggle(pool_path(@pool, :view => 'pretty'), pool_path(@pool, :view => 'filter'))
#obj_actions.button-container
= link_to 'New Deployment', launch_new_deployments_path(:pool_id => @pool.id), :class => 'button primary', :id => 'new_deployment_button'
-# ditch form_for since it doesn't allow specification of a CSS class.
diff --git a/src/app/views/pools/index.haml b/src/app/views/pools/index.haml
index e24f692..5d82e6c 100644
--- a/src/app/views/pools/index.haml
+++ b/src/app/views/pools/index.haml
@@ -7,7 +7,4 @@
= render :partial => 'scoreboard_index'
= render :partial => 'alerts_index'
-- if params[:view] == 'filter'
- = render :partial => 'layouts/tabpanel'
-- else
- = render :partial => 'pretty_list'
+= render :partial => @view
diff --git a/src/app/views/pools/show.haml b/src/app/views/pools/show.haml
index 9986a23..43b0452 100644
--- a/src/app/views/pools/show.haml
+++ b/src/app/views/pools/show.haml
@@ -1,6 +1,5 @@
= render :partial => 'header_show'
= render :partial => 'scoreboard_show'
-= pretty_filter_toggle(pool_path(@pool, :view => 'pretty'), pool_path(@pool, :view => 'filter'))
-# TODO - Alerts aren't implemented just yet
-#= render :partial => 'alerts'
diff --git a/src/public/javascripts/application.js b/src/public/javascripts/application.js
index 3e5aac0..4397606 100644
--- a/src/public/javascripts/application.js
+++ b/src/public/javascripts/application.js
@@ -79,22 +79,42 @@ var Conductor = {
$('#details-view').tabs('destroy').tabs();
},
+ resetContent: function() {
+ var $nav_history = $('#nav_history');
+ var $page_header = $('header.page-header');
+ var $scoreboard = $('#scoreboard');
+ return $('#content')
+ .html('')
+ .append($nav_history)
+ .append($page_header)
+ .append($scoreboard);
+ },
+
+ /* This hooks the specified callback to the jQuery element's click action in
+ a non-evil manner: it will not hijack middle-click, ctrl+click or
+ shift+click actions because these already have a defined behaviour in
+ most browsers. */
+ nicelyHookAjaxClick: function($element, callback) {
+ $element.live('click', function(ev) {
+ if(ev.which == 2 || ev.metaKey || ev.ctrlKey || ev.shiftKey) return true;
+
+ ev.preventDefault();
+ callback.call($element);
+ });
+ },
+
bind_pretty_toggle: function() {
- $("#pretty_view").click(function(){
- $.get($(this).attr("href"), $(this).serialize(),
- function(result) {
- $("#view").html(result);
- });
- return false;
+ Conductor.nicelyHookAjaxClick($("#pretty_view"), function() {
+ $.get($(this).attr("href"), $(this).serialize(), function(result) {
+ Conductor.resetContent().append(result);
+ });
});
- $("#filter_view").click(function(){
- $.get($(this).attr("href"), $(this).serialize(),
- function(result) {
- $("#view").html(result);
- $('#details-selected').hide();
- $('#details-view').tabs('destroy').tabs();
- });
- return false;
+ Conductor.nicelyHookAjaxClick($("#filter_view"), function() {
+ $.get($(this).attr("href"), $(this).serialize(), function(result) {
+ Conductor.resetContent().append(result);
+ $('#details-selected').hide();
+ $('#details-view').tabs();
+ });
});
},
--
1.7.4.4
12 years, 10 months
High Availability in Aeolus
by Steven Dake
Since March the pacemaker cloud project [1] has been working to provide
high availability functionality for Aeolus.
What is high service availability?
==================================
A high degree of availability [2] applied to end user applications. For
more details, see some more detailed mathematical constructs see [3].
How do you achieve high service availability?
=============================================
There are four major steps:
1. Monitor components failure
2. Isolate and terminate failed component
3. recover component by restart and escalation
4. report error so that a physical repair can be made
How does this relate to Aeolus?
===============================
Aeolus has several components that we are interested in appling the HA
methodology to. These are applications, assemblies, and deployables.
In order to execute the high availability methodology, pacemaker-cloud
needs to know how an application is started, stopped, or monitored.
This is usually achieved via init scripts, but custom mechanisms could
also be used.
What is recovery escalation?
===========================
If steps 2 or 3 fail, it is an indicator that the higher level object
may have failed, and at minimum can no longer be trusted. For example,
if an application fails to restart, the assembly may be bad. To resolve
this problem, we escalate application failures into assembly failures.
Why monitor applications at all?
================================
Most enterprise software consumers want automatic restart of failed
applications with escalation because unavailability of services results
in lost opportunity. The only way to achieve recovery is to notice the
fault happened in the first place, via active monitoring.
why just not use cloud provider to tell us assembly has failed?
===============================================================
This technique, called passive monitoring, relies on the cloud provider
to determine that the vm has failed. Unfortunately it doesn't actually
check the health of the virtual machine internally. A more advanced
approach is active monitoring, where the internal function of the
virtual machine is checked periodically.
What do we need out of Aeolus?
==============================
1. We need Matahari installed in the jeos assemblies.
2. An XML schema that describes the user application's start, stop, and
monitoring mechanism. This is typically achieved through init scripts
or ocf compliant scripts on the assembly.
Regards
-steve
[1] http://www.pacemaker-cloud.org
[2] http://en.wikipedia.org/wiki/Availability
[3]
http://www.redhat.com/summit/2011/presentations/summit/whats_new/thursday...
12 years, 10 months
Backing up/restoring Aeolus
by Justin Clift
Hi everyone,
What do we need to capture, in order to back up an Aeolus
installation, so we can restore it later in case the box
it's on dies?
My initial thinking is the PostgreSQL database, but not
sure what else? Are images/metadata/etc on the filesystem
anywhere that would need to be backed up/restored too?
Regards and best wishes,
Justin Clift
--
Aeolus Community Manager
http://www.aeolusproject.org
12 years, 10 months
Couple questions on push method for cli
by Jason Guiditta
Hey Mark, was just chatting with Scott on irc trying to figure out a
couple things that were not clear to me. I had one concern, and Scott
had another. I'll list them here and hope you have an answer, or at
least that we can figure out an approach in fairly short order.
1. If you pass 2 accounts (in your credentials block) and one provider,
does it upload for each account (assuming they are both for this
provider) or just the first?
2. How are account credentials matched to providers, and who is
responsible?
IOW, say I have providers mock1, rhevm-rdu, and ec2-us-east1 and
credentials for 1 or more accounts on each and I pass in some subset of
those providers to the push method. How does that all get matched up,
and who does it (factory, aeolus-image, $someone-else)? I am not sure
this makes any sense, so I'll paste a bit of xml and hope that if I ask
around that, it will clarify my concern (this example can be used for
both points above).
<provider_accounts>
<provider_account>
<name>mockaccount1</name>
<provider>mock1</provider>
<provider_type>mock</provider_type>
<provider_credentials>
<mock_credentials>
<password>mockpassword</password>
<username>mockuser</username> </mock_credentials>
</provider_credentials>
</provider_account>
<provider_account>
<name>mockaccount2</name>
<provider>mock1</provider>
<provider_type>mock</provider_type>
<provider_credentials>
<mock_credentials>
<password>mockpassword</password>
<username>mockuser</username> </mock_credentials>
</provider_credentials>
</provider_account>
</provider_accounts>
Assume the above block also had one valid account chunk for rhev and
ec2, and rackspace (which was not included in the call to push). Will
factory look at that block and say, 'ok, I need to use the
provider_account chunks for the 2 that contain 'mock1' as the provider
(since mock1 was specified as a provider to push to), and use one or
more of those chunks to actually effect an upload to that cloud'? Hope
that made sense, thanks for any feedback on these issues.
-j
12 years, 10 months
Add multi destroy validation
by Jirka Tomasek
This patch adds multiDestroyValidation method to application.js. It
should be used by all views with tables which have multi destroy
functionality. Script is based on Delete button having id of
delete_button and table containing checkboxes having class
checkbox_table. In this patch it is implemented for all views in
Administration section.
12 years, 10 months