diff --git a/.gitignore b/.gitignore
index 32c4421..45b891c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,15 @@
-.project
-.buildpath
\ No newline at end of file
+.vagrant
+Berksfile.lock
+*~
+*#
+.#*
+\#*#
+.*.sw[a-z]
+*.un~
+/cookbooks
+
+# Bundler
+Gemfile.lock
+bin/*
+.bundle/*
+
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000..8e31207
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,15 @@
+---
+driver:
+ name: vagrant
+
+provisioner:
+ name: chef_solo
+
+platforms:
+ - name: ubuntu-12.04
+ - name: centos-6.4
+
+suites:
+ - name: default
+ run_list:
+ attributes:
diff --git a/Berksfile b/Berksfile
new file mode 100644
index 0000000..c4bb297
--- /dev/null
+++ b/Berksfile
@@ -0,0 +1,3 @@
+site :opscode
+
+metadata
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..3017623
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gem 'berkshelf'
diff --git a/README.md b/README.md
index 9da9c23..d5a54ac 100644
--- a/README.md
+++ b/README.md
@@ -1,40 +1,9 @@
-# DESCRIPTION:
+Warning
+=======
-This cookbook basically translates the install instructions from http://docs.codehaus.org/display/SONAR/Install+Sonar#InstallSonar-Server into chef DSL.
+This cookbook is still on the state of Sonar 2.14 and not very generic. We use it for [metrics.typo3.org](http://metrics.typo3.org) were it does what it should.
-# REQUIREMENTS:
+Description
+===========
-* `java` + `jdk`
-* A database cookbook like `mysql` if you like to run sonar in production.
-The built in derby database is not recommended for production.
-
-# ATTRIBUTES:
-
-See `attributes/default.rb` for details.
-
-# USAGE:
-
-The cookbook installs sonar with derby database (default).
-Inlcude a `proxy_*` recipe to your `run_list` to access sonar over a proxy server.
-
-# Todos
-
-* Implement `dir` attribute to make installation path more flexible
-* Implement different Database backends like MySql
-* Implement plugin recipes eg. http://docs.codehaus.org/display/SONAR/PHP+Plugin
- Download jars to plugin folder, restart Sonar
-* Create database with mysql LWRP
-
- mysql_database "sonar" do
- host "localhost"
- username "root"
- password node[:mysql][:server_root_password]
- database "sonar"
- action :create_db
- end
-
-* Set allow / deny patterns with attributes for web access
-
- default['sonar']['web_deny'] = []
- default['sonar']['web_allow'] = []
-
+This Chef cookbook installs Sonar(Qube).
\ No newline at end of file
diff --git a/Thorfile b/Thorfile
new file mode 100644
index 0000000..cb1aeae
--- /dev/null
+++ b/Thorfile
@@ -0,0 +1,5 @@
+# encoding: utf-8
+
+require 'bundler'
+require 'bundler/setup'
+require 'berkshelf/thor'
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..133d52e
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,85 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure("2") do |config|
+ # All Vagrant configuration is done here. The most common configuration
+ # options are documented and commented below. For a complete reference,
+ # please see the online documentation at vagrantup.com.
+
+ config.vm.hostname = "sonar-berkshelf"
+
+ # Every Vagrant virtual environment requires a box to build off of.
+ config.vm.box = "opscode-debian-7.2"
+
+ # The url from where the 'config.vm.box' box will be fetched if it
+ # doesn't already exist on the user's system.
+ config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.2.0_chef-provisionerless.box"
+
+ # Assign this VM to a host-only network IP, allowing you to access it
+ # via the IP. Host-only networks can talk to the host machine as well as
+ # any other machines on the same network, but cannot be accessed (through this
+ # network interface) by any external networks.
+ config.vm.network :private_network, ip: "33.33.33.10"
+
+ # Create a public network, which generally matched to bridged network.
+ # Bridged networks make the machine appear as another physical device on
+ # your network.
+
+ # config.vm.network :public_network
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ # config.vm.synced_folder "../data", "/vagrant_data"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ #
+ # config.vm.provider :virtualbox do |vb|
+ # # Don't boot with headless mode
+ # vb.gui = true
+ #
+ # # Use VBoxManage to customize the VM. For example to change memory:
+ # vb.customize ["modifyvm", :id, "--memory", "1024"]
+ # end
+ #
+ # View the documentation for the provider you're using for more
+ # information on available options.
+
+ # The path to the Berksfile to use with Vagrant Berkshelf
+ # config.berkshelf.berksfile_path = "./Berksfile"
+
+ # Enabling the Berkshelf plugin. To enable this globally, add this configuration
+ # option to your ~/.vagrant.d/Vagrantfile file
+ config.berkshelf.enabled = true
+
+ # An array of symbols representing groups of cookbook described in the Vagrantfile
+ # to exclusively install and copy to Vagrant's shelf.
+ # config.berkshelf.only = []
+
+ # An array of symbols representing groups of cookbook described in the Vagrantfile
+ # to skip installing and copying to Vagrant's shelf.
+ # config.berkshelf.except = []
+
+ config.omnibus.chef_version = :latest
+
+ config.vm.provision :chef_solo do |chef|
+ chef.json = {
+ :mysql => {
+ :server_root_password => 'rootpass',
+ :server_debian_password => 'debpass',
+ :server_repl_password => 'replpass'
+ }
+ }
+
+ chef.run_list = [
+ "recipe[sonar::default]"
+ ]
+ end
+end
diff --git a/attributes/default.rb b/attributes/default.rb
index d802e6d..9f20245 100644
--- a/attributes/default.rb
+++ b/attributes/default.rb
@@ -1,8 +1,7 @@
# General settings
default['sonar']['dir'] = "/opt/sonar"
-default['sonar']['version'] = "2.11"
-default['sonar']['checksum'] = "9d05e25ca79c33d673004444d89c8770"
-default['sonar']['os_kernel'] = "linux-x86-32"
+default['sonar']['version'] = "2.14"
+default['sonar']['os_kernel'] = "linux-x86-64"
default['sonar']['mirror'] = "http://dist.sonar.codehaus.org"
# Web settings
diff --git a/chefignore b/chefignore
new file mode 100644
index 0000000..a6de142
--- /dev/null
+++ b/chefignore
@@ -0,0 +1,96 @@
+# Put files/directories that should be ignored in this file when uploading
+# or sharing to the community site.
+# Lines that start with '# ' are comments.
+
+# OS generated files #
+######################
+.DS_Store
+Icon?
+nohup.out
+ehthumbs.db
+Thumbs.db
+
+# SASS #
+########
+.sass-cache
+
+# EDITORS #
+###########
+\#*
+.#*
+*~
+*.sw[a-z]
+*.bak
+REVISION
+TAGS*
+tmtags
+*_flymake.*
+*_flymake
+*.tmproj
+.project
+.settings
+mkmf.log
+
+## COMPILED ##
+##############
+a.out
+*.o
+*.pyc
+*.so
+*.com
+*.class
+*.dll
+*.exe
+*/rdoc/
+
+# Testing #
+###########
+.watchr
+.rspec
+spec/*
+spec/fixtures/*
+test/*
+features/*
+Guardfile
+Procfile
+
+# SCM #
+#######
+.git
+*/.git
+.gitignore
+.gitmodules
+.gitconfig
+.gitattributes
+.svn
+*/.bzr/*
+*/.hg/*
+*/.svn/*
+
+# Berkshelf #
+#############
+Berksfile
+Berksfile.lock
+cookbooks/*
+tmp
+
+# Cookbooks #
+#############
+CONTRIBUTING
+CHANGELOG*
+
+# Strainer #
+############
+Colanderfile
+Strainerfile
+.colander
+.strainer
+
+# Vagrant #
+###########
+.vagrant
+Vagrantfile
+
+# Travis #
+##########
+.travis.yml
diff --git a/libraries/helper.rb b/libraries/helper.rb
new file mode 100644
index 0000000..58a8db7
--- /dev/null
+++ b/libraries/helper.rb
@@ -0,0 +1,56 @@
+#
+# Cookbook Name:: sonar
+# Library:: helper
+#
+# Copyright 2014, Steffen Gebert / TYPO3 Association
+#
+# Based on the jenkins cookbook:
+# Author:: Seth Chisamore
+# Copyright 2012, Opscode, 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.
+#
+
+require 'chef/mixin/shell_out'
+require 'chef/rest'
+
+# Helper library for testing Jenkins responses
+module SonarHelper
+ extend Chef::Mixin::ShellOut
+
+ def self.service_listening?(port)
+ netstat_command = 'netstat -lnt'
+ cmd = shell_out!(netstat_command)
+ Chef::Log.debug("`#{netstat_command}` returned: \n\n #{cmd.stdout}")
+ cmd.stdout.each_line.select do |l|
+ l.split[3] =~ /#{port}/
+ end.any?
+ end
+
+ def self.endpoint_responding?(url)
+ response = Chef::REST::RESTRequest.new(:GET, url, nil).call
+ if response.kind_of?(Net::HTTPSuccess) ||
+ response.kind_of?(Net::HTTPOK) ||
+ response.kind_of?(Net::HTTPRedirection) ||
+ response.kind_of?(Net::HTTPForbidden)
+ Chef::Log.debug("GET to #{url} successful")
+ return true
+ else
+ Chef::Log.debug("GET to #{url} returned #{response.code} / #{response.class}")
+ return false
+ end
+ rescue EOFError, Errno::ECONNREFUSED
+ Chef::Log.debug("GET to #{url} failed with connection refused")
+ return false
+ end
+end
diff --git a/metadata.rb b/metadata.rb
index 838ec8e..cbf9e6c 100644
--- a/metadata.rb
+++ b/metadata.rb
@@ -3,7 +3,7 @@
license "Apache 2.0"
description "Installs/Configures sonar"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
-version "0.0.4"
+version "0.0.6"
recipe "sonar", "Includes the recipe to download and configure a sonar server"
recipe "sonar::database_mysql", "Includes the recipe to install MySql-Server and create a database for sonar"
recipe "sonar::proxy_apache", "Includes the recipe to install Apache-Webserver and proxy modules to access sonar. Creates a host for sonar."
@@ -13,7 +13,7 @@
supports os
end
-%w{ java }.each do |cb|
+%w{ java ark database mysql nginx }.each do |cb|
depends cb
end
diff --git a/providers/plugin.rb b/providers/plugin.rb
new file mode 100644
index 0000000..b1f5714
--- /dev/null
+++ b/providers/plugin.rb
@@ -0,0 +1,92 @@
+#
+# Cookbook Name:: sonar
+# Provider:: plugin
+#
+# Copyright 2014, Steffen Gebert / TYPO3 Association
+#
+# Based on jenkins cookbook:
+# Copyright 2013, Opscode, 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.
+#
+
+def whyrun_supported?
+ true
+end
+
+
+action :install do
+ unless plugin_exists?
+ converge_by("Installing sonar plugin #{@new_resource.name} version #{@new_resource.version}") do
+ do_install_plugin
+ end
+ else
+ Chef::Log.debug "#{@new_resource.name} already exists"
+ end
+end
+
+action :remove do
+ if plugin_exists?
+ converge_by("remove #{@new_resource.name}") do
+ do_remove_plugin
+ end
+ else
+ Chef::Log.debug "#{@new_resource.name} doesn't exist"
+ end
+end
+
+private
+
+def plugins_dir
+ ::File.join(node['sonar']['dir'], 'extensions/plugins')
+end
+
+def plugin_file_name
+ @new_resource.name + '-' + @new_resource.version + '.jar'
+end
+
+def plugin_file_path
+ ::File.join(plugins_dir, plugin_file_name)
+end
+
+def plugin_exists?
+ ::File.exists?(plugin_file_path)
+end
+
+def do_install_plugin
+ plugin_url = @new_resource.url
+
+ remote_file plugin_file_path do
+ source plugin_url
+ backup false
+ action :create
+ notifies :restart, 'service[sonar]'
+ end
+
+end
+
+def do_remove_plugin
+ file plugin_file_path do
+ action :delete
+ backup false
+ notifies :restart, 'service[sonar]'
+ notifies :create, 'ruby_block[block_sonar_until_operational]'
+ end
+
+ directory plugin_dir_path do
+ action :delete
+ recursive true
+ notifies :restart, 'service[sonar]'
+ notifies :create, 'ruby_block[block_sonar_until_operational]'
+ end
+end
diff --git a/recipes/database_mysql.rb b/recipes/database_mysql.rb
index ba193ab..db92c54 100644
--- a/recipes/database_mysql.rb
+++ b/recipes/database_mysql.rb
@@ -1,17 +1,33 @@
-include_recipe "mysql::server"
+include_recipe "database::mysql"
-# Setup sonar user
-grants_path = "/opt/sonar/extras/database/mysql/create_database.sql"
+mysql_connection_info = {
+ :host => 'localhost',
+ :username => 'root',
+ :password => node['mysql']['server_root_password']
+}
-template grants_path do
- source "create_mysql_database.sql.erb"
- owner "root"
- group "root"
- mode "0600"
- action :create
- notifies :restart, resources(:service => "sonar")
+mysql_database "sonar" do
+ connection mysql_connection_info
+ collation "utf8_general_ci"
+ encoding "utf8"
end
-execute "mysql-install-application-privileges" do
- command "/usr/bin/mysql -u root #{node[:mysql][:server_root_password].empty? ? '' : '-p' }#{node[:mysql][:server_root_password]} < #{grants_path}"
+mysql_database_user "sonar" do
+ connection mysql_connection_info
+ password node['sonar']['jdbc_password']
+ action :create
+ notifies :grant, "mysql_database_user[sonar]"
end
+
+mysql_database_user "sonar-grant" do
+ connection mysql_connection_info
+ database_name "sonar"
+ action :nothing # should be notified with :grant
+ notifies :query, "mysql_database[flush privileges]"
+end
+
+mysql_database 'flush privileges' do
+ connection mysql_connection_info
+ sql 'flush privileges'
+ action :nothing # should be notified with #query
+end
\ No newline at end of file
diff --git a/recipes/default.rb b/recipes/default.rb
index 27f19a5..372b149 100644
--- a/recipes/default.rb
+++ b/recipes/default.rb
@@ -17,23 +17,15 @@
# limitations under the License.
#
+include_recipe "ark"
include_recipe "java"
-package "unzip"
-
-remote_file "/opt/sonar-#{node['sonar']['version']}.zip" do
- source "#{node['sonar']['mirror']}/sonar-#{node['sonar']['version']}.zip"
- mode "0644"
- checksum "#{node['sonar']['checksum']}"
- not_if { ::File.exists?("/opt/sonar-#{node['sonar']['version']}.zip") }
-end
-
-execute "unzip /opt/sonar-#{node['sonar']['version']}.zip -d /opt/" do
- not_if { ::File.directory?("/opt/sonar-#{node['sonar']['version']}/") }
-end
-
-link "/opt/sonar" do
- to "/opt/sonar-#{node['sonar']['version']}"
+ark "sonar" do
+ prefix_home "/opt"
+ prefix_root "/opt"
+ version node['sonar']['version']
+ url "#{node['sonar']['mirror']}/sonar-#{node['sonar']['version']}.zip"
+ action :install
end
service "sonar" do
@@ -53,7 +45,8 @@
variables(
:options => node['sonar']['options']
)
- notifies :restart, resources(:service => "sonar")
+ notifies :restart, 'service[sonar]', :immediately
+ notifies :create, 'ruby_block[block_sonar_until_operational]', :immediately
end
template "wrapper.conf" do
@@ -62,5 +55,29 @@
owner "root"
group "root"
mode 0644
- notifies :restart, resources(:service => "sonar")
+ notifies :restart, 'service[sonar]', :immediately
+ notifies :create, 'ruby_block[block_sonar_until_operational]', :immediately
+end
+
+ruby_block 'block_sonar_until_operational' do
+ block do
+ Chef::Log.info "Waiting until Sonar is listening on port #{node['sonar']['web_port']}"
+ until SonarHelper.service_listening?(node['sonar']['web_port'])
+ sleep 1
+ Chef::Log.debug('.')
+ end
+
+ Chef::Log.info 'Waiting until the Sonar API is responding'
+ test_url = URI.parse("http://localhost:#{node['sonar']['web_port']}/api/server")
+ until SonarHelper.endpoint_responding?(test_url)
+ sleep 1
+ Chef::Log.debug('.')
+ end
+ end
+ action :nothing
+end
+
+log 'ensure_sonar_is_running' do
+ notifies :start, 'service[sonar]', :immediately
+ notifies :create, 'ruby_block[block_sonar_until_operational]', :immediately
end
diff --git a/resources/plugin.rb b/resources/plugin.rb
new file mode 100644
index 0000000..17d7d93
--- /dev/null
+++ b/resources/plugin.rb
@@ -0,0 +1,27 @@
+#
+# Cookbook Name:: sonar
+# Resource:: plugin
+#
+# Copyright 2014, Steffen Gebert / TYPO3 Association
+#
+# Based on jenkins cookbook:
+# Copyright 2013, Opscode, 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.
+#
+
+actions :install, :remove
+default_action :install
+
+attribute :version, :kind_of => String
+attribute :url, :kind_of => String
\ No newline at end of file