foreman_pipeline 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +13 -1
  3. data/Rakefile +1 -39
  4. data/app/controllers/foreman_pipeline/api/jobs_controller.rb +1 -1
  5. data/app/lib/actions/foreman_pipeline/job/create_host.rb +1 -3
  6. data/app/lib/actions/foreman_pipeline/job/cv_promote_job_hook.rb +5 -5
  7. data/app/lib/actions/foreman_pipeline/job/cv_publish_job_hook.rb +1 -1
  8. data/app/lib/actions/foreman_pipeline/job/multiple_promotions.rb +1 -2
  9. data/app/lib/actions/foreman_pipeline/job/promote.rb +3 -2
  10. data/app/lib/actions/foreman_pipeline/job/repo_sync_job_hook.rb +1 -1
  11. data/app/lib/actions/foreman_pipeline/job/run_job_manually.rb +7 -2
  12. data/app/models/foreman_pipeline/concerns/content_view_extension.rb +2 -2
  13. data/app/models/foreman_pipeline/concerns/content_view_repository_extension.rb +3 -3
  14. data/app/models/foreman_pipeline/concerns/kt_environment_extension.rb +1 -1
  15. data/app/models/foreman_pipeline/concerns/repository_extension.rb +2 -2
  16. data/app/models/foreman_pipeline/jenkins_instance.rb +2 -0
  17. data/app/models/foreman_pipeline/jenkins_project.rb +2 -0
  18. data/app/models/foreman_pipeline/jenkins_project_param.rb +1 -1
  19. data/app/models/foreman_pipeline/jenkins_user.rb +3 -1
  20. data/app/models/foreman_pipeline/job.rb +38 -7
  21. data/app/models/foreman_pipeline/job_jenkins_project.rb +2 -0
  22. data/app/models/foreman_pipeline/job_to_environment.rb +2 -0
  23. data/config/routes.rb +7 -7
  24. data/db/migrate/20141014125836_make_content_view_and_hostgroup_optional_for_job.rb +1 -1
  25. data/lib/foreman_pipeline/engine.rb +10 -2
  26. data/lib/foreman_pipeline/plugin.rb +3 -2
  27. data/lib/foreman_pipeline/tasks/foreman_pipeline_seed.rake +19 -9
  28. data/lib/foreman_pipeline/tasks/foreman_pipeline_test.rake +15 -25
  29. data/lib/foreman_pipeline/version.rb +1 -1
  30. data/test/factories/hostgroup_factory.rb +0 -1
  31. data/test/foreman_pipeline_plugin_test_helper.rb +35 -9
  32. data/test/unit/jenkins_instance_test.rb +31 -0
  33. data/test/unit/job_test.rb +211 -2
  34. metadata +49 -19
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTM3MmMwNTFhYmUwNDY4NzZhZTljMDgwZjRiYTcxYTY2YTBlOWRjMA==
4
+ OWEyOTk0NWZhOThkMGJhYTJlZmFiM2Q2ZmFmNjBhN2QyMTk0ZTFmMQ==
5
5
  data.tar.gz: !binary |-
6
- ZGExMWRhZDE2YTJkZjA0NmU1NzUwYWMyZTA1OTM1MmQyZWRlZWViZg==
6
+ MGFlODFhZTMxMjUxODExZmZlYWMxMmE1MGY0NDBhYzU0MTZmNmY3OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjkwZDQyMmIzNjU1YmZmMTUwMDkxODc5NmU1ZmE2ODRlN2RhYzUyNDA0MjA4
10
- ZTgwNTQ1YmQxN2E2NjAwN2E5N2E1Mzc0ODllOWM5ODMwMDQ2MTA0ZjMyYzYz
11
- NzVmMjllNGFlNTkyMDY2ZWQ4NzUyM2FlZTM0NjczYzQ3ZGY2YmI=
9
+ YWVhNjAyOTFhYTdiN2I4MzIwNzJkNTUxMzc5MWNjYTlmNjQ4ZjFlNTZkNzMx
10
+ MjQ5NDk1MTZhODY1ZWE4MTg5NDQzOGUxZDBlY2JmZTM3Y2Y5YjA0ZThmOTE2
11
+ MzgxMGMxMjgzZWVhNTY2ZmFiYzk0ZDg5NDM1MWI0ZWJkMTJkNDA=
12
12
  data.tar.gz: !binary |-
13
- MjU4NDNhNmYwMmJkMzlhNzQwMmYxMzgzMTY2OWY2MzI4OWRkOThmMGMwYWQz
14
- ZWFjZjk4Y2RlNzJkNGRjOGQ4MDk1ZDE3ZDE1MDgwNWI4MDIwNWQ0N2YyOGNm
15
- ZWQ5NDlmYTgwMjg2NDQwNGU3ZDhlOWVlNDUyYTdmYTljZjZlOTI=
13
+ ZmExZGVmOGQ4ZmYyOWUxODc1YzQwNDk0MDVjOGE4Zjc1MDhiMjFjNGY0MmRj
14
+ N2RjNTMyZWViNWNkMDAzNWU1ZmQwMGQxMDlhNDkwMzdkMzNlZDlkYzA4NTU1
15
+ ZmUyMDE4OTYyNjY3MGU4NGEzZGFiZjg1YTE0ZjBkNTczMDgwN2U=
data/README.md CHANGED
@@ -4,7 +4,18 @@ This project provides support for Jenkins builds triggered from within Foreman.
4
4
 
5
5
  ##Installation##
6
6
 
