Skip to content
This repository was archived by the owner on Mar 6, 2021. It is now read-only.

Commit 8c552e0

Browse files
committed
Merge pull request #45 from alt3/dev
Merge dev in preparation for release 1.0-alpha1
2 parents 9e41316 + 3847b56 commit 8c552e0

39 files changed

+1200
-289
lines changed

.cakebox/.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Do not ignore anything in this subdirectory
22
!*
33

4-
# Except the git cloned Cakebox Console directory
4+
# Except these file
5+
last-known-box-version
6+
7+
# Except these directories
58
console/
9+
backups/

.cakebox/LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 ALT3 B.V.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

.cakebox/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cakebox 0.1.1
1+
cakebox 1.0-alpha1

.cakebox/Vagrantfile.rb

Lines changed: 208 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,45 @@ class Cakebox
22
def Cakebox.configure(config, user_settings)
33
require 'vagrant/util/deep_merge'
44
require 'json'
5+
require 'tempfile'
6+
7+
# Use absolute paths to construct file paths to support Vagrant Lookup Path
8+
# tree climbing (and thus running vagrant commands in any subfolder).
9+
currentFolder = "#{File.dirname(__FILE__)}"
10+
rootFolder = File.expand_path("..", currentFolder)
511

612
# Define absolutely required box settings
713
settings = Hash.new
814
settings["vm"] = Hash.new
915
settings["vm"]["hostname"] = "cakebox"
1016
settings["vm"]["ip"] = "10.33.10.10"
11-
settings["vm"]["memory"] = 2048
17+
settings["vm"]["memory"] = 1024
1218
settings["vm"]["cpus"] = 1
1319
settings["cakebox"] = Hash.new
14-
settings["cakebox"]["branch"] = "master"
20+
settings["cakebox"]["version"] = "dev-master"
21+
22+
if user_settings == false
23+
user_settings = Hash.new
24+
end
1525

16-
# Prevent merging empty vm user settings
17-
user_settings["vm"] = Hash.new if user_settings["vm"].nil?
18-
user_settings["vm"]["hostname"] = settings["vm"]["hostname"] if user_settings["vm"]["hostname"].nil?
19-
user_settings["vm"]["ip"] = settings["vm"]["ip"] if user_settings["vm"]["ip"].nil?
20-
user_settings["vm"]["memory"] = settings["vm"]["memory"] if user_settings["vm"]["memory"].nil?
21-
user_settings["vm"]["cpus"] = settings["vm"]["cpus"] if user_settings["vm"]["cpus"].nil?
22-
user_settings["cakebox"]["branch"] = settings["cakebox"]["branch"] if user_settings["cakebox"]["branch"].nil?
26+
# Deep merge user settings found in Cakebox.yaml. Uses the Vagrant Util
27+
# class to prevent a Vagrant plugin dependency + our custom 'compact' Hash
28+
# cleaner class to prevent non-DRY checking per setting.
29+
settings = Vagrant::Util::DeepMerge.deep_merge(settings, user_settings.compact!)
30+
settings.tildeConvert!
31+
32+
# Determine Cakebox Dashboard protocol only once
33+
if settings['cakebox']['https'] == true
34+
settings['cakebox']['protocol'] = 'https'
35+
else
36+
settings['cakebox']['protocol'] = 'http'
37+
end
2338

24-
# Deep merge user settings found in Cakebox.yaml without plugin dependency
25-
settings = Vagrant::Util::DeepMerge.deep_merge(settings, user_settings)
39+
# Specify Vagrant post-up message
40+
config.vm.post_up_message =
41+
"Your box is ready and waiting.\n\n" +
42+
"=> Login to your Dashboard by browsing to " + settings['cakebox']['protocol'] + '://' + settings["vm"]["ip"] + "\n" +
43+
"=> Login to your virtual machine by running: vagrant ssh"
2644

2745
# Specify CDN base-box and hostname for the vm
2846
config.vm.box = "cakebox"
@@ -41,9 +59,38 @@ def Cakebox.configure(config, user_settings)
4159
#vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
4260
end
4361

