|
1 | 1 | # @summary Create GlusterFS volumes, and maybe extend them |
2 | 2 | # |
| 3 | +# @param ensure |
| 4 | +# whether volume should be created ('present') or removed ('absent') |
3 | 5 | # @param stripe |
4 | 6 | # the stripe count to use for a striped volume |
5 | 7 | # @param replica |
|
43 | 45 | define gluster::volume ( |
44 | 46 | Array[String, 1] $bricks, |
45 | 47 |
|
| 48 | + Enum['present', 'absent'] $ensure = 'present', |
46 | 49 | Boolean $force = false, |
47 | 50 | Enum['tcp', 'rdma', 'tcp,rdma'] $transport = 'tcp', |
48 | 51 | Boolean $rebalance = true, |
|
111 | 114 | if $already_exists == false { |
112 | 115 | # this volume has not yet been created |
113 | 116 |
|
114 | | - exec { "gluster create volume ${title}": |
115 | | - command => "${::gluster_binary} volume create ${title} ${args}", |
116 | | - } |
| 117 | + # nothing to do if volume does not exist and it should be absent |
| 118 | + if $ensure == 'present' { |
| 119 | + exec { "gluster create volume ${title}": |
| 120 | + command => "${::gluster_binary} volume create ${title} ${args}", |
| 121 | + } |
| 122 | + |
| 123 | + # if we have volume options, activate them now |
| 124 | + # |
| 125 | + # Note: $options is an array, but create_resources requires |
| 126 | + # a hash of hashes. We do some contortions to get the |
| 127 | + # array into the hash of hashes that looks like: |
| 128 | + # |
| 129 | + # option.name: |
| 130 | + # value: value |
| 131 | + # |
| 132 | + # Note 2: we're using the $_options variable, which contains the |
| 133 | + # sorted list of options. |
| 134 | + if $_options { |
| 135 | + # first we need to prefix each array element with the volume name |
| 136 | + # so that we match the gluster::volume::option title format of |
| 137 | + # volume:option |
| 138 | + $vol_opts = prefix( $_options, "${title}:" ) |
| 139 | + # now we make some YAML, and then parse that to get a Puppet hash |
| 140 | + $yaml = join( regsubst( $vol_opts, ': ', ":\n value: ", 'G'), "\n") |
| 141 | + $hoh = parseyaml($yaml) |
117 | 142 |
|
118 | | - # if we have volume options, activate them now |
119 | | - # |
120 | | - # Note: $options is an array, but create_resources requires |
121 | | - # a hash of hashes. We do some contortions to get the |
122 | | - # array into the hash of hashes that looks like: |
123 | | - # |
124 | | - # option.name: |
125 | | - # value: value |
126 | | - # |
127 | | - # Note 2: we're using the $_options variable, which contains the |
128 | | - # sorted list of options. |
129 | | - if $_options { |
130 | | - # first we need to prefix each array element with the volume name |
131 | | - # so that we match the gluster::volume::option title format of |
132 | | - # volume:option |
133 | | - $vol_opts = prefix( $_options, "${title}:" ) |
134 | | - # now we make some YAML, and then parse that to get a Puppet hash |
135 | | - $yaml = join( regsubst( $vol_opts, ': ', ":\n value: ", 'G'), "\n") |
136 | | - $hoh = parseyaml($yaml) |
| 143 | + # safety check |
| 144 | + assert_type(Hash, $hoh) |
| 145 | + # we need to ensure that these are applied AFTER the volume is created |
| 146 | + # but BEFORE the volume is started |
| 147 | + $new_volume_defaults = { |
| 148 | + require => Exec["gluster create volume ${title}"], |
| 149 | + before => Exec["gluster start volume ${title}"], |
| 150 | + } |
137 | 151 |
|
138 | | - # safety check |
139 | | - assert_type(Hash, $hoh) |
140 | | - # we need to ensure that these are applied AFTER the volume is created |
141 | | - # but BEFORE the volume is started |
142 | | - $new_volume_defaults = { |
143 | | - require => Exec["gluster create volume ${title}"], |
144 | | - before => Exec["gluster start volume ${title}"], |
| 152 | + create_resources(::gluster::volume::option, $hoh, $new_volume_defaults) |
145 | 153 | } |
146 | 154 |
|
147 | | - create_resources(::gluster::volume::option, $hoh, $new_volume_defaults) |
148 | | - } |
149 | | - |
150 | | - # don't forget to start the new volume! |
151 | | - exec { "gluster start volume ${title}": |
152 | | - command => "${::gluster_binary} volume start ${title}", |
153 | | - require => Exec["gluster create volume ${title}"], |
| 155 | + # don't forget to start the new volume! |
| 156 | + exec { "gluster start volume ${title}": |
| 157 | + command => "${::gluster_binary} volume start ${title}", |
| 158 | + require => Exec["gluster create volume ${title}"], |
| 159 | + } |
154 | 160 | } |
155 | 161 |
|
156 | 162 | } elsif $already_exists { |
157 | 163 | # this volume exists |
158 | 164 |
|
159 | | - # our fact lists bricks comma-separated, but we need an array |
160 | | - $vol_bricks = split( getvar( "::gluster_volume_${title}_bricks" ), ',') |
161 | | - if $bricks != $vol_bricks { |
162 | | - # this resource's list of bricks does not match the existing |
163 | | - # volume's list of bricks |
164 | | - $new_bricks = difference($bricks, $vol_bricks) |
| 165 | + if $ensure == 'present' { |
| 166 | + # our fact lists bricks comma-separated, but we need an array |
| 167 | + $vol_bricks = split( getvar( "::gluster_volume_${title}_bricks" ), ',') |
| 168 | + if $bricks != $vol_bricks { |
| 169 | + # this resource's list of bricks does not match the existing |
| 170 | + # volume's list of bricks |
| 171 | + $new_bricks = difference($bricks, $vol_bricks) |
165 | 172 |
|
166 | | - $vol_count = count($vol_bricks) |
167 | | - if count($bricks) > $vol_count { |
168 | | - # adding bricks |
| 173 | + $vol_count = count($vol_bricks) |
| 174 | + if count($bricks) > $vol_count { |
| 175 | + # adding bricks |
169 | 176 |
|
170 | | - # if we have a stripe or replica volume, make sure the |
171 | | - # number of bricks to add is a factor of that value |
172 | | - if $stripe { |
173 | | - if ( count($new_bricks) % $stripe ) != 0 { |
174 | | - fail("Number of bricks to add is not a multiple of stripe count ${stripe}") |
| 177 | + # if we have a stripe or replica volume, make sure the |
| 178 | + # number of bricks to add is a factor of that value |
| 179 | + if $stripe { |
| 180 | + if ( count($new_bricks) % $stripe ) != 0 { |
| 181 | + fail("Number of bricks to add is not a multiple of stripe count ${stripe}") |
| 182 | + } |
| 183 | + $s = "stripe ${stripe}" |
| 184 | + } else { |
| 185 | + $s = '' |
175 | 186 | } |
176 | | - $s = "stripe ${stripe}" |
177 | | - } else { |
178 | | - $s = '' |
179 | | - } |
180 | 187 |
|
181 | | - if $replica { |
182 | | - if $arbiter and $arbiter != 0 { |
183 | | - $r = "replica ${replica} arbiter ${arbiter}" |
184 | | - } else { |
185 | | - if ( count($bricks) % $replica ) != 0 { |
186 | | - fail("Number of bricks to add is not a multiple of replica count ${replica}") |
| 188 | + if $replica { |
| 189 | + if $arbiter and $arbiter != 0 { |
| 190 | + $r = "replica ${replica} arbiter ${arbiter}" |
| 191 | + } else { |
| 192 | + if ( count($bricks) % $replica ) != 0 { |
| 193 | + fail("Number of bricks to add is not a multiple of replica count ${replica}") |
| 194 | + } |
| 195 | + $r = "replica ${replica}" |
187 | 196 | } |
188 | | - $r = "replica ${replica}" |
| 197 | + } else { |
| 198 | + $r = '' |
189 | 199 | } |
190 | | - } else { |
191 | | - $r = '' |
192 | | - } |
193 | 200 |
|
194 | | - $new_bricks_list = join($new_bricks, ' ') |
195 | | - exec { "gluster add bricks to ${title}": |
196 | | - command => "${::gluster_binary} volume add-brick ${title} ${s} ${r} ${new_bricks_list} ${_force}", |
197 | | - } |
| 201 | + $new_bricks_list = join($new_bricks, ' ') |
| 202 | + exec { "gluster add bricks to ${title}": |
| 203 | + command => "${::gluster_binary} volume add-brick ${title} ${s} ${r} ${new_bricks_list} ${_force}", |
| 204 | + } |
198 | 205 |
|
199 | | - if $rebalance { |
200 | | - exec { "gluster rebalance ${title}": |
201 | | - command => "${::gluster_binary} volume rebalance ${title} start", |
202 | | - require => Exec["gluster add bricks to ${title}"], |
| 206 | + if $rebalance { |
| 207 | + exec { "gluster rebalance ${title}": |
| 208 | + command => "${::gluster_binary} volume rebalance ${title} start", |
| 209 | + require => Exec["gluster add bricks to ${title}"], |
| 210 | + } |
203 | 211 | } |
204 | | - } |
205 | 212 |
|
206 | | - if $replica and $heal { |
207 | | - # there is a delay after which a brick is added before |
208 | | - # the self heal daemon comes back to life. |
209 | | - # as such, we sleep 5 here before starting the heal |
210 | | - exec { "gluster heal ${title}": |
211 | | - command => "/bin/sleep 5; ${::gluster_binary} volume heal ${title} full", |
212 | | - require => Exec["gluster add bricks to ${title}"], |
| 213 | + if $replica and $heal { |
| 214 | + # there is a delay after which a brick is added before |
| 215 | + # the self heal daemon comes back to life. |
| 216 | + # as such, we sleep 5 here before starting the heal |
| 217 | + exec { "gluster heal ${title}": |
| 218 | + command => "/bin/sleep 5; ${::gluster_binary} volume heal ${title} full", |
| 219 | + require => Exec["gluster add bricks to ${title}"], |
| 220 | + } |
213 | 221 | } |
214 | | - } |
215 | 222 |
|
216 | | - } elsif count($bricks) < $vol_count { |
217 | | - # removing bricks |
218 | | - notify{ 'removing bricks is not currently supported.': } |
219 | | - } else { |
220 | | - notify{ "unable to resolve brick changes for Gluster volume ${title}!\nDefined: ${_bricks}\nCurrent: ${vol_bricks}": } |
| 223 | + } elsif count($bricks) < $vol_count { |
| 224 | + # removing bricks |
| 225 | + notify{ 'removing bricks is not currently supported.': } |
| 226 | + } else { |
| 227 | + notify{ "unable to resolve brick changes for Gluster volume ${title}!\nDefined: ${_bricks}\nCurrent: ${vol_bricks}": } |
| 228 | + } |
221 | 229 | } |
222 | | - } |
223 | 230 |
|
224 | | - # did the options change? |
225 | | - $current_options_hash = pick(fact("gluster_volumes.${title}.options"), {}) |
226 | | - $_current = sort(join_keys_to_values($current_options_hash, ': ')) |
| 231 | + # did the options change? |
| 232 | + $current_options_hash = pick(fact("gluster_volumes.${title}.options"), {}) |
| 233 | + $_current = sort(join_keys_to_values($current_options_hash, ': ')) |
227 | 234 |
|
228 | | - if $_current != $_options { |
229 | | - # |
230 | | - # either of $current_options or $_options may be empty. |
231 | | - # we need to account for this situation |
232 | | - # |
233 | | - if is_array($_current) and is_array($_options) { |
234 | | - $to_remove = difference($_current, $_options) |
235 | | - $to_add = difference($_options, $_current) |
236 | | - } else { |
237 | | - if is_array($_current) { |
238 | | - # $_options is not an array, so remove all currently set options |
239 | | - $to_remove = $_current |
240 | | - } elsif is_array($_options) { |
241 | | - # $current_options is not an array, so add all our defined options |
242 | | - $to_add = $_options |
243 | | - } |
244 | | - } |
245 | | - if ! empty($to_remove) { |
246 | | - # we have some options active that are not defined here. Remove them |
| 235 | + if $_current != $_options { |
247 | 236 | # |
248 | | - # the syntax to remove ::gluster::volume::options is a little different |
249 | | - # so build up the hash correctly |
| 237 | + # either of $current_options or $_options may be empty. |
| 238 | + # we need to account for this situation |
250 | 239 | # |
251 | | - $remove_opts = prefix( $to_remove, "${title}:" ) |
252 | | - $remove_yaml = join( regsubst( $remove_opts, ': .+$', ":\n ensure: absent", 'G' ), "\n" ) |
253 | | - $remove = parseyaml($remove_yaml) |
254 | | - if $remove_options { |
255 | | - create_resources( ::gluster::volume::option, $remove ) |
| 240 | + if is_array($_current) and is_array($_options) { |
| 241 | + $to_remove = difference($_current, $_options) |
| 242 | + $to_add = difference($_options, $_current) |
256 | 243 | } else { |
257 | | - $remove_str = join( keys($remove), ', ' ) |
258 | | - notice("NOT REMOVING the following options for volume ${title}: ${remove_str}.") |
| 244 | + if is_array($_current) { |
| 245 | + # $_options is not an array, so remove all currently set options |
| 246 | + $to_remove = $_current |
| 247 | + } elsif is_array($_options) { |
| 248 | + # $current_options is not an array, so add all our defined options |
| 249 | + $to_add = $_options |
| 250 | + } |
| 251 | + } |
| 252 | + if ! empty($to_remove) { |
| 253 | + # we have some options active that are not defined here. Remove them |
| 254 | + # |
| 255 | + # the syntax to remove ::gluster::volume::options is a little different |
| 256 | + # so build up the hash correctly |
| 257 | + # |
| 258 | + $remove_opts = prefix( $to_remove, "${title}:" ) |
| 259 | + $remove_yaml = join( regsubst( $remove_opts, ': .+$', ":\n ensure: absent", 'G' ), "\n" ) |
| 260 | + $remove = parseyaml($remove_yaml) |
| 261 | + if $remove_options { |
| 262 | + create_resources( ::gluster::volume::option, $remove ) |
| 263 | + } else { |
| 264 | + $remove_str = join( keys($remove), ', ' ) |
| 265 | + notice("NOT REMOVING the following options for volume ${title}: ${remove_str}.") |
| 266 | + } |
| 267 | + } |
| 268 | + if ! empty($to_add) { |
| 269 | + # we have some options defined that are not active. Add them |
| 270 | + $add_opts = prefix( $to_add, "${title}:" ) |
| 271 | + $add_yaml = join( regsubst( $add_opts, ': ', ":\n value: ", 'G' ), "\n" ) |
| 272 | + $add = parseyaml($add_yaml) |
| 273 | + create_resources( ::gluster::volume::option, $add ) |
259 | 274 | } |
260 | 275 | } |
261 | | - if ! empty($to_add) { |
262 | | - # we have some options defined that are not active. Add them |
263 | | - $add_opts = prefix( $to_add, "${title}:" ) |
264 | | - $add_yaml = join( regsubst( $add_opts, ': ', ":\n value: ", 'G' ), "\n" ) |
265 | | - $add = parseyaml($add_yaml) |
266 | | - create_resources( ::gluster::volume::option, $add ) |
| 276 | + } else { |
| 277 | + # stop and remove volume |
| 278 | + exec { "gluster stop and remove ${title}": |
| 279 | + command => "${::gluster_binary} volume stop ${title} force && ${::gluster_binary} volume delete ${title}", |
267 | 280 | } |
268 | 281 | } |
269 | 282 | } |
|
0 commit comments