vagrant-clone 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/.rakeTasks +7 -0
  3. data/.idea/inspectionProfiles/Project_Default.xml +6 -0
  4. data/.idea/misc.xml +4 -0
  5. data/.idea/modules.xml +8 -0
  6. data/.idea/runConfigurations/clone.xml +21 -0
  7. data/.idea/runConfigurations/libvirt.xml +21 -0
  8. data/.idea/vagrant-clone.iml +114 -0
  9. data/.idea/vcs.xml +6 -0
  10. data/.idea/workspace.xml +948 -0
  11. data/Gemfile +9 -3
  12. data/Gemfile.lock +123 -37
  13. data/Rakefile +2 -1
  14. data/Vagrantfile +9 -0
  15. data/cookbooks/apt/CHANGELOG.md +321 -0
  16. data/cookbooks/apt/CONTRIBUTING.md +2 -0
  17. data/cookbooks/apt/MAINTAINERS.md +15 -0
  18. data/cookbooks/apt/README.md +250 -0
  19. data/cookbooks/apt/attributes/default.rb +57 -0
  20. data/cookbooks/apt/files/15update-stamp +1 -0
  21. data/cookbooks/apt/files/apt-proxy-v2.conf +50 -0
  22. data/cookbooks/apt/libraries/helpers.rb +49 -0
  23. data/cookbooks/apt/libraries/matchers.rb +16 -0
  24. data/cookbooks/apt/metadata.json +1 -0
  25. data/cookbooks/apt/recipes/cacher-client.rb +52 -0
  26. data/cookbooks/apt/recipes/cacher-ng.rb +39 -0
  27. data/cookbooks/apt/recipes/default.rb +93 -0
  28. data/cookbooks/apt/recipes/unattended-upgrades.rb +47 -0
  29. data/cookbooks/apt/resources/preference.rb +90 -0
  30. data/cookbooks/apt/templates/01proxy.erb +11 -0
  31. data/cookbooks/apt/templates/10dpkg-options.erb +8 -0
  32. data/cookbooks/apt/templates/10recommends.erb +3 -0
  33. data/cookbooks/apt/templates/20auto-upgrades.erb +5 -0
  34. data/cookbooks/apt/templates/50unattended-upgrades.erb +75 -0
  35. data/cookbooks/apt/templates/acng.conf.erb +275 -0
  36. data/cookbooks/apt/templates/unattended-upgrades.seed.erb +1 -0
  37. data/cookbooks/build-essential/.foodcritic +1 -0
  38. data/cookbooks/build-essential/CHANGELOG.md +257 -0
  39. data/cookbooks/build-essential/CONTRIBUTING.md +2 -0
  40. data/cookbooks/build-essential/MAINTAINERS.md +15 -0
  41. data/cookbooks/build-essential/README.md +134 -0
  42. data/cookbooks/build-essential/attributes/default.rb +21 -0
  43. data/cookbooks/build-essential/libraries/matchers.rb +9 -0
  44. data/cookbooks/build-essential/metadata.json +1 -0
  45. data/cookbooks/build-essential/recipes/_windows.rb +53 -0
  46. data/cookbooks/build-essential/recipes/default.rb +24 -0
  47. data/cookbooks/build-essential/resources/build_essential.rb +106 -0
  48. data/cookbooks/build-essential/resources/xcode_command_line_tools.rb +61 -0
  49. data/cookbooks/compat_resource/CHANGELOG.md +53 -0
  50. data/cookbooks/compat_resource/CONTRIBUTING.md +2 -0
  51. data/cookbooks/compat_resource/MAINTAINERS.md +16 -0
  52. data/cookbooks/compat_resource/README.md +60 -0
  53. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/constants.rb +47 -0
  54. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb +40 -0
  55. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb +73 -0
  56. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb +315 -0
  57. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/platform_introspection.rb +292 -0
  58. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb +37 -0
  59. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/universal.rb +70 -0
  60. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb +98 -0
  61. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb +74 -0
  62. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb +510 -0
  63. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/powershell_out.rb +117 -0
  64. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/properties.rb +328 -0
  65. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/property.rb +713 -0
  66. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_repository.rb +269 -0
  67. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_update.rb +105 -0
  68. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb +56 -0
  69. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/support/yum_repo.erb +132 -0
  70. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/systemd_unit.rb +253 -0
  71. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/yum_repository.rb +136 -0
  72. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider.rb +164 -0
  73. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb +114 -0
  74. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_repository.rb +65 -0
  75. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_update.rb +52 -0
  76. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/systemd_unit.rb +81 -0
  77. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/yum_repository.rb +97 -0
  78. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource.rb +214 -0
  79. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb +174 -0
  80. data/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef.rb +29 -0
  81. data/cookbooks/compat_resource/files/lib/chef_compat/mixin/properties.rb +8 -0
  82. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/exceptions.rb +10 -0
  83. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/log.rb +30 -0
  84. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/mixin/params_validate.rb +17 -0
  85. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/node.rb +9 -0
  86. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/property.rb +15 -0
  87. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/provider.rb +65 -0
  88. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe.rb +118 -0
  89. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe_hook.rb +20 -0
  90. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb +60 -0
  91. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource.rb +156 -0
  92. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_builder.rb +167 -0
  93. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rb +49 -0
  94. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_set.rb +49 -0
  95. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection.rb +103 -0
  96. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb +691 -0
  97. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb +153 -0
  98. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef.rb +33 -0
  99. data/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches.rb +41 -0
  100. data/cookbooks/compat_resource/files/lib/chef_compat/property.rb +6 -0
  101. data/cookbooks/compat_resource/files/lib/chef_compat/recipe.rb +8 -0
  102. data/cookbooks/compat_resource/files/lib/chef_compat/resource/lwrp_base.rb +44 -0
  103. data/cookbooks/compat_resource/files/lib/chef_compat/resource.rb +56 -0
  104. data/cookbooks/compat_resource/files/lib/chef_upstream_version.rb +3 -0
  105. data/cookbooks/compat_resource/files/lib/compat_resource.rb +35 -0
  106. data/cookbooks/compat_resource/libraries/autoload.rb +31 -0
  107. data/cookbooks/compat_resource/metadata.json +1 -0
  108. data/cookbooks/inifile_chef_gem/CHANGELOG.md +11 -0
  109. data/cookbooks/inifile_chef_gem/README.md +46 -0
  110. data/cookbooks/inifile_chef_gem/metadata.json +51 -0
  111. data/cookbooks/inifile_chef_gem/metadata.rb +11 -0
  112. data/cookbooks/inifile_chef_gem/resources/default.rb +28 -0
  113. data/cookbooks/mariadb/CHANGELOG.md +332 -0
  114. data/cookbooks/mariadb/README.md +225 -0
  115. data/cookbooks/mariadb/attributes/default.rb +199 -0
  116. data/cookbooks/mariadb/libraries/mariadb_conn_helper.rb +53 -0
  117. data/cookbooks/mariadb/libraries/mariadb_helper.rb +216 -0
  118. data/cookbooks/mariadb/libraries/matchers.rb +21 -0
  119. data/cookbooks/mariadb/metadata.json +1 -0
  120. data/cookbooks/mariadb/providers/configuration.rb +39 -0
  121. data/cookbooks/mariadb/recipes/_audit_plugin.rb +63 -0
  122. data/cookbooks/mariadb/recipes/_debian_galera.rb +62 -0
  123. data/cookbooks/mariadb/recipes/_debian_server.rb +78 -0
  124. data/cookbooks/mariadb/recipes/_mariadb_repository.rb +29 -0
  125. data/cookbooks/mariadb/recipes/_redhat_client.rb +27 -0
  126. data/cookbooks/mariadb/recipes/_redhat_galera.rb +55 -0
  127. data/cookbooks/mariadb/recipes/_redhat_server.rb +58 -0
  128. data/cookbooks/mariadb/recipes/client.rb +47 -0
  129. data/cookbooks/mariadb/recipes/config.rb +115 -0
  130. data/cookbooks/mariadb/recipes/default.rb +46 -0
  131. data/cookbooks/mariadb/recipes/devel.rb +41 -0
  132. data/cookbooks/mariadb/recipes/galera.rb +324 -0
  133. data/cookbooks/mariadb/recipes/plugins.rb +3 -0
  134. data/cookbooks/mariadb/recipes/repository.rb +45 -0
  135. data/cookbooks/mariadb/recipes/server.rb +157 -0
  136. data/cookbooks/mariadb/resources/configuration.rb +13 -0
  137. data/cookbooks/mariadb/resources/mysql2_gem.rb +25 -0
  138. data/cookbooks/mariadb/resources/replication.rb +192 -0
  139. data/cookbooks/mariadb/templates/default/conf.d.generic.erb +19 -0
  140. data/cookbooks/mariadb/templates/default/debian.cnf.erb +12 -0
  141. data/cookbooks/mariadb/templates/default/mariadb-server.seed.erb +13 -0
  142. data/cookbooks/mariadb/templates/default/mariadb_grants.erb +42 -0
  143. data/cookbooks/mariadb/templates/default/my.cnf.erb +210 -0
  144. data/cookbooks/mariadb/templates/default/root.cnf.erb +5 -0
  145. data/cookbooks/mingw/.foodcritic +1 -0
  146. data/cookbooks/mingw/CHANGELOG.md +50 -0
  147. data/cookbooks/mingw/CONTRIBUTING.md +2 -0
  148. data/cookbooks/mingw/MAINTAINERS.md +14 -0
  149. data/cookbooks/mingw/README.md +133 -0
  150. data/cookbooks/mingw/files/default/bash.bat +17 -0
  151. data/cookbooks/mingw/files/default/custom-upgrade.sh +23 -0
  152. data/cookbooks/mingw/files/default/custom_prefix.sh +13 -0
  153. data/cookbooks/mingw/files/default/pthread.h +719 -0
  154. data/cookbooks/mingw/files/default/time.h +297 -0
  155. data/cookbooks/mingw/libraries/_helper.rb +38 -0
  156. data/cookbooks/mingw/metadata.json +1 -0
  157. data/cookbooks/mingw/recipes/default.rb +19 -0
  158. data/cookbooks/mingw/resources/get.rb +56 -0
  159. data/cookbooks/mingw/resources/msys2_package.rb +139 -0
  160. data/cookbooks/mingw/resources/tdm_gcc.rb +114 -0
  161. data/cookbooks/ohai/.foodcritic +2 -0
  162. data/cookbooks/ohai/CHANGELOG.md +166 -0
  163. data/cookbooks/ohai/CONTRIBUTING.md +2 -0
  164. data/cookbooks/ohai/MAINTAINERS.md +15 -0
  165. data/cookbooks/ohai/README.md +134 -0
  166. data/cookbooks/ohai/libraries/matchers.rb +41 -0
  167. data/cookbooks/ohai/metadata.json +1 -0
  168. data/cookbooks/ohai/recipes/default.rb +20 -0
  169. data/cookbooks/ohai/resources/hint.rb +55 -0
  170. data/cookbooks/ohai/resources/plugin.rb +117 -0
  171. data/cookbooks/selinux_policy/.gitignore +51 -0
  172. data/cookbooks/selinux_policy/.kitchen.yml +25 -0
  173. data/cookbooks/selinux_policy/.rubocop.yml +2 -0
  174. data/cookbooks/selinux_policy/.travis.yml +26 -0
  175. data/cookbooks/selinux_policy/Berksfile +8 -0
  176. data/cookbooks/selinux_policy/CHANGELOG.md +155 -0
  177. data/cookbooks/selinux_policy/LICENSE +13 -0
  178. data/cookbooks/selinux_policy/README.md +217 -0
  179. data/cookbooks/selinux_policy/Rakefile +68 -0
  180. data/cookbooks/selinux_policy/TESTING.md +2 -0
  181. data/cookbooks/selinux_policy/Thorfile +12 -0
  182. data/cookbooks/selinux_policy/attributes/default.rb +5 -0
  183. data/cookbooks/selinux_policy/chefignore +102 -0
  184. data/cookbooks/selinux_policy/libraries/helper-disabled.rb +29 -0
  185. data/cookbooks/selinux_policy/libraries/matchers.rb +57 -0
  186. data/cookbooks/selinux_policy/metadata.json +58 -0
  187. data/cookbooks/selinux_policy/metadata.rb +20 -0
  188. data/cookbooks/selinux_policy/providers/boolean.rb +28 -0
  189. data/cookbooks/selinux_policy/providers/fcontext.rb +78 -0
  190. data/cookbooks/selinux_policy/providers/module.rb +81 -0
  191. data/cookbooks/selinux_policy/providers/permissive.rb +26 -0
  192. data/cookbooks/selinux_policy/providers/port.rb +58 -0
  193. data/cookbooks/selinux_policy/recipes/default.rb +9 -0
  194. data/cookbooks/selinux_policy/recipes/install.rb +32 -0
  195. data/cookbooks/selinux_policy/resources/boolean.rb +8 -0
  196. data/cookbooks/selinux_policy/resources/fcontext.rb +8 -0
  197. data/cookbooks/selinux_policy/resources/module.rb +21 -0
  198. data/cookbooks/selinux_policy/resources/permissive.rb +6 -0
  199. data/cookbooks/selinux_policy/resources/port.rb +9 -0
  200. data/cookbooks/seven_zip/CHANGELOG.md +30 -0
  201. data/cookbooks/seven_zip/README.md +108 -0
  202. data/cookbooks/seven_zip/attributes/default.rb +31 -0
  203. data/cookbooks/seven_zip/libraries/matchers.rb +33 -0
  204. data/cookbooks/seven_zip/metadata.json +1 -0
  205. data/cookbooks/seven_zip/providers/archive.rb +68 -0
  206. data/cookbooks/seven_zip/recipes/default.rb +41 -0
  207. data/cookbooks/seven_zip/resources/archive.rb +29 -0
  208. data/cookbooks/windows/.foodcritic +2 -0
  209. data/cookbooks/windows/CHANGELOG.md +528 -0
  210. data/cookbooks/windows/CONTRIBUTING.md +2 -0
  211. data/cookbooks/windows/MAINTAINERS.md +21 -0
  212. data/cookbooks/windows/README.md +803 -0
  213. data/cookbooks/windows/attributes/default.rb +21 -0
  214. data/cookbooks/windows/files/dism_features.rb +45 -0
  215. data/cookbooks/windows/libraries/matchers.rb +586 -0
  216. data/cookbooks/windows/libraries/powershell_helper.rb +53 -0
  217. data/cookbooks/windows/libraries/registry_helper.rb +356 -0
  218. data/cookbooks/windows/libraries/version.rb +207 -0
  219. data/cookbooks/windows/libraries/version_helper.rb +79 -0
  220. data/cookbooks/windows/libraries/windows_helper.rb +174 -0
  221. data/cookbooks/windows/libraries/windows_privileged.rb +103 -0
  222. data/cookbooks/windows/libraries/wmi_helper.rb +32 -0
  223. data/cookbooks/windows/metadata.json +1 -0
  224. data/cookbooks/windows/recipes/default.rb +21 -0
  225. data/cookbooks/windows/resources/auto_run.rb +46 -0
  226. data/cookbooks/windows/resources/certificate.rb +166 -0
  227. data/cookbooks/windows/resources/certificate_binding.rb +128 -0
  228. data/cookbooks/windows/resources/feature.rb +82 -0
  229. data/cookbooks/windows/resources/feature_dism.rb +108 -0
  230. data/cookbooks/windows/resources/feature_powershell.rb +70 -0
  231. data/cookbooks/windows/resources/feature_servermanagercmd.rb +76 -0
  232. data/cookbooks/windows/resources/font.rb +80 -0
  233. data/cookbooks/windows/resources/http_acl.rb +110 -0
  234. data/cookbooks/windows/resources/pagefile.rb +152 -0
  235. data/cookbooks/windows/resources/path.rb +54 -0
  236. data/cookbooks/windows/resources/printer.rb +103 -0
  237. data/cookbooks/windows/resources/printer_port.rb +101 -0
  238. data/cookbooks/windows/resources/share.rb +291 -0
  239. data/cookbooks/windows/resources/shortcut.rb +53 -0
  240. data/cookbooks/windows/resources/task.rb +384 -0
  241. data/cookbooks/windows/resources/zipfile.rb +125 -0
  242. data/cookbooks/yum/.foodcritic +1 -0
  243. data/cookbooks/yum/CHANGELOG.md +351 -0
  244. data/cookbooks/yum/CONTRIBUTING.md +2 -0
  245. data/cookbooks/yum/MAINTAINERS.md +16 -0
  246. data/cookbooks/yum/README.md +125 -0
  247. data/cookbooks/yum/attributes/main.rb +103 -0
  248. data/cookbooks/yum/libraries/matchers.rb +9 -0
  249. data/cookbooks/yum/metadata.json +1 -0
  250. data/cookbooks/yum/recipes/default.rb +26 -0
  251. data/cookbooks/yum/recipes/dnf_yum_compat.rb +29 -0
  252. data/cookbooks/yum/resources/globalconfig.rb +119 -0
  253. data/cookbooks/yum/templates/.DS_Store +0 -0
  254. data/cookbooks/yum/templates/main.erb +276 -0
  255. data/cookbooks/yum-epel/CHANGELOG.md +138 -0
  256. data/cookbooks/yum-epel/CONTRIBUTING.md +2 -0
  257. data/cookbooks/yum-epel/MAINTAINERS.md +19 -0
  258. data/cookbooks/yum-epel/README.md +172 -0
  259. data/cookbooks/yum-epel/attributes/default.rb +8 -0
  260. data/cookbooks/yum-epel/attributes/epel-debuginfo.rb +15 -0
  261. data/cookbooks/yum-epel/attributes/epel-source.rb +15 -0
  262. data/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb +15 -0
  263. data/cookbooks/yum-epel/attributes/epel-testing-source.rb +15 -0
  264. data/cookbooks/yum-epel/attributes/epel-testing.rb +15 -0
  265. data/cookbooks/yum-epel/attributes/epel.rb +21 -0
  266. data/cookbooks/yum-epel/metadata.json +1 -0
  267. data/cookbooks/yum-epel/recipes/default.rb +27 -0
  268. data/cookbooks/yum-scl/.kitchen.dokken.yml +24 -0
  269. data/cookbooks/yum-scl/.kitchen.yml +24 -0
  270. data/cookbooks/yum-scl/.rubocop.yml +6 -0
  271. data/cookbooks/yum-scl/.travis.yml +28 -0
  272. data/cookbooks/yum-scl/Berksfile +3 -0
  273. data/cookbooks/yum-scl/Berksfile.lock +25 -0
  274. data/cookbooks/yum-scl/CHANGELOG.md +11 -0
  275. data/cookbooks/yum-scl/Gemfile +46 -0
  276. data/cookbooks/yum-scl/README.md +76 -0
  277. data/cookbooks/yum-scl/attributes/centos.rb +83 -0
  278. data/cookbooks/yum-scl/attributes/default.rb +15 -0
  279. data/cookbooks/yum-scl/attributes/scientific.rb +1 -0
  280. data/cookbooks/yum-scl/files/default/RPM-GPG-KEY-CentOS-SIG-SCLo +20 -0
  281. data/cookbooks/yum-scl/libraries/yum_scl_helper.rb +33 -0
  282. data/cookbooks/yum-scl/metadata.json +42 -0
  283. data/cookbooks/yum-scl/metadata.rb +12 -0
  284. data/cookbooks/yum-scl/recipes/chef_install.rb +52 -0
  285. data/cookbooks/yum-scl/recipes/default.rb +17 -0
  286. data/cookbooks/yum-scl/recipes/native_install.rb +35 -0
  287. data/lib/vagrant-clone/command/clone.rb +66 -61
  288. data/lib/vagrant-clone/errors.rb +61 -0
  289. data/lib/vagrant-clone/util/clone_manager_base.rb +69 -0
  290. data/lib/vagrant-clone/util/clone_managers/docker.rb +31 -0
  291. data/lib/vagrant-clone/util/clone_managers/libvirt.rb +254 -0
  292. data/lib/vagrant-clone/util/vagrantfile_managers/docker.rb +154 -0
  293. data/lib/vagrant-clone/util/vagrantfile_managers/libvirt.rb +159 -0
  294. data/lib/vagrant-clone/version.rb +2 -2
  295. data/lib/vagrant-clone.rb +6 -6
  296. data/libvirt.txt +7 -0
  297. data/performance_testing.rb +165 -0
  298. data/results.txt +45 -0
  299. data/scripts/create_box.sh +134 -0
  300. data/test.rb +92 -0
  301. data/tools/create_box.sh +130 -0
  302. data/vagrant-clone.gemspec +7 -7
  303. metadata +296 -5
  304. data/lib/vagrant-clone/command/errors.rb +0 -16
  305. data/lib/vagrant-clone/command/provider/docker.rb +0 -13
  306. data/lib/vagrant-clone/utils/vagrantfile_manager.rb +0 -47