44-
# Mount small (and thus fast) scripts folder instead of complete box root folder.
62+
# SSH copy bash aliases file to the box
63+
config.vm.provision "file", source: currentFolder + File::SEPARATOR + "aliases", destination: "/home/vagrant/.bash_aliases"
64+
65+
# SSH copy local Cakebox.yaml to /home/vagrant/.cakebox when --provision is
66+
# being used so it can be used for virtual machine information.
67+
config.vm.provision "file", source: rootFolder + File::SEPARATOR + "Cakebox.yaml", destination: "/home/vagrant/.cakebox/last-known-cakebox-yaml" #@todo
68+
69+
# SSH copy most recent local Git commit for alt3/cakebox to /home/vagrant/.cakebox
70+
composerVersionParts = settings['cakebox']['version'].split('-')
71+
if composerVersionParts[1].nil?
72+
raise Vagrant::Errors::VagrantError.new, 'Fatal: unable to extract local git branch from composer version "' + settings['cakebox']['version'] + '"'
73+
end
74+
headFile = rootFolder + File::SEPARATOR + ".git" + File::SEPARATOR + "refs" + File::SEPARATOR + "heads" + File::SEPARATOR + "dev"
75+
config.vm.provision "file", source: headFile, destination: "/home/vagrant/.cakebox/last-known-cakebox-commit"
76+
77+
# Write vagrant box version to file before ssh copying to /home/vagrant/.cakebox
78+
tempfile = Tempfile.new('last-known-box-version')
79+
boxes = `vagrant box list`
80+
boxes.match(/cakebox\s+\(virtualbox,\s(.+)\)/)
81+
tempfile.write($1)
82+
config.vm.provision "file", source: tempfile, destination: "/home/vagrant/.cakebox/last-known-box-version"
83+
tempfile.close
84+
85+
# Mount small (and thus fast) scripts folder instead of complete box root folder
4586
config.vm.synced_folder '.', '/vagrant', disabled: true
46-
config.vm.synced_folder '.cakebox', '/cakebox'
87+
config.vm.synced_folder '.cakebox', '/cakebox', :mount_options => ["dmode=777","fmode=766"], create: true
88+
89+
# Temporarily mount .vagrant directory so we can replace the Vagrant 1.7.x
90+
# secure private key until these issues are resolved:
91+
# https://github.com/mitchellh/vagrant/issues/5090
92+
# https://github.com/mitchellh/vagrant/issues/4967
93+
config.vm.synced_folder '.vagrant', '/vagrant', :mount_options => ["dmode=777","fmode=766"], create: true
4794

4895
# Create Vagrant Synced Folders for all yaml specified "folders".
4996
unless settings["synced_folders"].nil?
@@ -78,42 +125,46 @@ def Cakebox.configure(config, user_settings)
78125
# Replace insecure Vagrant ssh public key with user generated public key
79126
unless settings["security"].nil?
80127
unless settings["security"]["box_public_key"].nil?
128+
81129
public_key = settings["security"]["box_public_key"]
82130
unless File.exists?(public_key)
83-
raise Vagrant::Errors::VagrantError.new, "Fatal: your public ssh key does not exist (#{settings["security"]["box_public_key"]})"
131+
raise Vagrant::Errors::VagrantError.new, "Fatal: your public SSH key does not exist (#{public_key})"
84132
end
85133

86-
# A public key MUST be an accompanied by a private key
134+
# A public key MUST be accompanied by a private key
87135
if settings["security"]["box_private_key"].nil?
88136
raise Vagrant::Errors::VagrantError.new, "Fatal: using a public ssh key also requires specifying a local private ssh key in your Cakebox.yaml"
89137
end
90-
unless File.exists?(settings["security"]["box_private_key"])
91-
raise Vagrant::Errors::VagrantError.new, "Fatal: your private ssh key does not exist (#{settings["security"]["box_private_key"]})"
138+
139+
private_key = settings["security"]["box_private_key"]
140+
unless File.exists?(private_key)
141+
raise Vagrant::Errors::VagrantError.new, "Fatal: your private ssh key does not exist (#{private_key})"
92142
end
93143

94144
# Copy user's public key to the vm so it can be validated and applied
95-
config.vm.provision "file", source: settings["security"]["box_public_key"], destination: "/home/vagrant/.ssh/" + File.basename(settings["security"]["box_public_key"])
145+
config.vm.provision "file", source: public_key, destination: "/home/vagrant/.ssh/" + File.basename(public_key)
96146

