]>
Commit | Line | Data |
---|---|---|
1 | # BEGIN BPS TAGGED BLOCK {{{ | |
2 | # | |
3 | # COPYRIGHT: | |
4 | # | |
5 | # This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC | |
6 | # <sales@bestpractical.com> | |
7 | # | |
8 | # (Except where explicitly superseded by other copyright notices) | |
9 | # | |
10 | # | |
11 | # LICENSE: | |
12 | # | |
13 | # This work is made available to you under the terms of Version 2 of | |
14 | # the GNU General Public License. A copy of that license should have | |
15 | # been provided with this software, but in any event can be snarfed | |
16 | # from www.gnu.org. | |
17 | # | |
18 | # This work is distributed in the hope that it will be useful, but | |
19 | # WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 | # General Public License for more details. | |
22 | # | |
23 | # You should have received a copy of the GNU General Public License | |
24 | # along with this program; if not, write to the Free Software | |
25 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
26 | # 02110-1301 or visit their web page on the internet at | |
27 | # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. | |
28 | # | |
29 | # | |
30 | # CONTRIBUTION SUBMISSION POLICY: | |
31 | # | |
32 | # (The following paragraph is not intended to limit the rights granted | |
33 | # to you to modify and distribute this software under the terms of | |
34 | # the GNU General Public License and is only of importance to you if | |
35 | # you choose to contribute your changes and enhancements to the | |
36 | # community by submitting them to Best Practical Solutions, LLC.) | |
37 | # | |
38 | # By intentionally submitting any modifications, corrections or | |
39 | # derivatives to this work, or any other work intended for use with | |
40 | # Request Tracker, to Best Practical Solutions, LLC, you confirm that | |
41 | # you are the copyright holder for those contributions and you grant | |
42 | # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, | |
43 | # royalty-free, perpetual, license to use, copy, create derivative | |
44 | # works based on those contributions, and sublicense and distribute | |
45 | # those contributions and any derivatives thereof. | |
46 | # | |
47 | # END BPS TAGGED BLOCK }}} | |
48 | ||
49 | package RT::Installer; | |
50 | use strict; | |
51 | use warnings; | |
52 | ||
53 | use DateTime; | |
54 | ||
55 | require UNIVERSAL::require; | |
56 | my %Meta = ( | |
57 | DatabaseType => { | |
58 | Widget => '/Widgets/Form/Select', | |
59 | WidgetArguments => { | |
60 | Description => 'Database type', # loc | |
61 | Values => [ | |
62 | grep { | |
63 | my $m = 'DBD::' . $_; | |
64 | $m->require ? 1 : 0 | |
65 | } qw/mysql Pg SQLite Oracle/ | |
66 | ], | |
67 | ValuesLabel => { | |
68 | mysql => 'MySQL', #loc | |
69 | Pg => 'PostgreSQL', #loc | |
70 | SQLite => 'SQLite', #loc | |
71 | Oracle => 'Oracle', #loc | |
72 | }, | |
73 | }, | |
74 | }, | |
75 | DatabaseHost => { | |
76 | Widget => '/Widgets/Form/String', | |
77 | WidgetArguments => { | |
78 | Description => 'Database host', #loc | |
79 | Default => 1, | |
80 | DefaultLabel => "Keep 'localhost' if you're not sure. Leave blank to connect locally over a socket", #loc | |
81 | Hints => "The domain name of your database server (like 'db.example.com').", #loc | |
82 | }, | |
83 | }, | |
84 | DatabasePort => { | |
85 | Widget => '/Widgets/Form/Integer', | |
86 | WidgetArguments => { | |
87 | Description => 'Database port', #loc | |
88 | Default => 1, | |
89 | DefaultLabel => | |
90 | 'Leave empty to use the default value for your database', #loc | |
91 | }, | |
92 | }, | |
93 | DatabaseName => { | |
94 | Widget => '/Widgets/Form/String', | |
95 | WidgetArguments => { | |
96 | Description => 'Database name', #loc | |
97 | }, | |
98 | }, | |
99 | DatabaseAdmin => { | |
100 | Widget => '/Widgets/Form/String', | |
101 | WidgetArguments => { | |
102 | Default => 1, | |
103 | Hints => "Leave this alone to use the default dba username for your database type", #loc | |
104 | Description => 'DBA username', # loc | |
105 | DefaultLabel => '', | |
106 | }, | |
107 | }, | |
108 | DatabaseAdminPassword => { | |
109 | Widget => '/Widgets/Form/String', | |
110 | WidgetArguments => { | |
111 | Description => 'DBA password', #loc | |
112 | DefaultLabel => "The DBA's database password",#loc | |
113 | Type => 'password', | |
114 | Hints => "You must provide the dba's password so we can create the RT database and user.", | |
115 | }, | |
116 | }, | |
117 | DatabaseUser => { | |
118 | Widget => '/Widgets/Form/String', | |
119 | WidgetArguments => { | |
120 | Description => 'Database username for RT', #loc | |
121 | Hints => 'RT will connect to the database using this user. It will be created for you.', #loc | |
122 | }, | |
123 | }, | |
124 | DatabasePassword => { | |
125 | Widget => '/Widgets/Form/String', | |
126 | WidgetArguments => { | |
127 | Description => 'Database password for RT', #loc | |
128 | Type => 'password', | |
129 | Hints => 'The password RT should use to connect to the database.', | |
130 | }, | |
131 | }, | |
132 | DatabaseRequireSSL => { | |
133 | Widget => '/Widgets/Form/Boolean', | |
134 | WidgetArguments => { | |
135 | Description => 'Use SSL?', # loc | |
136 | }, | |
137 | }, | |
138 | rtname => { | |
139 | Widget => '/Widgets/Form/String', | |
140 | WidgetArguments => { | |
141 | Description => 'Site name', #loc | |
142 | Hints => 'RT will use this string to uniquely identify your installation and looks for it in the subject of emails to decide what ticket a message applies to. We recommend that you set this to your internet domain. (ex: example.com)' #loc | |
143 | }, | |
144 | }, | |
145 | MinimumPasswordLength => { | |
146 | Widget => '/Widgets/Form/Integer', | |
147 | WidgetArguments => { | |
148 | Description => 'Minimum password length', #loc | |
149 | }, | |
150 | }, | |
151 | Password => { | |
152 | Widget => '/Widgets/Form/String', | |
153 | WidgetArguments => { | |
154 | Description => 'Administrative password', #loc | |
155 | Hints => 'RT will create a user called "root" and set this as their password', #loc | |
156 | Type => 'password', | |
157 | }, | |
158 | }, | |
159 | OwnerEmail => { | |
160 | Widget => '/Widgets/Form/String', | |
161 | WidgetArguments => { | |
162 | Description => 'RT Administrator Email', #loc | |
163 | Hints => "When RT can't handle an email message, where should it be forwarded?", #loc | |
164 | }, | |
165 | }, | |
166 | CommentAddress => { | |
167 | Widget => '/Widgets/Form/String', | |
168 | WidgetArguments => { | |
169 | Description => 'Comment address', #loc | |
170 | Hints => | |
171 | 'the default addresses that will be listed in From: and Reply-To: headers of comment mail.' #loc | |
172 | }, | |
173 | }, | |
174 | CorrespondAddress => { | |
175 | Widget => '/Widgets/Form/String', | |
176 | WidgetArguments => { | |
177 | Description => 'Correspond address', #loc | |
178 | Hints => | |
179 | 'the default addresses that will be listed in From: and Reply-To: headers of correspondence mail.' #loc | |
180 | }, | |
181 | }, | |
182 | SendmailPath => { | |
183 | Widget => '/Widgets/Form/String', | |
184 | WidgetArguments => { | |
185 | Hints => 'Where to find your sendmail binary.', #loc | |
186 | Description => 'Path to sendmail', #loc | |
187 | }, | |
188 | }, | |
189 | Timezone => { | |
190 | Widget => '/Widgets/Form/Select', | |
191 | WidgetArguments => { | |
192 | Description => 'Timezone', #loc | |
193 | Callback => sub { | |
194 | my $ret; | |
195 | $ret->{Values} = ['', DateTime::TimeZone->all_names]; | |
196 | ||
197 | my $dt = DateTime->now; | |
198 | for my $tz ( DateTime::TimeZone->all_names ) { | |
199 | $dt->set_time_zone( $tz ); | |
200 | $ret->{ValuesLabel}{$tz} = | |
201 | $tz . ' ' . $dt->strftime('%z'); | |
202 | } | |
203 | $ret->{ValuesLabel}{''} = 'System Default'; #loc | |
204 | ||
205 | return $ret; | |
206 | }, | |
207 | }, | |
208 | }, | |
209 | WebDomain => { | |
210 | Widget => '/Widgets/Form/String', | |
211 | WidgetArguments => { | |
212 | Description => 'Domain name', #loc | |
213 | Hints => "Don't include http://, just something like 'localhost', 'rt.example.com'", #loc | |
214 | }, | |
215 | }, | |
216 | WebPort => { | |
217 | Widget => '/Widgets/Form/Integer', | |
218 | WidgetArguments => { | |
219 | Description => 'Web port', #loc | |
220 | Hints => 'which port your web server will listen to, e.g. 8080', #loc | |
221 | }, | |
222 | }, | |
223 | ||
224 | ); | |
225 | ||
226 | sub Meta { | |
227 | my $class = shift; | |
228 | my $type = shift; | |
229 | return $Meta{$type} if $type; | |
230 | return \%Meta; | |
231 | } | |
232 | ||
233 | sub CurrentValue { | |
234 | my $class = shift; | |
235 | my $type = shift; | |
236 | $type = $class if !ref $class && $class && $class ne 'RT::Installer'; | |
237 | ||
238 | return undef unless $type; | |
239 | return $RT::Installer | |
240 | && exists $RT::Installer->{InstallConfig}{$type} | |
241 | ? $RT::Installer->{InstallConfig}{$type} | |
242 | : scalar RT->Config->Get($type); | |
243 | } | |
244 | ||
245 | sub CurrentValues { | |
246 | my $class = shift; | |
247 | my @types = @_; | |
248 | push @types, $class if !ref $class && $class && $class ne 'RT::Installer'; | |
249 | ||
250 | return { map { $_ => CurrentValue($_) } @types }; | |
251 | } | |
252 | ||
253 | sub ConfigFile { | |
254 | require File::Spec; | |
255 | return File::Spec->catfile( $RT::EtcPath, 'RT_SiteConfig.pm' ); | |
256 | } | |
257 | ||
258 | sub SaveConfig { | |
259 | my $class = shift; | |
260 | ||
261 | my $file = $class->ConfigFile; | |
262 | ||
263 | my $content; | |
264 | ||
265 | { | |
266 | local $/; | |
267 | open( my $fh, '<', $file ) or die $!; | |
268 | $content = <$fh>; | |
269 | $content =~ s/^\s*1;\s*$//m; | |
270 | } | |
271 | ||
272 | # make organization the same as rtname | |
273 | $RT::Installer->{InstallConfig}{Organization} = | |
274 | $RT::Installer->{InstallConfig}{rtname}; | |
275 | ||
276 | if ( open my $fh, '>', $file ) { | |
277 | for ( keys %{ $RT::Installer->{InstallConfig} } ) { | |
278 | ||
279 | # we don't want to store root's password in config. | |
280 | next if $_ eq 'Password'; | |
281 | ||
282 | $RT::Installer->{InstallConfig}{$_} = '' | |
283 | unless defined $RT::Installer->{InstallConfig}{$_}; | |
284 | ||
285 | # remove obsolete settings we'll add later | |
286 | $content =~ s/^\s* Set \s* \( \s* \$$_ .*$//xm; | |
287 | ||
288 | $content .= "Set( \$$_, '$RT::Installer->{InstallConfig}{$_}' );\n"; | |
289 | } | |
290 | $content .= "1;\n"; | |
291 | print $fh $content; | |
292 | close $fh; | |
293 | ||
294 | return ( 1, "Successfully saved configuration to $file." ); | |
295 | } | |
296 | ||
297 | return ( 0, "Cannot save configuration to $file: $!" ); | |
298 | } | |
299 | ||
300 | =head1 NAME | |
301 | ||
302 | RT::Installer - RT's Installer | |
303 | ||
304 | =head1 SYNOPSYS | |
305 | ||
306 | use RT::Installer; | |
307 | my $meta = RT::Installer->Meta; | |
308 | ||
309 | =head1 DESCRIPTION | |
310 | ||
311 | C<RT::Installer> class provides access to RT Installer Meta | |
312 | ||
313 | =cut | |
314 | ||
315 | RT::Base->_ImportOverlays(); | |
316 | ||
317 | 1; | |
318 |