@@ -0,0 +1,324 @@
1
+ #
2
+ # Cookbook Name:: mariadb
3
+ # Recipe:: galera
4
+ #
5
+ # Copyright 2014, blablacar.com
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ # rubocop:disable Lint/EmptyWhen
21
+
22
+ if Chef::Config[:solo]
23
+ Chef::Log.warn('This recipe uses search. Chef Solo does not support search.')
24
+ else
25
+ if node['mariadb']['server_root_password'].nil?
26
+ exist_data_bag_mariadb_root = search(:mariadb, 'id:user_root').first
27
+ unless exist_data_bag_mariadb_root.nil?
28
+ data_bag_mariadb_root = data_bag_item('mariadb', 'user_root')
29
+ node.override['mariadb']['server_root_password'] = data_bag_mariadb_root['password']
30
+ end
31
+ end
32
+
33
+ if node['mariadb']['debian']['password'].nil?
34
+ exist_data_bag_mariadb_debian = search(:mariadb, 'id:user_debian').first
35
+ unless exist_data_bag_mariadb_debian.nil?
36
+ data_bag_mariadb_debian = data_bag_item('mariadb', 'user_debian')
37
+ node.override['mariadb']['debian']['password'] = data_bag_mariadb_debian['password']
38
+ end
39
+ end
40
+
41
+ if node['mariadb']['galera']['wsrep_sst_auth'].nil?
42
+ exist_data_bag_mariadb_sstuser = search(:mariadb, 'id:user_sstuser').first
43
+ unless exist_data_bag_mariadb_sstuser.nil?
44
+ data_bag_mariadb_sstuser = data_bag_item('mariadb', 'user_sstuser')
45
+ node.override['mariadb']['galera']['wsrep_sst_auth'] = data_bag_mariadb_sstuser['user_password']
46
+ end
47
+ end
48
+ end
49
+
50
+ case node['mariadb']['install']['type']
51
+ when 'package'
52
+ # include MariaDB repositories
53
+ include_recipe "#{cookbook_name}::repository"
54
+
55
+ case node['platform']
56
+ when 'debian', 'ubuntu'
57
+ include_recipe "#{cookbook_name}::_debian_galera"
58
+ when 'redhat', 'centos', 'scientific', 'amazon'
59
+ include_recipe "#{cookbook_name}::_redhat_galera"
60
+ end
61
+ when 'from_source'
62
+ # To be filled as soon as possible
63
+ end
64
+
65
+ if node['mariadb']['install']['extra_packages']
66
+ if node['mariadb']['galera']['wsrep_sst_method'] == 'rsync'
67
+ package 'rsync' do
68
+ action :install
69
+ end
70
+ elsif node['mariadb']['galera']['wsrep_sst_method'] =~ /^xtrabackup(-v2)?/
71
+ %w(percona-xtrabackup socat pv).each do |pkg|
72
+ package pkg do
73
+ action :install
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ include_recipe "#{cookbook_name}::config"
80
+
81
+ if node['mariadb']['galera']['gcomm_address'].nil?
82
+ galera_cluster_nodes = []
83
+ if !node['mariadb'].attribute?('rspec') && Chef::Config[:solo]
84
+ if node['mariadb']['galera']['cluster_nodes'].empty?
85
+ Chef::Log.warn('By default this recipe uses search (unsupported by Chef Solo).' \
86
+ ' Nodes may manually be configured as attributes.')
87
+ else
88
+ galera_cluster_nodes = node['mariadb']['galera']['cluster_nodes']
89
+ end
90
+ else
91
+ if node['mariadb']['galera']['cluster_search_query'].empty?
92
+ galera_cluster_nodes = search(
93
+ :node, \
94
+ "mariadb_galera_cluster_name:#{node['mariadb']['galera']['cluster_name']}"
95
+ )
96
+ else
97
+ galera_cluster_nodes = search 'node', node['mariadb']['galera']['cluster_search_query']
98
+ log 'Chef search results' do
99
+ message "Searching for \"#{node['mariadb']['galera']['cluster_search_query']}\" \
100
+ resulted in \"#{galera_cluster_nodes}\" ..."
101
+ level :debug
102
+ end
103
+ end
104
+ # Sort Nodes by fqdn
105
+ galera_cluster_nodes.sort! { |x, y| x[:fqdn] <=> y[:fqdn] }
106
+ end
107
+
108
+ first = true
109
+ gcomm = 'gcomm://'
110
+ galera_cluster_nodes.each do |lnode|
111
+ next unless lnode.name != node.name
112
+ gcomm += ',' unless first
113
+ gcomm += if String(lnode['mariadb']['galera']['wsrep_node_port']).empty?
114
+ lnode['fqdn']
115
+ else
116
+ "#{lnode['fqdn']}:#{lnode['mariadb']['galera']['wsrep_node_port']}"
117
+ end
118
+ first = false
119
+ end
120
+ else
121
+ gcomm = node['mariadb']['galera']['gcomm_address']
122
+ end
123
+
124
+ include_recipe 'selinux_policy::install' if node['platform_family'] == 'rhel'
125
+
126
+ extend Chef::Util::Selinux
127
+ selinux_enabled = selinux_enabled?
128
+
129
+ selinux_policy_port node['mariadb']['galera']['wsrep_node_port'] do
130
+ protocol 'tcp'
131
+ secontext 'tram_port_t'
132
+ only_if { selinux_enabled }
133
+ not_if { String(node['mariadb']['galera']['wsrep_node_port']).empty? }
134
+ action :add
135
+ end
136
+
137
+ galera_options = {}
138
+
139
+ # Mandatory settings
140
+ galera_options['query_cache_size'] = '0'
141
+ galera_options['binlog_format'] = 'ROW'
142
+ galera_options['default_storage_engine'] = 'InnoDB'
143
+ galera_options['innodb_autoinc_lock_mode'] = '2'
144
+ galera_options['innodb_doublewrite'] = '1'
145
+ galera_options['server_id'] = \
146
+ node['mariadb']['galera']['server_id']
147
+ # Tuning paramaters
148
+ galera_options['innodb_flush_log_at_trx_commit'] = \
149
+ node['mariadb']['galera']['innodb_flush_log_at_trx_commit']
150
+ #
151
+ if node['mariadb']['install']['version'].to_f >= 10.1
152
+ galera_options['wsrep_on'] = 'ON'
153
+ end
154
+ unless node['mariadb']['galera']['wsrep_provider_options'].empty?
155
+ first = true
156
+ wsrep_prov_opt = '"'
157
+ node['mariadb']['galera']['wsrep_provider_options'].each do |opt, val|
158
+ wsrep_prov_opt += ';' unless first
159
+ wsrep_prov_opt += opt + '=' + val
160
+ first = false
161
+ end
162
+ wsrep_prov_opt += '"'
163
+ galera_options['wsrep_provider_options'] = wsrep_prov_opt
164
+ end
165
+ galera_options['wsrep_cluster_address'] = gcomm
166
+ galera_options['wsrep_cluster_name'] = \
167
+ node['mariadb']['galera']['cluster_name']
168
+ galera_options['wsrep_sst_method'] = \
169
+ node['mariadb']['galera']['wsrep_sst_method']
170
+ if node['mariadb']['galera'].attribute?('wsrep_sst_auth')
171
+ galera_options['wsrep_sst_auth'] = \
172
+ node['mariadb']['galera']['wsrep_sst_auth']
173
+ end
174
+ galera_options['wsrep_provider'] = \
175
+ node['mariadb']['galera']['wsrep_provider']
176
+ galera_options['wsrep_slave_threads'] = if node['mariadb']['galera'].attribute?('wsrep_slave_threads')
177
+ node['mariadb']['galera']['wsrep_slave_threads']
178
+ else
179
+ node['cpu']['total'] * 4
180
+ end
181
+
182
+ ipaddress = ''
183
+ iface = if node['mariadb']['galera']['wsrep_node_address_interface'].empty?
184
+ node['network']['interfaces'].reject { |_k, v| v['flags'].include?('LOOPBACK') }.keys.first
185
+ else
186
+ node['mariadb']['galera']['wsrep_node_address_interface']
187
+ end
188
+ node['network']['interfaces'][iface]['addresses'].each do |ip, params|
189
+ params['family'] == 'inet' && ipaddress = ip
190
+ end
191
+ galera_options['wsrep_node_address'] = unless ipaddress.empty?
192
+ if String(node['mariadb']['galera']['wsrep_node_port']).empty?
193
+ ipaddress
194
+ else
195
+ "#{ipaddress}:#{node['mariadb']['galera']['wsrep_node_port']}"
196
+ end
197
+ end
198
+
199
+ ipaddress_inc = ''
200
+ unless node['mariadb']['galera']['wsrep_node_incoming_address_interface'].empty?
201
+ iface_enc = node['mariadb']['galera']['wsrep_node_incoming_address_interface']
202
+ node['network']['interfaces'][iface_enc]['addresses'].each do |ip, params|
203
+ params['family'] == 'inet' && ipaddress_inc = ip
204
+ end
205
+ galera_options['wsrep_node_incoming_address'] = ipaddress_inc unless ipaddress_inc.empty?
206
+ end
207
+
208
+ galera_options['wsrep_slave_threads'] = node['cpu']['total'] * 4
209
+ node['mariadb']['galera']['options'].each do |key, value|
210
+ galera_options[key] = value
211
+ end
212
+
213
+ mariadb_configuration '90-galera' do
214
+ section 'mysqld'
215
+ option galera_options
216
+ action :add
217
+ sensitive true
218
+ end
219
+
220
+ #
221
+ # Under debian system we have to change the debian-sys-maint default password.
222
+ # This password is the same for the overall cluster.
223
+ #
224
+ if platform?('debian', 'ubuntu')
225
+ template '/etc/mysql/debian.cnf' do
226
+ sensitive true
227
+ source 'debian.cnf.erb'
228
+ owner 'root'
229
+ group 'root'
230
+ mode '0600'
231
+ end
232
+
233
+ grants_command = 'mysql -r -B -N -u root '
234
+
235
+ if node['mariadb']['server_root_password'].is_a?(String)
236
+ grants_command += '--password=\'' + \
237
+ node['mariadb']['server_root_password'] + '\' '
238
+ end
239
+
240
+ grants_command += '-e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ' \
241
+ 'DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, ' \
242
+ 'INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY ' \
243
+ 'TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, ' \
244
+ 'REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ' \
245
+ 'ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON ' \
246
+ ' *.* TO \'' + node['mariadb']['debian']['user'] + \
247
+ '\'@\'' + node['mariadb']['debian']['host'] + '\' ' \
248
+ 'IDENTIFIED BY \'' + \
249
+ node['mariadb']['debian']['password'] + '\' WITH GRANT ' \
250
+ 'OPTION"'
251
+
252
+ execute 'correct-debian-grants' do
253
+ command grants_command
254
+ action :run
255
+ only_if do
256
+ cmd = Mixlib::ShellOut.new('/usr/bin/mysql --user="' + \
257
+ node['mariadb']['debian']['user'] + \
258
+ '" --password="' + node['mariadb']['debian']['password'] + \
259
+ '" -r -B -N -e "SELECT 1"')
260
+ cmd.run_command
261
+ cmd.error?
262
+ end
263
+ ignore_failure true
264
+ sensitive true
265
+ end
266
+ end
267
+
268
+ #
269
+ # Galera SST method xtrabackup will need a seperated mysql sstuser as root
270
+ # should not be used.
271
+ #
272
+ if node['mariadb']['galera']['wsrep_sst_method'] =~ /^xtrabackup(-v2)?/
273
+
274
+ sstuser, sstpassword = node['mariadb']['galera']['wsrep_sst_auth'].split(/:/)
275
+
276
+ sstuser_cmd = 'mysql -r -B -N -u root '
277
+
278
+ if node['mariadb']['server_root_password'].is_a?(String)
279
+ sstuser_cmd += '--password=\'' + \
280
+ node['mariadb']['server_root_password'] + '\' '
281
+ end
282
+
283
+ sstuser_cmd += '-e "GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ' \
284
+ ' ON *.* TO \'' + sstuser + \
285
+ '\'@\'localhost\' ' \
286
+ 'IDENTIFIED BY \'' + sstpassword + '\'"'
287
+
288
+ execute 'sstuser-grants' do
289
+ command sstuser_cmd
290
+ action :run
291
+ only_if do
292
+ cmd = Mixlib::ShellOut.new('/usr/bin/mysql --user="' + \
293
+ sstuser + \
294
+ '" --password="' + sstpassword + \
295
+ '" -r -B -N -e "SELECT 1"')
296
+ cmd.run_command
297
+ cmd.error?
298
+ end
299
+ ignore_failure true
300
+ sensitive true
301
+ end
302
+ end
303
+
304
+ #
305
+ # NOTE: You cannot use the following code to restart Mariadb when in Galera mode.
306
+ # When your SST is longer than a chef run...
307
+ # ==> chef-client try to restart the service each time it run <==
308
+ #
309
+
310
+ # restart the service if needed
311
+ # workaround idea from https://github.com/stissot
312
+ #
313
+ # Chef::Resource::Execute.send(:include, MariaDB::Helper)
314
+ # execute 'mariadb-service-restart-needed' do
315
+ # command 'true'
316
+ # only_if do
317
+ # mariadb_service_restart_required?(
318
+ # node['mariadb']['mysqld']['bind-address'],
319
+ # node['mariadb']['mysqld']['port'],
320
+ # node['mariadb']['mysqld']['socket']
321
+ # )
322
+ # end
323
+ # notifies :restart, 'service[mysql]', :immediately
324
+ # end
@@ -0,0 +1,3 @@
1
+ node['mariadb']['plugins'].each do |plugin, enable|
2
+ include_recipe "#{cookbook_name}::_" + plugin + '_plugin' if enable
3
+ end
@@ -0,0 +1,45 @@
1
+ case node['platform']
2
+ when 'debian', 'ubuntu'
3
+ install_method = 'apt'
4
+ when 'redhat', 'centos', 'scientific', 'amazon'
5
+ install_method = 'yum'
6
+ end
7
+
8
+ if node['mariadb']['use_default_repository']
9
+ case install_method
10
+ when 'apt'
11
+ include_recipe 'apt::default'
12
+
13
+ apt_key = 'CBCB082A1BB943DB'
14
+ apt_key = 'F1656F24C74CD1D8' if node['platform'] == 'ubuntu' && node['platform_version'].split('.')[0].to_i >= 16
15
+
16
+ apt_repository "mariadb-#{node['mariadb']['install']['version']}" do
17
+ uri 'http://' + node['mariadb']['apt_repository']['base_url'] + '/' + \
18
+ node['mariadb']['install']['version'] + '/' + node['platform']
19
+ distribution node['lsb']['codename']
20
+ components ['main']
21
+ keyserver 'keyserver.ubuntu.com'
22
+ key apt_key
23
+ end
24
+ when 'yum'
25
+ include_recipe 'yum::default'
26
+
27
+ target_platform = if node['platform'] == 'redhat' || node['platform'] == 'scientific'
28
+ "rhel#{node['platform_version'].to_i}"
29
+ else
30
+ "#{node['platform']}#{node['platform_version'].to_i}"
31
+ end
32
+ yum_repository "mariadb-#{node['mariadb']['install']['version']}" do
33
+ description 'MariaDB Official Repository'
34
+ baseurl 'http://yum.mariadb.org/' + \
35
+ node['mariadb']['install']['version'] + "/#{target_platform}-amd64"
36
+ gpgkey 'https://yum.mariadb.org/RPM-GPG-KEY-MariaDB'
37
+ action :create
38
+ end
39
+
40
+ case node['platform']
41
+ when 'redhat', 'centos', 'scientific'
42
+ include_recipe 'yum-epel::default'
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,157 @@
1
+ #
2
+ # Cookbook Name:: mariadb
3
+ # Recipe:: server
4
+ #
5
+ # Copyright 2014, blablacar.com
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ Chef::Recipe.send(:include, MariaDB::Helper)
21
+
22
+ extend Chef::Util::Selinux
23
+ selinux_enabled = selinux_enabled?
24
+
25
+ case node['mariadb']['install']['type']
26
+ when 'package'
27
+ # Determine service name and register the resource
28
+ service_name = mariadb_service_name(node['platform'],
29
+ node['platform_version'],
30
+ node['mariadb']['install']['version'],
31
+ node['mariadb']['install']['prefer_os_package'],
32
+ node['mariadb']['install']['prefer_scl_package'])
33
+ node.default['mariadb']['mysqld']['service_name'] = service_name unless service_name.nil?
34
+ service 'mysql' do
35
+ service_name node['mariadb']['mysqld']['service_name']
36
+ supports restart: true
37
+ action :nothing
38
+ end
39
+
40
+ # Include recipe to install required repositories
41
+ include_recipe "#{cookbook_name}::_mariadb_repository"
42
+
43
+ # Include platform specific recipes
44
+ case node['platform']
45
+ when 'debian', 'ubuntu'
46
+ include_recipe "#{cookbook_name}::_debian_server"
47
+ when 'redhat', 'centos', 'scientific', 'amazon'
48
+ include_recipe "#{cookbook_name}::_redhat_server"
49
+ end
50
+
51
+ # Install server package
52
+ server_package_name = packages_names_to_install(node['platform'],
53
+ node['platform_version'],
54
+ node['mariadb']['install']['version'],
55
+ node['mariadb']['install']['prefer_os_package'],
56
+ node['mariadb']['install']['prefer_scl_package'])['server']
57
+ package 'MariaDB-server' do
58
+ package_name server_package_name
59
+ action :install
60
+ notifies :enable, 'service[mysql]'
61
+ end
62
+ end
63
+
64
+ include_recipe "#{cookbook_name}::config"
65
+
66
+ # move the datadir if needed
67
+ if node['mariadb']['mysqld']['datadir'] !=
68
+ node['mariadb']['mysqld']['default_datadir']
69
+
70
+ bash 'move-datadir' do
71
+ user 'root'
72
+ code <<-EOH
73
+ /bin/cp -a #{node['mariadb']['mysqld']['default_datadir']}/* \
74
+ #{node['mariadb']['mysqld']['datadir']} &&
75
+ /bin/rm -r #{node['mariadb']['mysqld']['default_datadir']} &&
76
+ /bin/ln -s #{node['mariadb']['mysqld']['datadir']} \
77
+ #{node['mariadb']['mysqld']['default_datadir']}
78
+ EOH
79
+ action :nothing
80
+ end
81
+
82
+ bash 'Restore security context' do
83
+ user 'root'
84
+ code "/usr/sbin/restorecon -v #{node['mariadb']['mysqld']['default_datadir']}"
85
+ only_if { selinux_enabled }
86
+ subscribes :run, 'bash[move-datadir]', :immediately
87
+ action :nothing
88
+ end
89
+
90
+ directory node['mariadb']['mysqld']['datadir'] do
91
+ owner 'mysql'
92
+ group 'mysql'
93
+ mode '0750'
94
+ action :create
95
+ notifies :stop, 'service[mysql]', :immediately
96
+ notifies :run, 'bash[move-datadir]', :immediately
97
+ notifies :start, 'service[mysql]', :immediately
98
+ only_if { !File.symlink?(node['mariadb']['mysqld']['default_datadir']) }
99
+ end
100
+ end
101
+
102
+ # restart the service if needed
103
+ # workaround idea from https://github.com/stissot
104
+ Chef::Resource::Execute.send(:include, MariaDB::Helper)
105
+ execute 'mariadb-service-restart-needed' do
106
+ command 'true'
107
+ only_if do
108
+ mariadb_service_restart_required?(
109
+ node['mariadb']['mysqld']['bind_address'],
110
+ node['mariadb']['mysqld']['port'],
111
+ node['mariadb']['mysqld']['socket']
112
+ )
113
+ end
114
+ notifies :restart, 'service[mysql]', :immediately
115
+ end
116
+
117
+ if node['mariadb']['allow_root_pass_change']
118
+ # Used to change root password after first install
119
+ # Still experimental
120
+ md5 = if node['mariadb']['server_root_password'].empty?
121
+ Digest::MD5.hexdigest('empty')
122
+ else
123
+ Digest::MD5.hexdigest(node['mariadb']['server_root_password'])
124
+ end
125
+
126
+ file '/etc/mysql_root_change' do
127
+ content md5
128
+ action :create
129
+ notifies :run, 'execute[install-grants]', :immediately
130
+ end
131
+ end
132
+
133
+ if node['mariadb']['allow_root_pass_change'] ||
134
+ node['mariadb']['remove_anonymous_users'] ||
135
+ node['mariadb']['forbid_remote_root'] ||
136
+ node['mariadb']['remove_test_database']
137
+ execute 'install-grants' do
138
+ command '/bin/bash -e /etc/mariadb_grants \'' + \
139
+ node['mariadb']['server_root_password'] + '\''
140
+ only_if { File.exist?('/etc/mariadb_grants') }
141
+ sensitive true
142
+ action :nothing
143
+ end
144
+ template '/etc/mariadb_grants' do
145
+ sensitive true
146
+ source 'mariadb_grants.erb'
147
+ owner 'root'
148
+ group 'root'
149
+ mode '0600'
150
+ helpers MariaDB::Helper
151
+ notifies :run, 'execute[install-grants]', :immediately
152
+ end
153
+ end
154
+
155
+ # MariaDB Plugins
156
+ include_recipe "#{cookbook_name}::plugins" if \
157
+ node['mariadb']['plugins_options']['auto_install']
@@ -0,0 +1,13 @@
1
+ #
2
+ # Cookbook Name:: mariadb
3
+ # Resource:: configuration
4
+ #
5
+
6
+ actions :add, :remove
7
+ default_action :add
8
+
9
+ # name of the extra conf file, used for .cnf filename
10
+ attribute :conf_name, kind_of: String, name_attribute: true
11
+ attribute :section, kind_of: String
12
+ attribute :option, kind_of: Hash, default: {}
13
+ attribute :cookbook, kind_of: String, default: nil
@@ -0,0 +1,25 @@
1
+ provides :mysql2_gem
2
+ resource_name :mysql2_gem
3
+
4
+ property :compile_time, [true, false], default: false
5
+
6
+ default_action :install
7
+
8
+ action :install do
9
+ include_recipe 'mariadb::devel'
10
+ build_essential 'install_packages'
11
+ gem_package 'mysql2'
12
+ end
13
+
14
+ action :remove do
15
+ gem_package 'mysql2' do
16
+ action :remove
17
+ end
18
+ end
19
+
20
+ def after_created
21
+ return unless compile_time
22
+ Array(action).each do |action|
23
+ run_action(action)
24
+ end
25
+ end