97147
# Add user's private key to all Vagrant-usable local private keys so all
98148
# required login scenarios will keep functioning as expected:
99149
# - initial non-secure vagrant up
100150
# - users protecting their box with a personally generated public key
101151
config.ssh.private_key_path = [
102-
'~/.vagrant.d/insecure_private_key',
103-
settings["security"]["box_private_key"]
152+
private_key,
153+
Dir.home + '/.vagrant.d/insecure_private_key'
104154
]
105155

106156
# Run bash script to replace insecure public key in authorized_keys
107157
config.vm.provision "shell" do |s|
108-
s.inline = "bash /cakebox/bash/replace-insecure-key.sh $@"
109-
s.args = "/home/vagrant/.ssh/" + File.basename(settings["security"]["box_public_key"])
158+
s.inline = "bash /cakebox/bash/ssh-authentication.sh $@"
159+
s.args = [ File.basename(public_key), File.basename(private_key) ]
110160
end
161+
162+
# Prevent Vagrant 1.7.x from generating a new private key and inserting
163+
# corresponding public key (overwriting our just set custom key).
164+
config.ssh.insert_key = false
111165
end
112166
end
113167

114-
# SSH copy bash aliases file to the box
115-
config.vm.provision "file", source: ".cakebox/aliases", destination: "/home/vagrant/.bash_aliases"
116-
117168
# Always display SSH Agent Forwarding sanity checks
118169
config.vm.provision "shell" do |s|
119170
s.privileged = false
@@ -124,7 +175,31 @@ def Cakebox.configure(config, user_settings)
124175
config.vm.provision "shell" do |s|
125176
s.privileged = false
126177
s.inline = "bash /cakebox/bash/console-installer.sh $@"
127-
s.args = user_settings["cakebox"]["branch"]
178+
s.args = settings["cakebox"]["version"]
179+
end
180+
181+
# Run cakebox self-update
182+
config.vm.provision "shell" do |s|
183+
s.privileged = false
184+
s.inline = "bash /cakebox/console/bin/cake update self"
185+
end
186+
187+
# Set Cakebox Dashboard protocol to HTTP or HTTPS
188+
config.vm.provision "shell" do |s|
189+
s.privileged = false
190+
s.inline = "bash /cakebox/console/bin/cake config dashboard --force --protocol $@"
191+
s.args = settings["cakebox"]["protocol"]
192+
end
193+
194+
# Turn CakePHP debug mode on/off for Cakebox Commands and Dashboard
195+
config.vm.provision "shell" do |s|
196+
s.privileged = false
197+
s.inline = "bash /cakebox/console/bin/cake config debug $@"
198+
if settings["cakebox"]["debug"] == false
199+
s.args = 'off'
200+
else
201+
s.args = 'on'
202+
end
128203
end
129204

130205
# Set global git username and email using `cakebox config git [options]`
@@ -143,14 +218,14 @@ def Cakebox.configure(config, user_settings)
143218
end
144219
end
145220

146-
# Create Nginx site configuration files for all yaml specified "sites"
147-
unless settings["sites"].nil?
148-
settings["sites"].each do |site|
221+
# Create Nginx virtual hosts for all yaml specified "vhosts"
222+
unless settings["vhosts"].nil?
223+
settings["vhosts"].each do |vhost|
149224
config.vm.provision "shell" do |s|
150225
s.privileged = false
151-
s.inline = "bash /cakebox/console/bin/cake site add $@"
152-
s.args = [ site["url"], site["webroot"] ]
153-
s.args.push(site["options"]) if !site["options"].nil?
226+
s.inline = "bash /cakebox/console/bin/cake vhost add $@"
227+
s.args = [ vhost["url"], vhost["webroot"] ]
228+
s.args.push(vhost["options"]) if !vhost["options"].nil?
154229
end
155230
end
156231
end
@@ -167,34 +242,123 @@ def Cakebox.configure(config, user_settings)
167242
end
168243
end
169244

170-
# Install fully working framework applications for all yaml specified "apps"
245+
# Install fully working framework applications for all yaml specified "apps".
246+
# The --repair parameter is appended so only missing components will be
247+
# installed when the sources already exist (e.g. when recreating a new box
248+
# with existing sources in a mapped Synced Folder)
171249
unless settings["apps"].nil?
172250
settings["apps"].each do |app|
173251
config.vm.provision "shell" do |s|
174252
s.privileged = false
175253
s.inline = "bash /cakebox/console/bin/cake application add $@"
176254
s.args = [ app["url"] ]
177255
s.args.push(app["options"]) if !app["options"].nil?
256+
s.args.push('--repair')
178257
end
179258
end
180259
end
181260

