├── .gitignore ├── .gitmodules ├── chef ├── roles │ ├── ceph-mon.rb │ ├── ceph-store.rb │ └── ceph-client.rb └── data_bags │ └── crowbar │ ├── bc-template-ceph.json │ └── bc-template-ceph.schema ├── README.rst ├── crowbar_framework └── app │ ├── views │ └── barclamp │ │ └── ceph │ │ ├── _edit_deployment.html.haml │ │ └── _edit_attributes.html.haml │ ├── controllers │ └── ceph_controller.rb │ └── models │ └── ceph_service.rb ├── bin ├── crowbar_ceph └── monitor-secret.py └── crowbar.yml /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "chef/cookbooks/ceph"] 2 | path = chef/cookbooks/ceph 3 | url = https://github.com/ceph/ceph-cookbooks.git 4 | -------------------------------------------------------------------------------- /chef/roles/ceph-mon.rb: -------------------------------------------------------------------------------- 1 | name "ceph-mon" 2 | description "Ceph monitor node" 3 | run_list( 4 | 'recipe[ceph::mon]' 5 | ) 6 | -------------------------------------------------------------------------------- /chef/roles/ceph-store.rb: -------------------------------------------------------------------------------- 1 | name "ceph-store" 2 | description "Ceph object store node" 3 | run_list( 4 | 'recipe[ceph::osd]' 5 | ) 6 | -------------------------------------------------------------------------------- /chef/roles/ceph-client.rb: -------------------------------------------------------------------------------- 1 | name "ceph-client" 2 | description "Ceph client tools and key" 3 | run_list( 4 | 'recipe[ceph::bootstrap_client]' 5 | ) 6 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ======================================== 2 | Barclamp for installing a Ceph cluster 3 | ======================================== 4 | 5 | Get Ceph cookbooks 6 | ================== 7 | 8 | To prepare the source tree after it has been git cloned: 9 | 10 | $ git submodule update --init 11 | 12 | -------------------------------------------------------------------------------- /crowbar_framework/app/views/barclamp/ceph/_edit_deployment.html.haml: -------------------------------------------------------------------------------- 1 | %p 2 | = render :partial => "barclamp/node_selector" 3 | 4 | :javascript 5 | $(document).ready(function(){ 6 | var constraints = { 7 | "ceph-mon": { "count": -1 }, 8 | "ceph-store": { "count": -1 }, 9 | "ceph-client": { "count": -1 } }; 10 | node_selector($('#drag_drop'), constraints); 11 | }); 12 | -------------------------------------------------------------------------------- /bin/crowbar_ceph: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Copyright 2011, Dell 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | 18 | require File.join(File.expand_path(File.dirname(__FILE__)), "barclamp_lib") 19 | @barclamp = "ceph" 20 | 21 | main 22 | -------------------------------------------------------------------------------- /crowbar_framework/app/controllers/ceph_controller.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2011, Dell 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | 16 | class CephController < BarclampController 17 | def initialize 18 | @service_object = CephService.new logger 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /bin/monitor-secret.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import base64 4 | import struct 5 | 6 | AES_128_KEY_TYPE = 1 7 | AES_128_KEY_LEN = 16 8 | 9 | def encode(created_nsec, entropy): 10 | """ 11 | Encodes a monitor secret and returns it. 12 | """ 13 | NANO = 1000000000 14 | secs, nsecs = divmod(created_nsec, NANO) 15 | assert len(entropy) == AES_128_KEY_LEN 16 | pbd = struct.pack( 17 | ' "hidden", :name => "proposal_attributes", :value => @proposal.raw_data['attributes'][@proposal.barclamp].to_json} 3 | %p 4 | %label{:for => "proposal_attributes"}= t('.attributes') 5 | = link_to t('raw'), proposal_barclamp_path(:id => @proposal.name, :controller => @proposal.barclamp, :dep_raw => @dep_raw, :attr_raw => true), :style => "float: right;" 6 | %div.container 7 | %p 8 | %label{ :for => :fsid }= t('.fsid') 9 | %input#fsid{:style => "width:280px;", :type => "text", :name => "fsid", :'data-default' => @proposal.raw_data['attributes'][@proposal.barclamp]["config"]["fsid"], :onchange => "update_value('config/fsid', 'fsid', 'string')"} 10 | %p 11 | %label{ :for => :monitor_secret }= t('.monitor_secret') 12 | %input#monitor_secret{:style => "width:360px;", :type => "text", :name => "monitor_secret", :'data-default' => @proposal.raw_data['attributes'][@proposal.barclamp]["monitor-secret"], :onchange => "update_value('monitor-secret', 'monitor_secret', 'string')"} 13 | 14 | 15 | -------------------------------------------------------------------------------- /crowbar.yml: -------------------------------------------------------------------------------- 1 | barclamp: 2 | name: ceph 3 | display: Ceph 4 | version: 0 5 | 6 | os_support: 7 | - ubuntu-10.10 8 | - ubuntu-11.04 9 | - ubuntu-11.10 10 | - ubuntu-12.04 11 | 12 | crowbar: 13 | layout: 1 14 | 15 | # TODO crowbar *and* chef cookbooks don't really need -dbg 16 | debs: 17 | ubuntu-10.10: 18 | repos: 19 | - deb http://ceph.com/debian/ maverick main 20 | ubuntu-11.04: 21 | repos: 22 | - deb http://ceph.com/debian/ natty main 23 | ubuntu-11.10: 24 | repos: 25 | - deb http://ceph.com/debian/ oneiric main 26 | ubuntu-12.04: 27 | repos: 28 | - deb http://www.ceph.com/debian-argonaut precise main 29 | pkgs: 30 | - ceph 31 | - ceph-dbg 32 | - ceph-common 33 | - ceph-common-dbg 34 | - libcephfs1 35 | - gdisk 36 | - libgoogle-perftools0 37 | 38 | locale_additions: 39 | en: 40 | nav: 41 | ceph: Ceph 42 | barclamp: 43 | ceph: 44 | edit_attributes: 45 | attributes: Attributes 46 | fsid: fsid 47 | monitor_secret: Monitor Secret Key 48 | mon_initial_members: mon_initial_members 49 | edit_deployment: 50 | deployment: Deployment 51 | -------------------------------------------------------------------------------- /crowbar_framework/app/models/ceph_service.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2011, Dell 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | 16 | class CephService < ServiceObject 17 | 18 | def initialize(thelogger) 19 | @bc_name = "ceph" 20 | @logger = thelogger 21 | end 22 | 23 | def create_proposal 24 | @logger.debug("Ceph create_proposal: entering") 25 | base = super 26 | 27 | fsid = `uuidgen` 28 | fsid.chomp! 29 | 30 | base["attributes"]["ceph"]["config"]["fsid"] = fsid 31 | 32 | #For testing use only. Will be implemeted into the cookbook. 33 | base["attributes"]["ceph"]["monitor-secret"] = `python /opt/dell/bin/monitor-secret.py` 34 | 35 | @logger.debug("Ceph create_proposal: exiting") 36 | base 37 | end 38 | 39 | def apply_role_pre_chef_call(old_role, role, all_nodes) 40 | @logger.debug("Ceph apply_role_pre_chef_call: entering #{all_nodes.inspect}") 41 | 42 | mon_nodes = role.override_attributes["ceph"]["elements"]["ceph-mon"] 43 | shortname = Array.new 44 | unless mon_nodes.nil? or mon_nodes.empty? 45 | mon_nodes.each do |n| 46 | node = NodeObject.find_node_by_name n 47 | shortname.push(n.split(".").first.concat(",")) 48 | @logger.debug("Ceph assign node[:ceph-mon] for #{n}") 49 | end 50 | @logger.debug("Shortname array: #{shortname.inspect}") 51 | role.default_attributes["ceph"]["config"]["mon_initial_members"] = shortname 52 | role.save 53 | end 54 | end 55 | 56 | end 57 | -------------------------------------------------------------------------------- /chef/data_bags/crowbar/bc-template-ceph.schema: -------------------------------------------------------------------------------- 1 | { 2 | "type": "map", 3 | "required": true, 4 | "mapping": { 5 | "id": { "type": "str", "required": true, "pattern": "/^bc-ceph-|^bc-template-ceph$/" }, 6 | "description": { "type": "str", "required": true }, 7 | "attributes": { 8 | "type": "map", 9 | "required": true, 10 | "mapping": { 11 | "ceph": { 12 | "type": "map", 13 | "required": true, 14 | "mapping": { 15 | "monitor-secret": { "type": "str" }, 16 | "config": { 17 | "type": "map", 18 | "required": true, 19 | "mapping": { 20 | "fsid": { "type": "str" }, 21 | "mon_initial_members": {"type": "str", "required": true } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | }, 28 | "deployment": { 29 | "type": "map", 30 | "required": true, 31 | "mapping": { 32 | "ceph": { 33 | "type": "map", 34 | "required": true, 35 | "mapping": { 36 | "crowbar-revision": { "type": "int", "required": true }, 37 | "crowbar-committing": { "type": "bool" }, 38 | "crowbar-queued": { "type": "bool" }, 39 | "element_states": { 40 | "type": "map", 41 | "mapping": { 42 | = : { 43 | "type": "seq", 44 | "required": true, 45 | "sequence": [ { "type": "str" } ] 46 | } 47 | } 48 | }, 49 | "elements": { 50 | "type": "map", 51 | "required": true, 52 | "mapping": { 53 | = : { 54 | "type": "seq", 55 | "required": true, 56 | "sequence": [ { "type": "str" } ] 57 | } 58 | } 59 | }, 60 | "element_order": { 61 | "type": "seq", 62 | "required": true, 63 | "sequence": [ { 64 | "type": "seq", 65 | "sequence": [ { "type": "str" } ] 66 | } ] 67 | }, 68 | "config": { 69 | "type": "map", 70 | "required": true, 71 | "mapping": { 72 | "environment": { "type": "str", "required": true }, 73 | "mode": { "type": "str", "required": true }, 74 | "transitions": { "type": "bool", "required": true }, 75 | "transition_list": { 76 | "type": "seq", 77 | "required": true, 78 | "sequence": [ { "type": "str" } ] 79 | } 80 | } 81 | } 82 | } 83 | } 84 | } 85 | } 86 | } 87 | } 88 | --------------------------------------------------------------------------------