| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package omnitool::installer; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
794
|
use 5.022001; |
|
|
1
|
|
|
|
|
4
|
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
19
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
39
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = "1.0.13"; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# for reading in configs |
|
10
|
1
|
|
|
1
|
|
1661
|
use File::Slurp; |
|
|
1
|
|
|
|
|
24572
|
|
|
|
1
|
|
|
|
|
70
|
|
|
11
|
1
|
|
|
1
|
|
1698
|
use IO::Prompter; |
|
|
1
|
|
|
|
|
37223
|
|
|
|
1
|
|
|
|
|
8
|
|
|
12
|
1
|
|
|
1
|
|
824
|
use Getopt::Long; |
|
|
1
|
|
|
|
|
10418
|
|
|
|
1
|
|
|
|
|
5
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# for creating config files |
|
15
|
1
|
|
|
1
|
|
731
|
use Template; |
|
|
1
|
|
|
|
|
19309
|
|
|
|
1
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# for building databases |
|
18
|
1
|
|
|
1
|
|
2065
|
use DBI; |
|
|
1
|
|
|
|
|
19184
|
|
|
|
1
|
|
|
|
|
67
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# for getting default hostname/domain name |
|
21
|
1
|
|
|
1
|
|
550
|
use Net::Domain qw( hostfqdn domainname ); |
|
|
1
|
|
|
|
|
8841
|
|
|
|
1
|
|
|
|
|
2673
|
|
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# create myself and try to grab arguments |
|
24
|
|
|
|
|
|
|
sub new { |
|
25
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# our variables |
|
28
|
0
|
|
|
|
|
|
my ($self, $default_text, $hostname, $domainname, $options_map, $option_keys, $options, $options_file, $line, $name, $value, $option_key, $my_git_repo); |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# my default hostname and domain name |
|
31
|
0
|
|
|
|
|
|
$hostname = hostfqdn(); |
|
32
|
0
|
|
|
|
|
|
$domainname = domainname(); |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# where OmniTool lives |
|
35
|
0
|
|
|
|
|
|
$my_git_repo = 'https://github.com/ericschernoff/omnitool'; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# we need a map of what our options mean and their defaults |
|
38
|
|
|
|
|
|
|
# the default will be the second item in the array, if there is a default |
|
39
|
|
|
|
|
|
|
$options_map = { |
|
40
|
|
|
|
|
|
|
'config-file' => ['Full path to a file name which will include some/all of the config parameters for this installer, one name=value pairs, one per line. Provided args will override.'], |
|
41
|
|
|
|
|
|
|
'save-config-file' => ['If you wish to save a file with config parameters, provide a full path to the new file.'], |
|
42
|
|
|
|
|
|
|
'save-config-file-only' => ['Will save file with config parameters and exit without attempting to install; provide a full path to the new file.'], |
|
43
|
|
|
|
|
|
|
'othome' => ['The root directory for OmniTool, e.g. /usr/local/omnitool','/opt/omnitool'], |
|
44
|
|
|
|
|
|
|
'database-server' => ['Hostname or IP address of primary MySQL database server','127.0.0.1'], |
|
45
|
|
|
|
|
|
|
'db-username' => ['Username for connecting to MySQL; value must be provided'], |
|
46
|
|
|
|
|
|
|
'db-password' => ['Password for connecting to MySQL; value must be provided'], |
|
47
|
|
|
|
|
|
|
'init-vector' => ['Init vector for MySQL encryption; value longer than 10 characters must be provided'], |
|
48
|
|
|
|
|
|
|
'salt-phrase' => ['Salt phrase for MySQL encryption; value longer than 10 characters must be provided'], |
|
49
|
|
|
|
|
|
|
'ot-cookie-domain' => ['The domain name for the authentication cookie',$domainname], |
|
50
|
|
|
|
|
|
|
'ot-primary-hostname' => ['The full hostname for the main Web URI for this system',$hostname], |
|
51
|
|
|
|
|
|
|
'omnitool-admin' => ['The email address of the responsible party(ies) for this OmniTool system',$ENV{USER}.'@'.$domainname], |
|
52
|
0
|
|
|
|
|
|
'os-username' => ['The OS username who will run and own all OmniTool processes and resources',$ENV{USER}], |
|
53
|
|
|
|
|
|
|
'admin-ui-password' => [qq{The password for the 'omnitool_admin' user in the OT Admin Web UI; value must be provided}], |
|
54
|
|
|
|
|
|
|
'source_git_repo' => [qq{The source repo for OmniTool; change from default only if you have your own trusted fork.}, $my_git_repo], |
|
55
|
|
|
|
|
|
|
}; |
|
56
|
0
|
|
|
|
|
|
$option_keys = [ |
|
57
|
|
|
|
|
|
|
'config-file','save-config-file','save-config-file-only', |
|
58
|
|
|
|
|
|
|
'othome','database-server','db-username','db-password', |
|
59
|
|
|
|
|
|
|
'init-vector','salt-phrase', |
|
60
|
|
|
|
|
|
|
'omnitool-admin','os-username','admin-ui-password', |
|
61
|
|
|
|
|
|
|
'ot-cookie-domain','ot-primary-hostname','source_git_repo' |
|
62
|
|
|
|
|
|
|
]; |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# what arguments did they send? |
|
65
|
0
|
|
|
|
|
|
$options = {}; |
|
66
|
0
|
|
|
|
|
|
GetOptions ($options, qw(-help+ |
|
67
|
|
|
|
|
|
|
-config-file=s -save-config-file=s -save-config-file-only=s |
|
68
|
|
|
|
|
|
|
-othome=s -database-server=s |
|
69
|
|
|
|
|
|
|
-db-username=s -db-password=s init-vector=s -salt-phrase=s -ot-cookie-domain=s |
|
70
|
|
|
|
|
|
|
-admin-ui-password=s -ot-primary-hostname=s -omnitool-admin=s -os-username=s |
|
71
|
|
|
|
|
|
|
-source_git_repo=s) |
|
72
|
|
|
|
|
|
|
); |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# do they just want to see the help screen? |
|
75
|
0
|
0
|
|
|
|
|
if ($$options{help}) { |
|
76
|
0
|
|
|
|
|
|
$self = bless { |
|
77
|
|
|
|
|
|
|
'options' => $options, |
|
78
|
|
|
|
|
|
|
'options_map' => $options_map, |
|
79
|
|
|
|
|
|
|
'option_keys' => $option_keys, |
|
80
|
|
|
|
|
|
|
}, $class; |
|
81
|
0
|
|
|
|
|
|
$self->print_help_text(); |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# if they sent a file that exists, read it to get any options now already sent |
|
85
|
0
|
0
|
0
|
|
|
|
if ($$options{'config-file'} && (-e $$options{'config-file'})) { |
|
86
|
0
|
|
|
|
|
|
$options_file = read_file($$options{'config-file'}); |
|
87
|
0
|
|
|
|
|
|
foreach $line (split /\n/, $options_file) { |
|
88
|
0
|
|
|
|
|
|
($name,$value) = split /\s?\=\s?/, $line; |
|
89
|
0
|
0
|
|
|
|
|
next if $$options{$name}; # skip if already filled |
|
90
|
0
|
|
|
|
|
|
$$options{$name} = $value |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# now we need to validate what we have so far, and prompt for what we do not have |
|
95
|
0
|
|
|
|
|
|
foreach $option_key (@$option_keys) { |
|
96
|
0
|
0
|
|
|
|
|
next if $option_key =~ /config-file/; # not for the config files |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# if we do not have a value for this option, prompt for it |
|
99
|
0
|
0
|
|
|
|
|
if (!$$options{$option_key}) { |
|
100
|
|
|
|
|
|
|
# does it have a default? |
|
101
|
0
|
0
|
|
|
|
|
if ($$options_map{$option_key}[1]) { |
|
102
|
0
|
|
|
|
|
|
$default_text = ' [Default: '.$$options_map{$option_key}[1].']: '; |
|
103
|
|
|
|
|
|
|
} else { # no default |
|
104
|
0
|
|
|
|
|
|
$default_text = ' [No Default] : '; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# password mode? |
|
108
|
0
|
0
|
|
|
|
|
if ($option_key =~ /password/i) { |
|
109
|
0
|
|
|
|
|
|
$$options{$option_key} = prompt $$options_map{$option_key}[0].$default_text, -v, -echo=>'*'; |
|
110
|
|
|
|
|
|
|
} else { # OK to show |
|
111
|
0
|
|
|
|
|
|
$$options{$option_key} = prompt $$options_map{$option_key}[0].$default_text, -v; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# if it was not provided, take any calculated default |
|
115
|
0
|
0
|
|
|
|
|
$$options{$option_key} = $$options_map{$option_key}[1] if !length($$options{$option_key}); |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# if it is required and either does not exist or is not long enough, then die() here. |
|
118
|
0
|
0
|
0
|
|
|
|
if (!length($$options{$option_key}) && ($$options_map{$option_key}[0] =~ /must be provided/ || $option_key eq 'source_git_repo')) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
die(qq{ERROR: You must provide a value for the '$option_key' option. Please run 'omnitool-installer --help' for details.}."\n"); |
|
120
|
|
|
|
|
|
|
} elsif (length($$options{$option_key}) < 10 && $$options_map{$option_key}[0] =~ /longer than 10 characters/) { |
|
121
|
0
|
|
|
|
|
|
die(qq{ERROR: Value for '$option_key' option must be 10 characters or greater. Please run 'omnitool-installer --help' for details.}."\n"); |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
} |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# set up the object with all the options data |
|
128
|
0
|
|
|
|
|
|
$self = bless { |
|
129
|
|
|
|
|
|
|
'options' => $options, |
|
130
|
|
|
|
|
|
|
'options_map' => $options_map, |
|
131
|
|
|
|
|
|
|
'option_keys' => $option_keys, |
|
132
|
|
|
|
|
|
|
}, $class; |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# do they want to save these configs back out (and potentially exit)? |
|
135
|
0
|
0
|
0
|
|
|
|
if ($self->{options}{'save-config-file'} || $self->{options}{'save-config-file-only'}) { |
|
136
|
0
|
|
|
|
|
|
$self->save_config_file(); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# if we are still alive, send it back |
|
140
|
0
|
|
|
|
|
|
return $self; |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# method to undertake all the installation tasks |
|
144
|
|
|
|
|
|
|
sub do_the_installation { |
|
145
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
146
|
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
|
my (@sub_directories, $config_file, $sub_directory, $the_sub_directory, $belt, $db_info, $distribution_directory, $htdocs_source, $htdocs_link, $omnitool_pm_source, $omnitool_pm_link, @ot_code_pieces, $ot_code_piece, $ot_code_source, $ot_code_link, @web_urls, $next_steps,$next_steps_file); |
|
148
|
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
print "\n\nATTEMPTING INSTALLATION TASKS:\n\n"; |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# here are the sub-directories we need |
|
152
|
0
|
|
|
|
|
|
@sub_directories = qw( |
|
153
|
|
|
|
|
|
|
code code/omnitool code/omnitool/applications |
|
154
|
|
|
|
|
|
|
configs configs/ssl_cert |
|
155
|
|
|
|
|
|
|
files hash_cache |
|
156
|
|
|
|
|
|
|
htdocs log log/archive |
|
157
|
|
|
|
|
|
|
tmp tmp/docs tmp/email_incoming tmp/pids |
|
158
|
|
|
|
|
|
|
); |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# start with the home directory |
|
161
|
0
|
0
|
|
|
|
|
if (!(-d $self->{options}{othome})) { |
|
162
|
0
|
|
|
|
|
|
mkdir($self->{options}{othome}, 0755); |
|
163
|
0
|
|
|
|
|
|
print "Created OmniTool root directory at ".$self->{options}{othome}."\n"; |
|
164
|
|
|
|
|
|
|
} else { |
|
165
|
0
|
|
|
|
|
|
print "OmniTool root directory already exists at ".$self->{options}{othome}."\n"; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
# no go through the sub directories |
|
169
|
0
|
|
|
|
|
|
foreach $sub_directory (@sub_directories) { |
|
170
|
0
|
|
|
|
|
|
$the_sub_directory = $self->{options}{othome}.'/'.$sub_directory; |
|
171
|
0
|
0
|
|
|
|
|
if (!(-d $the_sub_directory)) { |
|
172
|
0
|
|
|
|
|
|
mkdir($the_sub_directory, 0755); |
|
173
|
0
|
|
|
|
|
|
print "Created $the_sub_directory\n"; |
|
174
|
|
|
|
|
|
|
} else { |
|
175
|
0
|
|
|
|
|
|
print "Skipped $the_sub_directory - already exists\n"; |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# our distribution directory will be here: |
|
180
|
0
|
|
|
|
|
|
$distribution_directory = $self->{options}{othome}.'/distribution'; |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# now pull down the code |
|
183
|
0
|
0
|
|
|
|
|
if (-d $distribution_directory.'/omnitool') { # already there, need to do a 'git pull' |
|
184
|
0
|
|
|
|
|
|
chdir $distribution_directory; |
|
185
|
0
|
|
|
|
|
|
system('git','pull'); |
|
186
|
0
|
|
|
|
|
|
print "Latest OmniTool code repo *pulled* into $distribution_directory\n"; |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
} else { # need to do a clone |
|
189
|
0
|
|
|
|
|
|
system('git','clone',$self->{options}{source_git_repo},$distribution_directory); |
|
190
|
0
|
|
|
|
|
|
print "Latest OmniTool code repo *cloned* into $distribution_directory\n"; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# link distribution/htdocs to OTHOME/htdocs/omnitool |
|
194
|
0
|
|
|
|
|
|
$htdocs_source = $distribution_directory.'/htdocs'; |
|
195
|
0
|
|
|
|
|
|
$htdocs_link = $self->{options}{othome}.'/htdocs/omnitool'; |
|
196
|
0
|
0
|
|
|
|
|
if (!(-l $htdocs_link)) { |
|
197
|
0
|
|
|
|
|
|
symlink $htdocs_source, $htdocs_link; |
|
198
|
0
|
|
|
|
|
|
print "Linked static (HTML/JS/CSS/Images) collateral to $htdocs_link.\n"; |
|
199
|
|
|
|
|
|
|
} else { |
|
200
|
0
|
|
|
|
|
|
print "Skipped link to static (HTML/JS/CSS/Images) collateral to $htdocs_link; symlink already exists.\n"; |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# now link to the code, but make it possible for them to write their own applications under $OTPERL/applications |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# first: omnitool.pm |
|
206
|
0
|
|
|
|
|
|
$omnitool_pm_source = $distribution_directory.'/omnitool.pm'; |
|
207
|
0
|
|
|
|
|
|
$omnitool_pm_link = $self->{options}{othome}.'/code/omnitool.pm'; |
|
208
|
0
|
0
|
|
|
|
|
if (!(-l $omnitool_pm_link)) { |
|
209
|
0
|
|
|
|
|
|
symlink $omnitool_pm_source, $omnitool_pm_link; |
|
210
|
0
|
|
|
|
|
|
print "Linked omnitool.pm to $omnitool_pm_link.\n"; |
|
211
|
|
|
|
|
|
|
} else { |
|
212
|
0
|
|
|
|
|
|
print "Skipped link of omnitool.pm to $omnitool_pm_link; symlink already exists.\n"; |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# now the bits under the actual directory |
|
216
|
0
|
|
|
|
|
|
@ot_code_pieces = qw( |
|
217
|
|
|
|
|
|
|
common dispatcher.pm main.psgi omniclass omniclass.pm scripts |
|
218
|
|
|
|
|
|
|
static_files tool tool.pm |
|
219
|
|
|
|
|
|
|
applications/otadmin applications/sample_apps |
|
220
|
|
|
|
|
|
|
); |
|
221
|
0
|
|
|
|
|
|
foreach $ot_code_piece (@ot_code_pieces) { |
|
222
|
0
|
|
|
|
|
|
$ot_code_source = $distribution_directory.'/omnitool/'.$ot_code_piece; |
|
223
|
0
|
|
|
|
|
|
$ot_code_link = $self->{options}{othome}.'/code/omnitool/'.$ot_code_piece; |
|
224
|
0
|
0
|
|
|
|
|
if (!(-l $ot_code_link)) { |
|
225
|
0
|
|
|
|
|
|
symlink $ot_code_source, $ot_code_link; |
|
226
|
0
|
|
|
|
|
|
print "Linked $ot_code_source to $ot_code_link.\n"; |
|
227
|
|
|
|
|
|
|
} else { |
|
228
|
0
|
|
|
|
|
|
print "Skipped link of $ot_code_source to $ot_code_link; symlink already exists.\n"; |
|
229
|
|
|
|
|
|
|
} |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# now, let's set up configs/dbinfo.txt |
|
233
|
0
|
|
|
|
|
|
$db_info = $self->{options}{'db-username'}."\n".$self->{options}{'db-password'}; |
|
234
|
0
|
|
|
|
|
|
$self->stash_some_text($db_info, $self->{options}{othome}.'/configs/dbinfo.txt'); |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# now create the configuration files |
|
237
|
0
|
|
|
|
|
|
foreach $config_file ('bash_aliases.tt','mysql_omnitool.cnf.tt','omnitool.service.tt','omnitool_apache.conf.tt','start_omnitool.bash.tt') { |
|
238
|
0
|
|
|
|
|
|
$self->create_config_files($config_file); |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# symlink over code map |
|
242
|
0
|
|
|
|
|
|
symlink $self->{options}{othome}.'/distribution/configs/ot6_modules.yml', $self->{options}{othome}.'/configs/ot6_modules.yml'; |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# if the user who will run OT6 is not the same username running this script, run a chown |
|
245
|
0
|
0
|
|
|
|
|
if ($ENV{USER} ne $self->{options}{'os-username'}) { |
|
246
|
0
|
|
|
|
|
|
system('chown -R '.$self->{options}{'os-username'}.' '.$self->{options}{othome}); |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# final step is the database work |
|
250
|
|
|
|
|
|
|
# we need to log into the database and see if we need to create the 'omnitool' and 'otstatedata' DB's |
|
251
|
|
|
|
|
|
|
# and then set up their OT6 Admin user |
|
252
|
0
|
|
|
|
|
|
$self->setup_databases(); |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# what is left for them to do? |
|
255
|
0
|
|
|
|
|
|
$web_urls[0] = 'https://'.$self->{options}{'ot-primary-hostname'}.'/sample_apps_admin'; |
|
256
|
0
|
|
|
|
|
|
$web_urls[1] = 'https://'.$self->{options}{'ot-primary-hostname'}.'/sample_tools'; |
|
257
|
0
|
|
|
|
|
|
$web_urls[2] = 'https://'.$self->{options}{'ot-primary-hostname'}.'/apps_admin'; |
|
258
|
0
|
|
|
|
|
|
$web_urls[3] = 'https://'.$self->{options}{'ot-primary-hostname'}.'/apps_admin#/tools/view_module_docs'; |
|
259
|
0
|
|
|
|
|
|
$next_steps = qq{ |
|
260
|
|
|
|
|
|
|
OMNITOOL INSTALLATION IS COMPLETE. |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Next Steps: |
|
263
|
|
|
|
|
|
|
1. Adjust your CLI environment by adding this to ~/.bash_aliases: |
|
264
|
|
|
|
|
|
|
source $self->{options}{othome}/configs/bash_aliases |
|
265
|
|
|
|
|
|
|
2. Bring in the Apache config (or adjust Nginix to taste). For Ubuntu: |
|
266
|
|
|
|
|
|
|
cd /etc/apache2/conf-enabled ; ln -s $self->{options}{othome}/configs/omnitool_apache.conf |
|
267
|
|
|
|
|
|
|
3. Install SSL certificates in here: $self->{options}{othome}/configs/ssl_cert |
|
268
|
|
|
|
|
|
|
- Self-signing cert info: https://httpd.apache.org/docs/2.4/ssl/ssl_faq.html#selfcert |
|
269
|
|
|
|
|
|
|
- You will need to edit lines 76-78 in $self->{options}{othome}/configs/omnitool_apache.conf |
|
270
|
|
|
|
|
|
|
4. Restart Apache: sudo systemctl restart apache2 |
|
271
|
|
|
|
|
|
|
5. Review/tweak and install the special MySQL Config File. For Ubuntu: |
|
272
|
|
|
|
|
|
|
cd /etc/mysql/mysql.conf.d ; sudo cp /opt/omnitool/configs/mysql_omnitool.cnf ./ |
|
273
|
|
|
|
|
|
|
\$EDITOR mysql_omnitool.cnf |
|
274
|
|
|
|
|
|
|
sudo systemctl restart mysql |
|
275
|
|
|
|
|
|
|
6. Reviw/tweak the script to start the Plack Service, especially lines 24-42: |
|
276
|
|
|
|
|
|
|
\$EDITOR /opt/omnitool/configs/start_omnitool.bash |
|
277
|
|
|
|
|
|
|
# Note the 'RECAPTCHA' vars if you want to use Google's ReCaptcha service. |
|
278
|
|
|
|
|
|
|
7. Start the Plack Service: |
|
279
|
|
|
|
|
|
|
sudo /opt/omnitool/configs/start_omnitool.bash start |
|
280
|
|
|
|
|
|
|
(Look at the omnitool.service SystemD script under /opt/omnitool/configs/ as well.) |
|
281
|
|
|
|
|
|
|
8. Check out the sample apps: |
|
282
|
|
|
|
|
|
|
Admin: $web_urls[0] |
|
283
|
|
|
|
|
|
|
User-Facing: $web_urls[1] |
|
284
|
|
|
|
|
|
|
9. Read some Perl docs: $web_urls[3] |
|
285
|
|
|
|
|
|
|
10. Get Started on Your Apps: $web_urls[2] |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
** The username for the Web URL's in steps 8-10 will be 'omnitool_admin' with the |
|
288
|
|
|
|
|
|
|
password you gave for the ''admin-ui-password' option. ** |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
If you have any questions, please reach out to ericschernoff\@gmail.com . |
|
291
|
|
|
|
|
|
|
}; |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# save that to their home directory |
|
294
|
0
|
|
|
|
|
|
$next_steps_file = $self->{options}{othome}.'/configs/omnitool_next_steps.txt'; |
|
295
|
0
|
|
|
|
|
|
write_file($next_steps_file,$next_steps); |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# output it, telling them where it is |
|
298
|
0
|
|
|
|
|
|
print $next_steps."\n(A copy of these next steps have been saved to $next_steps_file .\n"; |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
} |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# stripped-down version of text-stashing |
|
303
|
|
|
|
|
|
|
sub stash_some_text { |
|
304
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
305
|
|
|
|
|
|
|
|
|
306
|
0
|
|
|
|
|
|
my ($text_to_stash,$file_location) = @_; |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# garble it up |
|
309
|
0
|
|
|
|
|
|
my $obfuscated = unpack "h*", $text_to_stash; |
|
310
|
|
|
|
|
|
|
# get this out like: |
|
311
|
|
|
|
|
|
|
# $obfuscated = read_file($file_location); |
|
312
|
|
|
|
|
|
|
# my $stashed_text = pack "h*", $obfuscated; |
|
313
|
|
|
|
|
|
|
# print $stashed_text."\n"; |
|
314
|
|
|
|
|
|
|
# This is 0.0000001% of what pack() can do, please see: http://perldoc.perl.org/functions/pack.html |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
# stash it out |
|
317
|
0
|
|
|
|
|
|
write_file( $file_location, $obfuscated); |
|
318
|
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
|
return 1; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
# method to create new config files from my templates |
|
323
|
|
|
|
|
|
|
sub create_config_files { |
|
324
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# the name of the config file template we are going to create |
|
327
|
0
|
|
|
|
|
|
my ($config_filename) = @_; |
|
328
|
|
|
|
|
|
|
# return if blank or non-existent |
|
329
|
0
|
0
|
0
|
|
|
|
return if !$config_filename || !(-e $self->{options}{othome}.'/distribution/configs/'.$config_filename); |
|
330
|
|
|
|
|
|
|
|
|
331
|
0
|
|
|
|
|
|
my ($destination_file, $output, $tt, $key, $new_key); |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
# where is it going? |
|
334
|
0
|
|
|
|
|
|
$destination_file = $self->{options}{othome}.'/configs/'.$config_filename; |
|
335
|
0
|
|
|
|
|
|
$destination_file =~ s/.tt$//; |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# if it exists, abort |
|
338
|
0
|
0
|
|
|
|
|
if (-e $destination_file) { |
|
339
|
0
|
|
|
|
|
|
print "SKIPPED: Can not overwrite config file: $destination_file ; please delete and re-attempt or adjust by hand.\n"; |
|
340
|
0
|
|
|
|
|
|
return; |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
# i hate dashes, but felt like they were standard in the args |
|
344
|
0
|
|
|
|
|
|
foreach $key ('database-server','omnitool-admin','os-username','init-vector','salt-phrase','ot-cookie-domain','ot-primary-hostname') { |
|
345
|
0
|
|
|
|
|
|
($new_key = $key) =~ s/-/_/g; |
|
346
|
0
|
|
|
|
|
|
$self->{options}{$new_key} = $self->{options}{$key}; |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# prepare template toolkit |
|
350
|
0
|
|
|
|
|
|
$output = ''; # where the text shall go |
|
351
|
|
|
|
|
|
|
$tt = Template->new({ |
|
352
|
|
|
|
|
|
|
ENCODING => 'utf8', |
|
353
|
0
|
|
|
|
|
|
INCLUDE_PATH => $self->{options}{othome}.'/distribution/configs/', |
|
354
|
|
|
|
|
|
|
OUTPUT => \$output, |
|
355
|
|
|
|
|
|
|
}); |
|
356
|
|
|
|
|
|
|
# process the template |
|
357
|
0
|
|
|
|
|
|
$tt->process($config_filename, $self, $output, {binmode => ':encoding(utf8)'}); |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# save the new file under OTHOME/configs |
|
360
|
0
|
|
|
|
|
|
write_file($destination_file, $output); |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
# if it's start_omnitool.bash.tt, make it executable |
|
363
|
0
|
0
|
|
|
|
|
if ($config_filename eq 'start_omnitool.bash.tt') { |
|
364
|
0
|
|
|
|
|
|
chmod 0744, $destination_file; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
# symlink over code map |
|
368
|
0
|
|
|
|
|
|
symlink $self->{options}{othome}.'/distribution/configs/ot6_modules.yml', $self->{options}{othome}.'/configs/ot6_modules.yml'; |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
# report success |
|
371
|
0
|
|
|
|
|
|
print "Created config file $destination_file ; please verify and adjust.\n"; |
|
372
|
0
|
|
|
|
|
|
return; |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
# method to set up the 'omnitool' and 'otstatedata' databases |
|
376
|
|
|
|
|
|
|
sub setup_databases { |
|
377
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
378
|
|
|
|
|
|
|
|
|
379
|
0
|
|
|
|
|
|
my ($dsn, $dbh, $db_name, $sth, $exists, $safe_to_modify); |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# try to make the connection |
|
382
|
0
|
|
|
|
|
|
$dsn = qq{DBI:mysql:database=information_schema;host=}.$self->{options}{'database-server'}.qq{;port=3306}; |
|
383
|
0
|
|
|
|
|
|
$dbh = DBI->connect($dsn, $self->{options}{'db-username'}, $self->{options}{'db-password'},{ PrintError => 1, RaiseError=>1, mysql_enable_utf8=>8 }); |
|
384
|
0
|
|
|
|
|
|
$dbh->{LongReadLen} = 1000000; |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
# check to see if it has our databases |
|
387
|
0
|
|
|
|
|
|
foreach $db_name ('omnitool','otstatedata','omnitool_applications','omnitool_samples','sample_tools') { |
|
388
|
0
|
|
|
|
|
|
$sth = $dbh->prepare(qq{select CATALOG_NAME from SCHEMATA where SCHEMA_NAME='$db_name'}); |
|
389
|
0
|
0
|
|
|
|
|
$sth->execute or print $dbh->errstr."\n"; |
|
390
|
0
|
|
|
|
|
|
($exists) = $sth->fetchrow_array; |
|
391
|
0
|
0
|
|
|
|
|
if ($exists) { # if it exists, skip it |
|
392
|
0
|
|
|
|
|
|
print "SKIPPED: $db_name already exists and was not be overwritten.\n"; |
|
393
|
|
|
|
|
|
|
} else { # otherwise, load it in |
|
394
|
0
|
|
|
|
|
|
$sth = $dbh->prepare(qq{create database $db_name}); |
|
395
|
0
|
0
|
|
|
|
|
$sth->execute or print $dbh->errstr."\n"; |
|
396
|
0
|
|
|
|
|
|
system('mysql -u'.$self->{options}{'db-username'}.' -p'.$self->{options}{'db-password'}.' -h'.$self->{options}{'database-server'}.' '.$db_name.' < '.$self->{options}{othome}.'/distribution/schema/'.$db_name.'.sql'); |
|
397
|
0
|
|
|
|
|
|
print "Created $db_name from included schema.\n"; |
|
398
|
|
|
|
|
|
|
# so we know we can update the databases below with out install tweaks |
|
399
|
0
|
|
|
|
|
|
$$safe_to_modify{$db_name} = 1; |
|
400
|
|
|
|
|
|
|
} |
|
401
|
|
|
|
|
|
|
} |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
# start tweaking the omnitool(_*) DB's |
|
404
|
|
|
|
|
|
|
|
|
405
|
0
|
0
|
|
|
|
|
if ($$safe_to_modify{omnitool}) { # can modify core omnitool admin |
|
406
|
|
|
|
|
|
|
# fix the password for the 'omnitool_admin' user in all three databases |
|
407
|
0
|
|
|
|
|
|
foreach $db_name ('omnitool','omnitool_applications','omnitool_samples') { |
|
408
|
0
|
|
|
|
|
|
$sth = $dbh->prepare('update '.$db_name.qq{.omnitool_users set password=sha2(?,224) where username='omnitool_admin'}); |
|
409
|
0
|
0
|
|
|
|
|
$sth->execute($self->{options}{'admin-ui-password'}) or print $dbh->errstr."\n"; |
|
410
|
|
|
|
|
|
|
} |
|
411
|
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
print "Set Password for 'omnitool_admin' user in the OmniTool Admin Web UI.\n"; |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# fix the name and hostname of the Apps for their domain |
|
415
|
0
|
|
|
|
|
|
$sth = $dbh->prepare(qq{update omnitool.instances set name=?, hostname=? where code='10'}); |
|
416
|
0
|
0
|
|
|
|
|
$sth->execute('Admin for '.ucfirst($self->{options}{'ot-cookie-domain'}), 'apps-admin.'.$self->{options}{'ot-cookie-domain'}) or print $dbh->errstr."\n"; |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
# fix the name and hostname of the Sample Apps |
|
419
|
0
|
|
|
|
|
|
$sth = $dbh->prepare(qq{update omnitool.instances set hostname=? where code='9'}); |
|
420
|
0
|
0
|
|
|
|
|
$sth->execute('sample-apps-admin.'.$self->{options}{'ot-cookie-domain'}) or print $dbh->errstr."\n"; |
|
421
|
|
|
|
|
|
|
|
|
422
|
0
|
|
|
|
|
|
print "Updated Name, Hostname for Custom Applications Admin UI.\n"; |
|
423
|
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
} else { |
|
425
|
|
|
|
|
|
|
|
|
426
|
0
|
|
|
|
|
|
print "SKIPPED: Could not modify 'omnitool_admin' password; Core 'omnitool' database already exists.\n"; |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
# Update all database server records |
|
431
|
0
|
|
|
|
|
|
foreach $db_name ('omnitool','omnitool_applications','omnitool_samples') { |
|
432
|
0
|
0
|
|
|
|
|
if ($$safe_to_modify{$db_name}) { |
|
433
|
0
|
|
|
|
|
|
$sth = $dbh->prepare('update '.$db_name.qq{.database_servers set hostname=?}); |
|
434
|
0
|
0
|
|
|
|
|
$sth->execute($self->{options}{'database-server'}) or print $dbh->errstr."\n"; |
|
435
|
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
print "Set database server hostname for $db_name.\n"; |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
} else { |
|
439
|
0
|
|
|
|
|
|
print "SKIPPED: Could not set database server hostname for $db_name; that database already exists.\n"; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
} |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
} |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
# method to save out the config file if they sent the right arguments |
|
446
|
|
|
|
|
|
|
sub save_config_file { |
|
447
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
448
|
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
my ($option_key, $options_config); |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
# just need a set of name=value pairs, one per line |
|
452
|
0
|
|
|
|
|
|
foreach $option_key (@{ $self->{option_keys} }) { |
|
|
0
|
|
|
|
|
|
|
|
453
|
0
|
0
|
|
|
|
|
next if $option_key =~ /config-file/; # not for the config files |
|
454
|
0
|
|
|
|
|
|
$options_config .= $option_key.'='.$self->{options}{$option_key}."\n"; |
|
455
|
|
|
|
|
|
|
} |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
# take off the last character |
|
458
|
0
|
|
|
|
|
|
chomp($options_config); |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
# just save? |
|
461
|
0
|
0
|
|
|
|
|
if ($self->{options}{'save-config-file'}) { |
|
|
|
0
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
|
|
463
|
0
|
|
|
|
|
|
write_file($self->{options}{'save-config-file'}, $options_config); |
|
464
|
|
|
|
|
|
|
|
|
465
|
0
|
|
|
|
|
|
print "\n\nConfig options file saved to ".$self->{options}{'save-config-file'}."\n\n"; |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
# or save an exit |
|
468
|
|
|
|
|
|
|
} elsif ($self->{options}{'save-config-file-only'}) { |
|
469
|
|
|
|
|
|
|
|
|
470
|
0
|
|
|
|
|
|
write_file($self->{options}{'save-config-file-only'}, $options_config); |
|
471
|
|
|
|
|
|
|
|
|
472
|
0
|
|
|
|
|
|
print "\n\nConfig options file saved to ".$self->{options}{'save-config-file-only'}." and no further action taken.\n\n"; |
|
473
|
0
|
|
|
|
|
|
exit; |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
} |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# method to print a help screen, based on map above |
|
478
|
|
|
|
|
|
|
sub print_help_text { |
|
479
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
# start with intro |
|
482
|
0
|
|
|
|
|
|
print qq{ |
|
483
|
|
|
|
|
|
|
OmniTool Installer: Retrieves and installs the OmniTool Web Framework onto this system. |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Usage: omnitool_installer [OPTIONS] |
|
486
|
|
|
|
|
|
|
Must provide either a config_file or all options, where options are: |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Git Repo for OmniTool: https://github.com/ericschernoff/omnitool |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
OmniTool Website: http://www.omnitool.org |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Requires Ubuntu 16.04+ (or distro based on 16.04), as well as Perl 5.22+ and Git. |
|
493
|
|
|
|
|
|
|
Also requires MySQL 5.7+ or MariaDB 10.3+ here or close by, and it's no fun without |
|
494
|
|
|
|
|
|
|
Apache installed. |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Before running, please install the following packages: |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
zlib1g-dev libssl-dev install build-essential cpanminus perl-doc |
|
499
|
|
|
|
|
|
|
mysql-server libmysqlclient-dev apache2 |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Then, you will need to enable a few Apache modules: |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
a2enmod proxy ssl headers proxy_http rewrite |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
}; |
|
506
|
0
|
|
|
|
|
|
foreach my $option_key (@{ $self->{option_keys} }) { |
|
|
0
|
|
|
|
|
|
|
|
507
|
0
|
|
|
|
|
|
print '--'.$option_key.' '; |
|
508
|
0
|
0
|
|
|
|
|
if ($self->{options_map}{$option_key}[1]) { |
|
509
|
0
|
|
|
|
|
|
print $self->{options_map}{$option_key}[0].': [Default: '.$self->{options_map}{$option_key}[1].']'; |
|
510
|
|
|
|
|
|
|
} else { |
|
511
|
0
|
|
|
|
|
|
print $self->{options_map}{$option_key}[0].': [No Default]'; |
|
512
|
|
|
|
|
|
|
} |
|
513
|
0
|
|
|
|
|
|
print "\n\n"; |
|
514
|
|
|
|
|
|
|
} |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
# done here |
|
517
|
0
|
|
|
|
|
|
exit; |
|
518
|
|
|
|
|
|
|
} |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
1; |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
__END__ |
|
523
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=encoding utf-8 |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head1 NAME |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
omnitool::installer - Install the OmniTool Web Application Framework |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Provides the 'omnitool_installer' script to install OmniTool on your system. |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head1 END-OF-LIFE / DEPRECATION |
|
533
|
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
This system is no longer under active development. OmniTool should not be used for any new projects. |
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
This repo contains some interesting ideas and perhaps a few solutions, so this repo will remain online for archive purposes. If you are interested in taking over this project, please let me know. |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
# To provide installation details interactively then install: |
|
541
|
|
|
|
|
|
|
omnitool_installer |
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
# Safer approach: provide the installation details interactively and save config file: |
|
544
|
|
|
|
|
|
|
omnitool_installer --save-config-file-only=/some/path/ot_install.config |
|
545
|
|
|
|
|
|
|
# then run |
|
546
|
|
|
|
|
|
|
omnitool_installer --config-file=/some/path/ot_install.config |
|
547
|
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
# Be sure to delete/protect ot_install.config |
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
# To see help and exit: |
|
551
|
|
|
|
|
|
|
omnitool_installer --help |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
OmniTool allows you to build web application suites very quickly and with minimal code. It is |
|
556
|
|
|
|
|
|
|
designed to simplify and speed up the development process, reducing code requirements to only |
|
557
|
|
|
|
|
|
|
the specific features and logic for the target application. The resulting applications are |
|
558
|
|
|
|
|
|
|
mobile-responsive and API-enabled with no extra work by the developers. |
|
559
|
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
For lots more information on how this works, including demos, examples, and lots of documentation, |
|
561
|
|
|
|
|
|
|
please visit L<http://www.omnitool.org/> |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
The GitHub Repo for OmniTool is L<https://github.com/ericschernoff/omnitool> |
|
564
|
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=head2 PREREQUISITES |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
OmniTool has been developed and tested with the following base components: |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
=over |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=item - Ubuntu 16.04 Server |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=item - Perl 5.22 |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=item - Git 2.10 |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
=item - MySQL 5.7 or MariaDB 10.3 (at least the client libraries if separate DB server) |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=item - Apache 2.4 |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
=back |
|
582
|
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
You can very likely make it work on FreeBSD 10.1+ or a recent release of RHEL, Fedora, or CentOS. I am not able |
|
584
|
|
|
|
|
|
|
to provide detailed instructions on each of these -- volunteers would be very welcome! |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Prior to installation, the following packages will need to be installed via 'sudo apt install': |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=over |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=item - build-essential |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
=item - zlib1g-dev |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
=item - libssl-dev |
|
595
|
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
=item - cpanminus |
|
597
|
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=item - perl-doc |
|
599
|
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=item - mysql-server |
|
601
|
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
=item - libmysqlclient-dev |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
=item - apache2 |
|
605
|
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
=back |
|
607
|
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
Then, you will need to enable a few Apache modules: |
|
609
|
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
=over |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
sudo a2enmod proxy ssl headers proxy_http rewrite |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=back |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
Again, these are Ubuntu 16.04 commands. I am quite sure you can make this work with the other BSD, Linux |
|
617
|
|
|
|
|
|
|
flavors, as well as with Nginix instead of Apache if you prefer. |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
=head2 ACKNOWLEDGEMENTS |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
I am very appreciative to my employer, Cisco Systems, Inc., for allowing this software to be |
|
622
|
|
|
|
|
|
|
released to the community as open source. (IP Central ID: 153330984). |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
I am also grateful to Mohsen Hosseini for allowing me to include his most excellent Ace |
|
625
|
|
|
|
|
|
|
Admin as part of this software. |
|
626
|
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
=head1 LICENSE |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
MIT License |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Copyright (c) 2017 Eric Chernoff |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
634
|
|
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal |
|
635
|
|
|
|
|
|
|
in the Software without restriction, including without limitation the rights |
|
636
|
|
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
637
|
|
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is |
|
638
|
|
|
|
|
|
|
furnished to do so, subject to the following conditions: |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all |
|
641
|
|
|
|
|
|
|
copies or substantial portions of the Software. |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
644
|
|
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
645
|
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
646
|
|
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
647
|
|
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
648
|
|
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
649
|
|
|
|
|
|
|
SOFTWARE. |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=head1 AUTHOR |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
Eric Chernoff E<lt>ericschernoff@gmail.comE<gt> |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=cut |
|
656
|
|
|
|
|
|
|
|