182-
# Install all yaml specified "additional_software" packages
183-
unless settings["software"].nil?
184-
settings["software"].each do |package|
185-
config.vm.provision "shell" do |s|
186-
s.privileged = false
187-
s.inline = "bash /cakebox/console/bin/cake package add $@"
188-
s.args = [ package["package"] ]
261+
# Install extras
262+
unless settings["extra"].nil?
263+
settings["extra"].each do | hash |
264+
hashKey = hash.keys.first
265+
unless hash[hashKey].nil?
266+
267+
# Install additional apt packages from the Ubuntu Package Archive
268+
if hashKey == "apt_packages"
269+
hash[hashKey].each do | package |
270+
config.vm.provision "shell" do |s|
271+
s.privileged = false
272+
s.inline = "bash /cakebox/console/bin/cake package add $@"
273+
s.args = [package]
274+
end
275+
end
276+
end
277+
278+
# Upload and run user created bash scripts
279+
if hashKey == "scripts"
280+
hash[hashKey].each do | script |
281+
remoteCopy = "/home/vagrant/.cakebox/last-known-script." + File.basename(script.to_s)
282+
config.vm.provision "file", source: script, destination: remoteCopy
283+
config.vm.provision "shell" do |s|
284+
s.privileged = false
285+
s.inline = "bash " + remoteCopy
286+
end
287+
end
288+
end
189289
end
190290
end
191291
end
192292

193-
# Provide user with box-info
194-
config.vm.provision "shell" do |s|
195-
s.inline = "bash /cakebox/bash/box-info.sh $@"
196-
s.args = [ settings["vm"]["ip"] ]
293+
end
294+
end
295+
296+
297+
298+
# Hash cleaner, removes nil/empty values recursively from a hash.
299+
#
300+
# Very handy to avoid errors when user yaml file does not include all required parts
301+
# After removing nil values, it can safely be deep merged into default settings,
302+
# without the need to check for all keys being present or having a value
303+
class Hash
304+
def compact!
305+
self.delete_if do |key, val|
306+
307+
if block_given?
308+
yield(key,val)
309+
else
310+
test1 = val.nil?
311+
test2 = val.empty? if val.respond_to?('empty?')
312+
test3 = val.strip.empty? if val.is_a?(String) && val.respond_to?('empty?')
313+
314+
test1 || test2 || test3
315+
end
316+
end
317+
318+
self.each do |key, val|
319+
if self[key].is_a?(Hash) && self[key].respond_to?('compact!')
320+
if block_given?
321+
self[key] = self[key].compact!(&Proc.new)
322+
else
323+
self[key] = self[key].compact!
324+
end
325+
end
197326
end
198327

328+
return self
329+
end
330+
end
331+
332+
# Recursively searches a Hash for Strings starting with ~ and then replaces ~
333+
# with OS independent Dir.home so we can support the use of ~ on Windows too.
334+
class Hash
335+
def tildeConvert!
336+
self.each do | key, value |
337+
338+
if value.is_a?(String)
339+
if ( value =~ /^~/ )
340+
self[key] = value.sub(/^~/, Dir.home)
341+
end
342+
end
343+
344+
if value.is_a?(Array)
345+
value.each_with_index do | arrayElement, i |
346+
if arrayElement.is_a?(String)
347+
if ( arrayElement =~ /^~/ )
348+
self[key][i] = arrayElement.sub(/^~/, Dir.home)
349+
end
350+
end
351+
352+
if arrayElement.is_a?(Hash)
353+
arrayElement.tildeConvert!
354+
end
355+
end
356+
end
357+
358+
if value.is_a?(Hash)
359+
value.tildeConvert!
360+
end
361+
362+
end
199363
end
200364
end

.cakebox/backups/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Backups
2+
3+
This directory will be used for backups of your:
4+
5+
+ MySQL database server (full)

.cakebox/bash/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bash scripts used by ``.cakebox/Vagrantfile.rb`` when running ``vagrant --provision``.

0 commit comments

Comments
 (0)