7
- from source:
7
+ ```
8
+ gem install foreman_pipeline
9
+ ```
10
+
11
+ and
12
+
13
+ ```
14
+ #foreman/bundler.d/*.local.rb
15
+ gem 'foreman_pipeline'
16
+ ```
17
+
18
+ or from source:
8
19
 
9
20
  ```
10
21
  #foreman/bundler.d/*.local.rb
@@ -31,6 +42,7 @@ rake foreman_pipeline:seed
31
42
  |:-------:|:-------:|:-------------------:|:------------------:|:----------------:|
32
43
  |>= 1.9 | >= 2.3 | ~> 0.0.1 | < 2.0.0 | 0.0.1 |
33
44
 
45
+
34
46
  ##Usage##
35
47
 
36
48
  See [wiki](https://github.com/xprazak2/foreman-pipeline/wiki/Jobs).
data/Rakefile CHANGED
@@ -1,40 +1,2 @@
1
1
  #!/usr/bin/env rake
2
- begin
3
- require 'bundler/setup'
4
- rescue LoadError
5
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
- end
7
- begin
8
- require 'rdoc/task'
9
- rescue LoadError
10
- require 'rdoc/rdoc'
11
- require 'rake/rdoctask'
12
- RDoc::Task = Rake::RDocTask
13
- end
14
-
15
- RDoc::Task.new(:rdoc) do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'ForemanPipeline'
18
- rdoc.options << '--line-numbers'
19
- rdoc.rdoc_files.include('README.rdoc')
20
- rdoc.rdoc_files.include('lib/**/*.rb')
21
- end
22
-
23
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
- load 'rails/tasks/engine.rake'
25
-
26
-
27
-
28
- Bundler::GemHelper.install_tasks
29
-
30
- require 'rake/testtask'
31
-
32
- Rake::TestTask.new(:test) do |t|
33
- t.libs << 'lib'
34
- t.libs << 'test'
35
- t.pattern = 'test/**/*_test.rb'
36
- t.verbose = true
37
- end
38
-
39
-
40
- task :default => :test
2
+ # useful tasks to be found in lib/foreman_pipeline/tasks
@@ -200,7 +200,7 @@ module ForemanPipeline
200
200
  rollback = {:occured => false}
201
201
  Job.transaction do
202
202
  projects = params[:projects].map do |p|
203
- JenkinsProject.create(:name => p, :organization => @organization)
203
+ JenkinsProject.create(:name => p, :organization_id => @organization.id)
204
204
  end
205
205
  projects_to_add = projects.delete_if { |p| @job.jenkins_projects.include? p }
206
206
  @job.jenkins_projects = @job.jenkins_projects + projects_to_add
@@ -18,9 +18,7 @@ module Actions
18
18
 
19
19
  def run
20
20
  hostgroup = Hostgroup.find(input[:hostgroup_id])
21
- location = Location.where(:name => "foreman_pipeline").first_or_create
22
- location.subnet_ids = (location.subnet_ids + [hostgroup.subnet_id]).uniq
23
- location.save!
21
+ location = Location.where(:name => "foreman_pipeline").first
24
22
  host = ::Host::Managed.new(
25
23
  name: input[:name],
26
24
  hostgroup: hostgroup,
@@ -7,15 +7,15 @@ module Actions
7
7
  Katello::ContentView::Promote
8
8
  end
9
9
 
10
- def plan(version, environment, is_force = false)
10
+ def plan(version, environment, is_force = false)
11
11
  valid_jobs = version.content_view.jobs.select { |job| job.is_valid? }
12
12
  jobs_to_run = valid_jobs.select { |job| version.eql? job.target_cv_version }
13
- allowed_jobs = jobs_to_run.select { |job| job.levelup_trigger && !job.version_already_promoted? }
14
-
13
+ allowed_jobs = jobs_to_run.select { |job| job.levelup_trigger && job.not_yet_promoted? }
14
+
15
15
  plan_self(:trigger => trigger.output,
16
16
  :job_ids => allowed_jobs.map(&:id),
17
- :job_names => allowed_jobs.map(&:name))
18
- end
17
+ :job_names => allowed_jobs.map(&:name))
18
+ end
19
19
  end
20
20
  end
21
21
  end
@@ -10,7 +10,7 @@ module Actions
10
10
  def plan(content_view, descripton)
11
11
  valid_jobs = content_view.jobs.select { |job| job.is_valid? }
12
12
  jobs_to_run = valid_jobs.select { |job| job.environment.library? }
13
- allowed_jobs = jobs_to_run.select { |job| job.levelup_trigger && !job.version_already_promoted? }
13
+ allowed_jobs = jobs_to_run.select { |job| job.levelup_trigger && job.not_yet_promoted? }
14
14
 
15
15
  plan_self(:trigger => trigger.output,
16
16
  :job_ids => allowed_jobs.map(&:id),
@@ -6,12 +6,11 @@ module Actions
6
6
 
7
7
  def plan(job)
8
8
  sequence do
9
- job.to_environments.each do |env|
9
+ job.envs_for_promotion.each do |env|
10
10
  plan_action(::Actions::Katello::ContentView::Promote, job.target_cv_version, env, false)
11
11
  end
12
12
  end
13
13
  end
14
-
15
14
  end
16
15
  end
17
16
  end
@@ -9,8 +9,9 @@ module Actions
9
9
  end
10
10
 
11
11
  def run
12
- unless job.environment.successors.empty?
13
- fail "Content View promotion disabled" if job.to_environments.empty?
12
+ unless job.environment.successors.empty? #when we are not at the end of lifecycle path
13
+ fail "Content View promotion disabled" unless job.should_be_promoted?
14
+ fail "Content view already promoted to the next environment(s), skipping promotion(s)" unless job.promotion_safe?
14
15
  promote_environment
15
16
  end
16
17
  end
@@ -11,7 +11,7 @@ module Actions
11
11
  valid_jobs = repo.jobs.select { |job| job.is_valid? }
12
12
 
13
13
  jobs_to_run = valid_jobs.select { |job| job.target_cv_version_avail? }
14
- allowed_jobs = jobs_to_run.select { |job| job.sync_trigger && !job.version_already_promoted? }
14
+ allowed_jobs = jobs_to_run.select { |job| job.sync_trigger && job.not_yet_promoted? }
15
15
  grouped_jobs = allowed_jobs.group_by(&:target_cv_version).values
16
16
 
17
17
  if grouped_jobs.max_by(&:length).length > 1
@@ -4,16 +4,21 @@ module Actions
4
4
  class RunJobManually < Actions::EntryAction
5
5
 
6
6
  def plan(job)
7
- if job.is_valid? && job.target_cv_version_avail? && !job.version_already_promoted?
7
+ if job.is_valid? && job.target_cv_version_avail? && job.not_yet_promoted?
8
8
  plan_action(DeployNewHost, job)
9
9
  plan_self(:info => "Manually triggered job started.", :name => job.name)
10
10
  else
11
- plan_self(:info => "Manually triggered job execution skipped, check job configuration.", :name => job.name)
11
+ plan_self(:info => "Manually triggered job execution skipped, check job configuration.", :name => job.name, :fail => true)
12
12
  end
13
13
  end
14
14
 
15
15
  def run
16
16
  output = input
17
+ fail input[:info] if input[:fail]
18
+ end
19
+
20
+ def rescue_strategy_for_self
21
+ Dynflow::Action::Rescue::Skip
17
22
  end
18
23
 
19
24
  def humanized_name
@@ -1,4 +1,4 @@
1
- module ForemanPipeline
1
+ module ForemanPipeline
2
2
  module Concerns
3
3
  module ContentViewExtension
4
4
  extend ActiveSupport::Concern
@@ -6,7 +6,7 @@ module ForemanPipeline
6
6
  included do
7
7
  has_many :jobs, :class_name => 'ForemanPipeline::Job', :inverse_of => :content_view, :dependent => :nullify
8
8
  end
9
-
9
+
10
10
  end
11
11
  end
12
12
  end
@@ -4,9 +4,9 @@ module ForemanPipeline
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- belongs_to :job, :class_name => 'ForemanPipeline::Job', :foreign_key => :content_view_id, :primary_key => :content_view_id
7
+ belongs_to :job, :class_name => 'ForemanPipeline::Job', :foreign_key => :content_view_id, :primary_key => :content_view_id
8
8
  end
9
-
9
+
10
10
  end
11
- end
11
+ end
12
12
  end
@@ -8,7 +8,7 @@ module ForemanPipeline
8
8
  :dependent => :destroy, :foreign_key => :to_environment_id
9
9
  has_many :jobs, :through => :job_to_environments, :class_name => 'ForemanPipeline::Job', :dependent => :nullify
10
10
  end
11
-
11
+
12
12
  def full_paths
13
13
  return [self.full_path] unless library?
14
14
  successors.map(&:full_path)
@@ -4,9 +4,9 @@ module ForemanPipeline
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- has_many :jobs, :class_name => 'ForemanPipeline::Job', :source => :job, :through => :content_view_repositories
7
+ has_many :jobs, :class_name => 'ForemanPipeline::Job', :source => :job, :through => :content_view_repositories
8
8
  end
9
9
 
10
10
  end
11
- end
11
+ end
12
12
  end
@@ -9,6 +9,8 @@ module ForemanPipeline
9
9
  include Glue::ElasticSearch::JenkinsInstance
10
10
  include ForemanPipeline::Authorization::JenkinsInstance
11
11
 
12
+ attr_accessible :name, :url, :organization_id, :pubkey, :jenkins_home, :cert_path, :jenkins_user_id
13
+
12
14
  belongs_to :organization
13
15
  has_many :jobs, :class_name => "ForemanPipeline::Job", :dependent => :nullify
14
16
  belongs_to :jenkins_user, :class_name => "ForemanPipeline::JenkinsUser"
@@ -8,6 +8,8 @@ module ForemanPipeline
8
8
 
9
9
  belongs_to :organization
10
10
 
11
+ attr_accessible :name, :organization_id
12
+
11
13
  has_many :job_jenkins_projects, :dependent => :destroy
12
14
  has_many :jobs, :through => :job_jenkins_projects, :class_name => 'ForemanPipeline::Job'
13
15
 
@@ -9,7 +9,7 @@ module ForemanPipeline
9
9
  self.inheritance_column = :_inheritance_type_disabled
10
10
  belongs_to :organization
11
11
  belongs_to :jenkins_project, :class_name => "ForemanPipeline::JenkinsProject"
12
- attr_accessible :name, :type, :description, :value
12
+ attr_accessible :name, :type, :description, :value, :organization_id, :jenkins_project_id
13
13
 
14
14
  TYPES = ["string", "boolean", "text"]
15
15
  validates :type, :inclusion => { :in => TYPES }
@@ -11,5 +11,7 @@ module ForemanPipeline
11
11
 
12
12
  validates :name, :presence => true
13
13
  validates :token, :presence => true
14
+
15
+ attr_accessible :name, :token, :organization_id
14
16
  end
15
- end
17
+ end
@@ -26,7 +26,10 @@ module ForemanPipeline
26
26
 
27
27
  validates :name, :presence => true
28
28
  validates :organization, :presence => true
29
- validate :no_composite_view
29
+ validate :no_composite_view, :check_env_succession
30
+
31
+ attr_accessible :name, :content_view_id, :hostgroup_id, :organization_id, :compute_resource_id, :jenkins_instance_id,
32
+ :environment_id, :manual_trigger, :levelup_trigger, :sync_trigger
30
33
 
31
34
  def is_valid?
32
35
  !self.attributes.values.include?(nil) && !self.jenkins_instance.jenkins_user.nil?
@@ -39,22 +42,41 @@ module ForemanPipeline
39
42
  def target_cv_version
40
43
  fail "Cannot fetch target version, no environment set" if environment.nil?
41
44
  fail "Cannot fetch target version, no content view set" if content_view.nil?
45
+ fail "Content view has no versions!" if content_view.content_view_versions.empty?
42
46
  self.environment.content_view_versions.where(:content_view_id => self.content_view.id).first
43
47
  end
44
48
 
45
49
  def init_run
46
50
  fail "Cannnot contact Jenkins server: no Jenkins Instance set for the job: #{name}" if jenkins_instance.nil?
47
- fail "Cannot log in to Jenkins server:
48
- no Jenkins User set for the Jenkins Instance: #{jenkins_instancej.name}" if jenkins_instance.jenkins_user.nil?
51
+ fail "Cannot log in to Jenkins server: no Jenkins User set for the Jenkins Instance: #{jenkins_instance.name}" if jenkins_instance.jenkins_user.nil?
49
52
  jenkins_instance.create_client(jenkins_instance.jenkins_user.name, jenkins_instance.jenkins_user.token)
50
53
  end
51
54
 
52
- def version_already_promoted?
53
- self.target_cv_version.environments.include?(self.environment.successor)
55
+ #Is any to_env set? (Do we want to promote to any env?)
56
+ def should_be_promoted?
57
+ !to_environments.empty?
58
+ end
59
+
60
+ # this shlould make sure not to trigger cyclic runs in hook actions
61
+ def not_yet_promoted?
62
+ # no to_envs means we do not want to promote, no need to check further here
63
+ return true if to_environments.empty?
64
+ #we want to promote, but are any of to_envs safe to promote to?
65
+ can_be_promoted?
66
+ end
67
+
68
+ #If we want to promote, is it safe (or could we get a cycle)?
69
+ def promotion_safe?
70
+ should_be_promoted? ? can_be_promoted? : false
71
+ end
72
+
73
+ #we have some to_envs set (== we want to promote), but cv version may already be in those envs
74
+ def envs_for_promotion
75
+ to_environments.reject { |env| target_cv_version.environments.include?(env) }
54
76
  end
55
77
 
56
- def environment_in_paths?(env_id)
57
- paths.map(&:full_path).flatten.uniq.map(&:id).include? env_id
78
+ def can_be_promoted?
79
+ !envs_for_promotion.empty?
58
80
  end
59
81
 
60
82
  def available_compute_resources
@@ -68,5 +90,14 @@ module ForemanPipeline
68
90
  "Cannot add content view, only non-composites allowed.") if !content_view.nil? && content_view.composite?
69
91
  end
70
92
 
93
+ def check_env_succession
94
+ if environment && should_be_promoted?
95
+ to_environments.each do |to_env|
96
+ unless to_env.prior == environment
97
+ errors.add(:base, "Environment succession violation: #{to_env.name}")
98
+ end
99
+ end
100
+ end
101
+ end
71
102
  end
72
103
  end
@@ -9,6 +9,8 @@ module ForemanPipeline
9
9
 
10
10
  after_destroy :remove_orphaned_projects
11
11
 
12
+ attr_accessible :job_id, :jenkins_project_id
13
+
12
14
  private
13
15
 
14
16
  def org_membership
@@ -7,6 +7,8 @@ module ForemanPipeline
7
7
  belongs_to :organization
8
8
  validate :org_membership
9
9
 
10
+ attr_accessible :job_id, :environment_id, :organization_id
11
+
10
12
  private
11
13
 
12
14
  def org_membership
data/config/routes.rb CHANGED
@@ -5,13 +5,13 @@ class ActionDispatch::Routing::Mapper
5
5
  end
6
6
 
7
7
  ForemanPipeline::Engine.routes.draw do
8
-
8
+
9
9
 
10
10
  scope :foreman_pipeline, :path => '/foreman_pipeline' do
11
-
11
+
12
12
  namespace :api do
13
-
14
- api_resources :organizations, :only => [] do
13
+
14
+ api_resources :organizations, :only => [] do
15
15
  api_resources :jobs do
16
16
  member do
17
17
  put :set_content_view
@@ -23,7 +23,7 @@ ForemanPipeline::Engine.routes.draw do
23
23
  get :run_job
24
24
  put :add_projects
25
25
  put :remove_projects
26
- put :set_to_environments
26
+ put :set_to_environments
27
27
  get :available_paths
28
28
  end
29
29
  end
@@ -46,8 +46,8 @@ ForemanPipeline::Engine.routes.draw do
46
46
  api_resources :jenkins_project_params, :only => [:update]
47
47
 
48
48
  api_resources :jenkins_users, :only => [:index, :create, :destroy, :show, :update]
49
-
49
+
50
50
  end
51
51
  end
52
- end
52
+ end
53
53
  end
@@ -1,5 +1,5 @@
1
1
  class MakeContentViewAndHostgroupOptionalForJob < ActiveRecord::Migration
2
- def up
2
+ def up
3
3
  change_column_null :integration_jobs, :content_view_id, true
4
4
  change_column_null :integration_jobs, :hostgroup_id, true
5
5
  end
@@ -2,13 +2,17 @@ module ForemanPipeline
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace ForemanPipeline
4
4
  require 'foreman_deployments'
5
+ require 'bastion'
6
+ require 'katello'
5
7
 
6
8
  initializer 'foreman_pipeline.mount_engine', :after => :build_middleware_stack do |app|
7
9
  app.routes_reloader.paths << "#{ForemanPipeline::Engine.root}/config/mount_engine.rb"
8
10
  end
9
11
 
10
12
  initializer 'foreman_pipeline.load_app_instance_data' do |app|
11
- app.config.paths['db/migrate'] += ForemanPipeline::Engine.paths['db/migrate'].existent
13
+ ForemanPipeline::Engine.paths['db/migrate'].existent.each do |path|
14
+ app.config.paths['db/migrate'] << path
15
+ end
12
16
  app.config.autoload_paths += Dir["#{config.root}/app/lib"]
13
17
  app.config.autoload_paths += Dir["#{config.root}/app/views/foreman"]
14
18
  end
@@ -29,6 +33,10 @@ module ForemanPipeline
29
33
  }
30
34
  end
31
35
 
36
+ initializer "foreman_pipeline.apipie" do
37
+ Apipie.configuration.checksum_path += ['/foreman_pipeline/api/']
38
+ end
39
+
32
40
  initializer 'foreman_pipeline.register_actions', :before => 'foreman_tasks.initialize_dynflow' do |app|
33
41
  ForemanTasks.dynflow.require!
34
42
 
@@ -39,7 +47,7 @@ module ForemanPipeline
39
47
 
40
48
  config.to_prepare do
41
49
 
42
- Bastion.register_plugin({
50
+ ::Bastion.register_plugin({
43
51
  :name => 'foreman_pipeline',
44
52
  :javascript => 'foreman_pipeline/foreman_pipeline',
45
53
  :stylesheet => 'foreman_pipeline/foreman_pipeline',
@@ -1,8 +1,9 @@
1
1
  Foreman::Plugin.register :foreman_pipeline do
2
-
2
+ requires_foreman '>= 1.9'
3
+
3
4
  sub_menu :top_menu, :foreman_pipeline_menu, :caption => N_('Pipeline') do
4
5
  menu :top_menu,
5
- :jobs,
6
+ :jobs,
6
7
  :caption => N_("Jobs"),
7
8
  :url => '/jobs',
8
9
  :url_hash => {:controller => 'foreman_pipeline/api/jobs', :action => 'index'},
@@ -3,16 +3,26 @@ namespace :foreman_pipeline do
3
3
  desc "seeding the database"
4
4
  task :seed => :environment do
5
5
  defaults = {:default => true, :locked => false}
6
- templates = [{:name => "foreman_pipeline_jenkins_pubkey", :source => "snippets/_jenkins_instance_pubkey.erb", :snippet => true}]
6
+ ProvisioningTemplate.without_auditing do
7
+ [
8
+ {:name => "foreman_pipeline_jenkins_pubkey", :source => "snippets/_jenkins_instance_pubkey.erb", :snippet => true}
9
+ ].each do |template|
10
+ template[:template] = File.read(File.join(ForemanPipeline::Engine.root, "app/views/foreman/unattended", template.delete(:source)))
7
11
 
8
- templates.each do |template|
9
- template[:template] = File.read(File.join(ForemanPipeline::Engine.root, "app/views/foreman/unattended", template.delete(:source)))
10
-
11
- ::ConfigTemplate.find_or_create_by_name(template) do |tmplt|
12
- tmplt.update_attributes(defaults.merge(template))
13
- end
12
+ ProvisioningTemplate.find_or_create_by_name(template) do |tmplt|
13
+ tmplt.update_attributes(defaults.merge(template))
14
+ end
15
+ end
14
16
  end
15
-
17
+
18
+ loc = Location.new(:name => "foreman_pipeline")
19
+ loc.organizations = Organization.all
20
+ loc.environments = Environment.all
21
+ loc.domains = Domain.all
22
+ loc.media = Medium.all
23
+ loc.subnets = Subnet.all
24
+ loc.compute_resources = ComputeResource.all
25
+ loc.smart_proxies = SmartProxy.all
26
+ loc.save!
16
27
  end
17
-
18
28
  end
@@ -1,34 +1,24 @@
1
1
  require File.expand_path("../engine", File.dirname(__FILE__))
2
2
 
3
3
  namespace :test do
4
-
5
- namespace :foreman_pipeline do
6
-
7
- task :test => ['db:test:prepare'] do
8
- test_task = Rake::TestTask.new('foreman_pipeline_test_task') do |t|
9
- t.libs << ["test", "#{ForemanPipeline::Engine.root}/test"]
10
- t.test_files = ["#{ForemanPipeline::Engine.root}/test/**/*_test.rb"]
11
- t.verbose = true
12
- end
13
- Rake::Task[test_task.name].invoke
14
- end
15
4
 
16
- task :spec => ['db:test:prepare'] do
17
- test_task = Rake::TestTask.new('foreman_pipeline_spec_task') do |t|
18
- t.libs << ["spec", "#{ForemanPipeline::Engine.root}/spec", "test", "#{ForemanPipeline::Engine.root}/test"]
19
- t.test_files = ["#{ForemanPipeline::Engine.root}/spec/**/*_spec.rb"]
20
- t.verbose = true
21
- end
22
- Rake::Task[test_task.name].invoke
5
+ task :foreman_pipeline => ['db:test:prepare'] do
6
+ test_task = Rake::TestTask.new('foreman_pipeline_test_task') do |t|
7
+ t.libs << ["test", "#{ForemanPipeline::Engine.root}/test"]
8
+ t.test_files = ["#{ForemanPipeline::Engine.root}/test/**/*_test.rb"]
9
+ t.verbose = true
23
10
  end
11
+ Rake::Task[test_task.name].invoke
24
12
  end
13
+ end
25
14
 
15
+ Rake::Task[:test].enhance do
16
+ Rake::Task['test:foreman_pipeline'].invoke
17
+ end
26
18
 
27
- desc "run all plugin's tests"
28
- task :foreman_pipeline do
29
- Rake::Task['test:foreman_pipeline:test'].invoke
30
- Rake::Task['test:foreman_pipeline:spec'].invoke
19
+ load 'tasks/jenkins.rake'
20
+ if Rake::Task.task_defined?(:'jenkins:unit')
21
+ Rake::Task["jenkins:unit"].enhance do
22
+ Rake::Task['test:foreman_pipeline'].invoke
31
23
  end
32
-
33
- end
34
-
24
+ end
@@ -1,3 +1,3 @@
1
1
  module ForemanPipeline
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  FactoryGirl.define do
2
2
  factory :pipeline_hostgroup, :class => Hostgroup do
3
3
  sequence(:name) { |n| "hostgroup#{n}" }
4
- compute_profile
5
4
  end
6
5
  end
@@ -1,17 +1,44 @@
1
1
  require "test_helper"
2
2
 
3
- def katello_root
4
- "#{ForemanPipeline::Engine::Railties.engines
5
- .select {|engine| engine.railtie_name == "katello"}
6
- .first.config.root}"
7
- end
8
-
9
- require "#{katello_root}/spec/models/model_spec_helper"
10
- FactoryGirl.definition_file_paths << File.join(katello_root, 'test', 'factories')
3
+ FactoryGirl.definition_file_paths << File.join(Katello::Engine.root, 'test', 'factories')
11
4
  FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
12
5
  FactoryGirl.reload
13
6
 
7
+ require "#{Katello::Engine.root}/test/support/fixtures_support"
8
+
9
+ module FixtureTestCase
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ extend ActiveRecord::TestFixtures
14
+
15
+ self.use_transactional_fixtures = true
16
+ self.use_instantiated_fixtures = false
17
+ self.pre_loaded_fixtures = true
18
+
19
+ Katello::FixturesSupport.set_fixture_classes(self)
20
+
21
+ self.fixture_path = Dir.mktmpdir("katello_fixtures")
22
+ FileUtils.cp(Dir.glob("#{Katello::Engine.root}/test/fixtures/models/*"), self.fixture_path)
23
+ FileUtils.cp(Dir.glob("#{Rails.root}/test/fixtures/*"), self.fixture_path)
24
+ fixtures(:all)
25
+ FIXTURES = load_fixtures
26
+
27
+ # load_permissions
28
+
29
+ Setting::Katello.load_defaults
30
+ end
31
+
32
+ module ClassMethods
33
+ def before_suite
34
+ @@admin = ::User.find(FIXTURES['users']['admin']['id'])
35
+ User.current = @@admin
36
+ end
37
+ end
38
+ end
39
+
14
40
  class ActiveSupport::TestCase
41
+ include FixtureTestCase
15
42
 
16
43
  def get_organization(org = nil)
17
44
  saved_user = User.current
@@ -24,5 +51,4 @@ class ActiveSupport::TestCase
24
51
  User.current = saved_user
25
52
  organization
26
53
  end
27
-
28
54
  end
@@ -0,0 +1,31 @@
1
+ require 'foreman_pipeline_plugin_test_helper'
2
+
3
+ class JenkinsInstanceTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @org = get_organization
7
+ @valid_url = "http://somewhere.com:8080"
8
+ @valid_home = "/var/lib/jenkins"
9
+ @valid_cert_path = "/home/user/.ssh/foreman-jenkins"
10
+ end
11
+
12
+ test "should be valid" do
13
+ @instance = ForemanPipeline::JenkinsInstance.create(:name => "test_jenkins_instance",
14
+ :url => @valid_url,
15
+ :cert_path => @valid_cert_path,
16
+ :jenkins_home => @valid_home,
17
+ :organization_id => @org.id)
18
+ assert @instance.errors.empty?
19
+ end
20
+
21
+ test "should have url" do
22
+ @instance = ForemanPipeline::JenkinsInstance.create(:name => "test_jenkins_instance",
23
+ :url => "invalid url",
24
+ :cert_path => @valid_cert_path,
25
+ :jenkins_home => @valid_home,
26
+ :organization_id => @org.id)
27
+ refute @instance.errors.empty?
28
+ end
29
+
30
+
31
+ end
@@ -5,7 +5,7 @@ class JobTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @organization = get_organization
7
7
  @compute_resource = FactoryGirl.create(:compute_resource, :libvirt)
8
- @hostgroup = FactoryGirl.create(:pipeline_hostgroup, :compute_profile => @compute_profile)
8
+ @hostgroup = FactoryGirl.create(:pipeline_hostgroup)
9
9
  @content_view = FactoryGirl.create(:katello_content_view)
10
10
  @jenkins_user = FactoryGirl.create(:jenkins_user, :organization => get_organization)
11
11
  @jenkins_instance = FactoryGirl.create(:jenkins_instance, :jenkins_user => @jenkins_user, :organization => get_organization)
@@ -23,4 +23,213 @@ class JobTest < ActiveSupport::TestCase
23
23
  assert job.is_valid?
24
24
  end
25
25
 
26
- end
26
+ test "should find target cv" do
27
+ cv = Katello::ContentView.find(katello_content_views(:acme_default))
28
+ env = Katello::KTEnvironment.find(katello_environments(:library))
29
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
30
+
31
+ job = ForemanPipeline::Job.create(:name => "test job",
32
+ :organization => @organization,
33
+ :hostgroup => @hostgroup,
34
+ :compute_resource => @compute_resource,
35
+ :content_view => cv,
36
+ :jenkins_instance => @jenkins_instance,
37
+ :environment => env,
38
+ :to_environments => [to_env])
39
+ target_v = cv.content_view_versions.select { |v| v.environments.include?(env) && !v.environments.include?(to_env) }.first
40
+ assert_equal target_v, job.target_cv_version
41
+ end
42
+
43
+ test "should not find target cv" do
44
+ cv = Katello::ContentView.find(katello_content_views(:acme_default))
45
+ env = Katello::KTEnvironment.find(katello_environments(:test))
46
+
47
+ job = ForemanPipeline::Job.create(:name => "test job",
48
+ :organization => @organization,
49
+ :hostgroup => @hostgroup,
50
+ :compute_resource => @compute_resource,
51
+ :content_view => cv,
52
+ :jenkins_instance => @jenkins_instance,
53
+ :environment => env)
54
+
55
+ assert_equal nil, job.target_cv_version
56
+ end
57
+
58
+ test "should find envs for promotion" do
59
+ cv = Katello::ContentView.find(katello_content_views(:acme_default))
60
+ env = Katello::KTEnvironment.find(katello_environments(:library))
61
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
62
+ to_env2 = Katello::KTEnvironment.find(katello_environments(:staging))
63
+
64
+ job = ForemanPipeline::Job.create(:name => "test job",
65
+ :organization => @organization,
66
+ :hostgroup => @hostgroup,
67
+ :compute_resource => @compute_resource,
68
+ :content_view => cv,
69
+ :jenkins_instance => @jenkins_instance,
70
+ :environment => env,
71
+ :to_environments => [to_env, to_env2])
72
+ assert_equal [to_env, to_env2], job.envs_for_promotion
73
+ end
74
+
75
+ test "envs_for_promotion should exclude one env from promotions" do
76
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
77
+ env = Katello::KTEnvironment.find(katello_environments(:library))
78
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
79
+ to_env2 = Katello::KTEnvironment.find(katello_environments(:staging))
80
+
81
+ job = ForemanPipeline::Job.create(:name => "test job",
82
+ :organization => @organization,
83
+ :hostgroup => @hostgroup,
84
+ :compute_resource => @compute_resource,
85
+ :content_view => cv,
86
+ :jenkins_instance => @jenkins_instance,
87
+ :environment => env,
88
+ :to_environments => [to_env, to_env2])
89
+ assert_equal [to_env2], job.envs_for_promotion
90
+ end
91
+
92
+ test "job can be promoted" do
93
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
94
+ env = Katello::KTEnvironment.find(katello_environments(:library))
95
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
96
+ to_env2 = Katello::KTEnvironment.find(katello_environments(:staging))
97
+
98
+ job = ForemanPipeline::Job.create(:name => "test job",
99
+ :organization => @organization,
100
+ :hostgroup => @hostgroup,
101
+ :compute_resource => @compute_resource,
102
+ :content_view => cv,
103
+ :jenkins_instance => @jenkins_instance,
104
+ :environment => env,
105
+ :to_environments => [to_env, to_env2])
106
+ assert job.can_be_promoted?
107
+ end
108
+
109
+ test "job cannot be promoted" do
110
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
111
+ env = Katello::KTEnvironment.find(katello_environments(:library))
112
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
113
+
114
+ job = ForemanPipeline::Job.create(:name => "test job",
115
+ :organization => @organization,
116
+ :hostgroup => @hostgroup,
117
+ :compute_resource => @compute_resource,
118
+ :content_view => cv,
119
+ :jenkins_instance => @jenkins_instance,
120
+ :environment => env,
121
+ :to_environments => [to_env])
122
+ refute job.can_be_promoted?
123
+ end
124
+
125
+ test "is promotion safe" do
126
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
127
+ env = Katello::KTEnvironment.find(katello_environments(:library))
128
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
129
+ to_env2 = Katello::KTEnvironment.find(katello_environments(:staging))
130
+
131
+ job = ForemanPipeline::Job.create(:name => "test job",
132
+ :organization => @organization,
133
+ :hostgroup => @hostgroup,
134
+ :compute_resource => @compute_resource,
135
+ :content_view => cv,
136
+ :jenkins_instance => @jenkins_instance,
137
+ :environment => env,
138
+ :to_environments => [to_env, to_env2])
139
+ assert job.promotion_safe?
140
+ end
141
+
142
+ test "is not promotion safe" do
143
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
144
+ env = Katello::KTEnvironment.find(katello_environments(:library))
145
+
146
+ job = ForemanPipeline::Job.create(:name => "test job",
147
+ :organization => @organization,
148
+ :hostgroup => @hostgroup,
149
+ :compute_resource => @compute_resource,
150
+ :content_view => cv,
151
+ :jenkins_instance => @jenkins_instance,
152
+ :environment => env)
153
+ refute job.promotion_safe?
154
+ end
155
+
156
+ test "is not promotion safe again" do
157
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
158
+ env = Katello::KTEnvironment.find(katello_environments(:library))
159
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
160
+
161
+ job = ForemanPipeline::Job.create(:name => "test job",
162
+ :organization => @organization,
163
+ :hostgroup => @hostgroup,
164
+ :compute_resource => @compute_resource,
165
+ :content_view => cv,
166
+ :jenkins_instance => @jenkins_instance,
167
+ :environment => env,
168
+ :to_environments => [to_env])
169
+ refute job.promotion_safe?
170
+ end
171
+
172
+ test "should detect env succession violation" do
173
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
174
+ env = Katello::KTEnvironment.find(katello_environments(:library))
175
+ to_env = Katello::KTEnvironment.find(katello_environments(:test))
176
+
177
+ job = ForemanPipeline::Job.new(:name => "test job",
178
+ :organization => @organization,
179
+ :hostgroup => @hostgroup,
180
+ :compute_resource => @compute_resource,
181
+ :content_view => cv,
182
+ :jenkins_instance => @jenkins_instance,
183
+ :environment => env,
184
+ :to_environments => [to_env])
185
+ job.save
186
+ assert_equal "Environment succession violation: #{to_env.name}", job.errors[:base].first
187
+ end
188
+
189
+ test "was not yet promoted" do
190
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
191
+ env = Katello::KTEnvironment.find(katello_environments(:library))
192
+ job = ForemanPipeline::Job.create(:name => "test job",
193
+ :organization => @organization,
194
+ :hostgroup => @hostgroup,
195
+ :compute_resource => @compute_resource,
196
+ :content_view => cv,
197
+ :jenkins_instance => @jenkins_instance,
198
+ :environment => env,
199
+ :to_environments => [])
200
+ assert job.not_yet_promoted?
201
+ end
202
+
203
+ test "there should be env for promotion" do
204
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
205
+ env = Katello::KTEnvironment.find(katello_environments(:dev))
206
+ to_env = Katello::KTEnvironment.find(katello_environments(:test))
207
+
208
+ job = ForemanPipeline::Job.create(:name => "test job",
209
+ :organization => @organization,
210
+ :hostgroup => @hostgroup,
211
+ :compute_resource => @compute_resource,
212
+ :content_view => cv,
213
+ :jenkins_instance => @jenkins_instance,
214
+ :environment => env,
215
+ :to_environments => [to_env])
216
+ assert_equal 1, job.envs_for_promotion.count
217
+ assert_equal to_env, job.envs_for_promotion.first
218
+ end
219
+
220
+ test "there shloud not be env for promotion" do
221
+ cv = Katello::ContentView.find(katello_content_views(:library_dev_view))
222
+ env = Katello::KTEnvironment.find(katello_environments(:library))
223
+ to_env = Katello::KTEnvironment.find(katello_environments(:dev))
224
+
225
+ job = ForemanPipeline::Job.create(:name => "test job",
226
+ :organization => @organization,
227
+ :hostgroup => @hostgroup,
228
+ :compute_resource => @compute_resource,
229
+ :content_view => cv,
230
+ :jenkins_instance => @jenkins_instance,
231
+ :environment => env,
232
+ :to_environments => [to_env])
233
+ assert job.envs_for_promotion.empty?
234
+ end
235
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_pipeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondřej Pražák
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-02 00:00:00.000000000 Z
11
+ date: 2015-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foreman_deployments
@@ -25,35 +25,49 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.0.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: bastion
28
+ name: jenkins_api_client
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - <
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 3.0.0
33
+ version: 1.4.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - <
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: 3.0.0
40
+ version: 1.4.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: net-ssh
42
+ name: katello
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - <=
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
- version: 2.9.2
47
+ version: 2.4.0.rc2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - <=
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
- version: 2.9.2
54
+ version: 2.4.0.rc2
55
55
  - !ruby/object:Gem::Dependency
56
- name: net-scp
56
+ name: bastion
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-ssh
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ! '>='
@@ -67,19 +81,33 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: jenkins_api_client
84
+ name: net-scp
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: less-rails
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
- - - <
101
+ - - ~>
74
102
  - !ruby/object:Gem::Version
75
- version: 2.0.0
103
+ version: 2.5.0
76
104
  type: :runtime
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
- - - <
108
+ - - ~>
81
109
  - !ruby/object:Gem::Version
82
- version: 2.0.0
110
+ version: 2.5.0
83
111
  description: Jenkins is able to deploy artifacts onto newly provisioned host by Foreman
84
112
  email:
85
113
  - oprazak@redhat.com
@@ -294,6 +322,7 @@ files:
294
322
  - test/factories/hostgroup_factory.rb
295
323
  - test/factories/jenkins_instance_related_factory.rb
296
324
  - test/foreman_pipeline_plugin_test_helper.rb
325
+ - test/unit/jenkins_instance_test.rb
297
326
  - test/unit/job_test.rb
298
327
  - test/unit/sanity_test.rb
299
328
  homepage: https://github.com/xprazak2/foreman-pipeline
@@ -315,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
344
  version: '0'
316
345
  requirements: []
317
346
  rubyforge_project:
318
- rubygems_version: 2.4.5
347
+ rubygems_version: 2.4.3
319
348
  signing_key:
320
349
  specification_version: 4
321
350
  summary: Makes Foreman talk to Jenkins CI server.
@@ -324,4 +353,5 @@ test_files:
324
353
  - test/factories/jenkins_instance_related_factory.rb
325
354
  - test/foreman_pipeline_plugin_test_helper.rb
326
355
  - test/unit/sanity_test.rb
356
+ - test/unit/jenkins_instance_test.rb
327
357
  - test/unit/job_test.rb