-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathonboard.rb
207 lines (175 loc) · 6 KB
/
onboard.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# -*- coding: UTF-8 -*-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + '/lib'
require 'rubygems'
begin
require 'bundler/setup'
rescue LoadError
warn 'Warning: Not leveraging Bundler -- is it installed?'
end
require 'find'
require 'logger'
require 'etc'
require 'onboard/constants'
require 'onboard/logger'
require 'onboard/exceptions'
require 'onboard/extensions/object'
require 'onboard/extensions/logger'
require 'onboard/menu/node'
require 'onboard/system/command'
require 'onboard/platform/debian'
require 'onboard/network/dnsmasq'
if Process.uid == 0
fail 'OnBoard should not be run as root: use an user who can sudo instead!'
end
class OnBoard
FileUtils.mkdir_p RWDIR
FileUtils.chmod 0700, RWDIR # too much sensible data here ;-)
FileUtils.mkdir_p LOGDIR unless Dir.exists? LOGDIR
use_logfile
LOGGER.level = Logger::INFO
LOGGER.level = Logger::DEBUG if
$0 == __FILE__ and not
ENV['ONBOARD_ENVIRONMENT'] =~ /production/i
# this is required because there is no Sinatra environment until
# controller.rb is loaded (where OnBoard::Controller inherits
# from Sinatra::Base)
PLATFORM = Platform::Debian # TODO? make it configurable? get rid of Platform?
MENU_ROOT = Menu::MenuNode.new('ROOT', {
:href => '/',
:name => 'Home',
:desc => 'Home page',
:n => 0
})
def self.find_n_load(dir)
# sort to resamble /etc/rc*.d/* or run-parts behavior
Find.find(dir).sort.each do |file|
if file =~ /\.rb$/
print "loading: #{file}... "
STDOUT.flush
if load file
print "OK\n"
STDOUT.flush
end
end
end
end
def self.web?
return true unless (ARGV.include?('--no-web') or ARGV.include?('--restore-dns'))
return false
end
def self.restore_dns
Network::Dnsmasq.init_conf
Network::Dnsmasq.restart
end
def self.prepare
system "sudo mkdir -p #{VARRUN}"
system "sudo chown #{Process.uid} #{VARRUN}"
# modules
Dir.foreach(ROOTDIR + '/modules') do |dir|
dir_fullpath = ROOTDIR + '/modules/' + dir
if File.directory? dir_fullpath and not dir =~ /^\./
file = dir_fullpath + '/load.rb'
if File.readable? file
if File.exists? dir_fullpath + '/.disable'
puts "Module #{dir}: disabled." if web? # be quiet if non-web
else
load dir_fullpath + '/load.rb'
puts "Module #{dir}: enabled." if web? # be quiet if non-web
end
else
STDERR.puts "Warning: Couldn't load modules/#{dir}/load.rb: Skipped!"
end
end
end
# After the modules, 'cause we want to know, among other things,
# whether to activate public pages layout configuration page
# (and relative menu item).
if web?
require 'onboard/controller/helpers'
require 'onboard/controller'
# modular menu
find_n_load ROOTDIR + '/etc/menu/'
end
# restore scripts, sorted like /etc/rc?.d/ SysVInit/Unix/Linux scripts
if ARGV.include? '--restore'
restore_scripts =
Dir.glob(ROOTDIR + '/etc/restore/[0-9][0-9]*.rb') #+
#Dir.glob(ROOTDIR + '/modules/*/etc/restore/[0-9][0-9]*.rb')
Dir.glob(ROOTDIR + '/modules/*').each do |module_dir|
next if File.exists? "#{module_dir}/.disable"
restore_scripts += Dir.glob("#{module_dir}/etc/restore/[0-9][0-9]*.rb")
end
restore_scripts.sort!{|x,y| File.basename(x) <=> File.basename(y)}
restore_scripts.each do |script|
print "loading: #{script}... "
STDOUT.flush
begin
load script and puts "OK"
rescue Exception
exception = $!
puts "ERR!"
puts "#{exception.class}: #{exception.message}"
LOGGER.error "loading #{script}: #{exception.inspect}"
backtrace_str = "Exception backtrace follows:"
exception.backtrace.each{|line| backtrace_str << "\n" << line}
LOGGER.error backtrace_str
end
end
end
# TODO: DRY DRY DRY
if ARGV.include? '--shutdown'
shutdown_scripts =
Dir.glob(ROOTDIR + '/etc/shutdown/[0-9][0-9]*.rb')
Dir.glob(ROOTDIR + '/modules/*').each do |module_dir|
next if File.exists? "#{module_dir}/.disable"
shutdown_scripts += Dir.glob("#{module_dir}/etc/shutdown/[0-9][0-9]*.rb")
end
shutdown_scripts.sort!{|x,y| File.basename(x) <=> File.basename(y)}
shutdown_scripts.each do |script|
print "loading: #{script}... "
STDOUT.flush
begin
load script and puts "OK"
rescue Exception
exception = $!
puts exception.inspect
LOGGER.error "loading #{script}: #{exception.inspect}"
backtrace_str = "Exception backtrace follows:"
exception.backtrace.each{|line| backtrace_str << "\n" << line}
LOGGER.error backtrace_str
end
end
end
end
def self.save!
LOGGER.info 'Saving configuration...'
find_n_load ROOTDIR + '/etc/save/'
# modules
Dir.glob(ROOTDIR + '/modules/*').each do |module_dir|
next if File.exists? "#{module_dir}/.disable"
Dir.glob("#{module_dir}/etc/save/*.rb").each do |script|
print "loading: #{script}... " and STDOUT.flush
load script and puts ' OK'
end
end
# for Voyage-Linux embedded Debian flavour http://linux.voyage.hk
voyage_sync = '/etc/init.d/voyage-sync'
if File.file? voyage_sync and File.executable? voyage_sync
# TODO: move this to a specific file/module/method...
rootfsmode = `(sudo touch /.rw 2> /dev/null) && echo 'rw' || echo 'ro'`.strip.to_sym
System::Command.run "remountrw", :sudo if rootfsmode == :ro
System::Command.run "#{voyage_sync} sync", :sudo
System::Command.run "remountro", :sudo if rootfsmode == :ro
end
System::Command.run 'sync'
end
end
OnBoard.prepare
if ARGV.include? '--restore-dns'
OnBoard.restore_dns
end
if OnBoard.web?
if $0 == __FILE__
OnBoard::Controller.run! :bind => '0.0.0.0'
end
end