Revision 10
Date:
2010/03/29 11:56:08
Author:
ahitrov@rambler.ru
Revision Log:
The INSTALLER
Files:
Legend:
Added
Removed
Modified
utf8/install/bin/install
1
#!/usr/bin/perl
2
3
##############################################################################
4
# $HeadURL: http://svn.dev.rambler.ru/cndinst/trunk/bin/install $
5
# $Id: install 65 2009-12-18 12:09:37Z abavykin $
6
##############################################################################
7
8
use strict;
9
use File::Spec;
10
use FindBin qw($RealBin);
11
use Getopt::Long;
12
use User::grent;
13
use User::pwent;
14
15
# defaults
16
my $options = {
17
svn_program => (`which svn` =~ /(.*)/)[0],
18
core_repository => ($ENV{CORE_REPOSITORY} || 'http://developers.rambler.ru/svn/contenido/utf8/core'),
19
server => (`hostname` =~ /(.*)/)[0],
20
httpd_port => ($ENV{HTTPD_PORT} || 0),
21
db_type => 'R',
22
backups => '/spool/backups',
23
crosslinks => '/spool/crosslinks',
24
sessions => '/spool/sessions',
25
};
26
27
my ($force, $help);
28
GetOptions('force' => \$force, 'help' => \$help);
29
30
if ($help) {
31
&usage;
32
exit;
33
}
34
35
my $yes_no = { y => 'YES', n => 'NO' };
36
my $db_types = { N => 'NONE', R => 'REMOTE', S => 'SINGLE' };
37
38
# begin
39
my ($user, $group, $umask) = (getpwuid($>), getgrgid($)), sprintf('%03o', umask));
40
my $destdir = $ENV{CNDINST_DESTDIR} || undef;
41
(my $home = $user->dir) =~ s/\/+$//;
42
43
load_conf($home, $options);
44
45
START:
46
while ($umask !~ /^\d0\d$/) {
47
my $a = user_prompt("Current umask ($umask) isn't group friendly. Are you sure?", default => 'n');
48
last if $a eq 'y';
49
next unless $a eq 'n';
50
print "Correct umask and try again!\n";
51
exit 0;
52
}
53
54
print sprintf (<<'EOM'
55
Start installation as:
56
User: %s [%d]
57
Group: %s [%d]
58
Home: %s
59
Shell: %s
60
Umask: %s
61
EOM
62
, $user->name, $user->uid, $group->name, $group->gid, $home, $user->shell, $umask);
63
64
while (1) {
65
my $a = lc(user_prompt('Is it correct?', default => 'y'));
66
last if $a eq 'y';
67
next unless $a eq 'n';
68
print "Bye, see you later!\n";
69
exit 0;
70
}
71
72
while (1) {
73
$destdir = user_prompt('Enter installation directory (absolute path)', default => $destdir ? $destdir : $home."/Contenido", ignore_force=>1);
74
next unless $destdir;
75
76
$destdir = File::Spec->canonpath($destdir);
77
$destdir =~ s/\/*$//;
78
79
if (-d $destdir) {
80
unless (is_dir_empty($destdir)) {
81
print "Directory exists and non-empty!\n";
82
undef $destdir;
83
next;
84
}
85
unless (-w $destdir) {
86
print "Directory exists, but you have no write permissions in it!\n";
87
undef $destdir;
88
next;
89
}
90
} else {
91
my @dirs = split /\/+/, $destdir;
92
my $pdir = '/'.join('/', @dirs[0..$#dirs-1]);
93
unless (-w $pdir) {
94
print "You have no permissions to create directory!\n";
95
undef $destdir;
96
next;
97
}
98
}
99
last;
100
}
101
102
while (1) {
103
my $a = lc(user_prompt('Which is svn executable?', default => $options->{svn_program}));
104
unless ($a && -x $a) {
105
print "There is no svn executable!\n";
106
next;
107
}
108
$options->{svn_program} = $a;
109
save_conf($home, $options);
110
last;
111
}
112
113
while (1) {
114
my $a = user_prompt('Which Contenido repository will be checked out?', default => $options->{core_repository});
115
$a =~ s/\/$//;
116
print "Contacting repository... ";
117
next if system("$options->{svn_program} ls $a >/dev/null");
118
print "success\n";
119
$options->{core_repository} = $a;
120
save_conf($home, $options);
121
last;
122
}
123
124
while (1) {
125
my $a = user_prompt('Enter server name', default => $options->{server});
126
next unless $a =~ /^[\w\-\+\.]+$/i;
127
$options->{server} = $a;
128
save_conf($home, $options);
129
last;
130
}
131
132
while (1) {
133
my $a = user_prompt('Enter HTTP port', default => $options->{httpd_port}, ignore_force=>1);
134
next unless $a =~ /^(\d)+$/i;
135
next if int($a)<1024 || int($a)>65535;
136
my %occupied = map {chomp; s/.*?(\d+)$/$1/; $_ => 1} `netstat -na | grep LISTEN | awk '{print \$4}'`;
137
if ($occupied{$a}) {
138
my $ao;
139
while (1) {
140
$ao = lc(user_prompt('Port seems busy. Are you sure?', default => 'n'));
141
last if $ao eq 'y';
142
next unless $ao eq 'n';
143
last;
144
}
145
next unless $ao eq 'y';
146
}
147
$options->{httpd_port} = $a;
148
save_conf($home, $options);
149
last;
150
}
151
152
while (1) {
153
my $a = user_prompt('Select database type: [N]ONE [R]EMOTE [S]INGLE', default => $options->{db_type}, ignore_force=>1);
154
next unless $a =~ /^[NRS]$/i;
155
$options->{db_type} = uc($a);
156
save_conf($home, $options);
157
last;
158
}
159
160
while (1) {
161
my $a = user_prompt('Enter backups directory', default => $options->{backups});
162
next unless $a;
163
$options->{backups} = $a;
164
save_conf($home, $options);
165
last;
166
}
167
168
while (1) {
169
my $a = user_prompt('Enter crosslinks directory', default => $options->{crosslinks});
170
next unless $a;
171
$options->{crosslinks} = $a;
172
save_conf($home, $options);
173
last;
174
}
175
176
while (1) {
177
my $a = user_prompt('Enter sessions directory', default => $options->{sessions});
178
next unless $a;
179
$options->{sessions} = $a;
180
save_conf($home, $options);
181
last;
182
}
183
184
185
186
print <<EOM
187
188
189
Summary:
190
Installation directory: $destdir
191
Executable svn: $options->{svn_program}
192
Contenido repository: $options->{core_repository}
193
Server name: $options->{server}
194
HTTP port: $options->{httpd_port}
195
Database type: $db_types->{$options->{db_type}}
196
Backups directory: $options->{backups}
197
Crosslinks directory: $options->{crosslinks}
198
Sessions directory: $options->{sessions}
199
EOM
200
;
201
202
while (1) {
203
my $a = lc(user_prompt('Is it correct?', default => 'y'));
204
last if $a eq 'y';
205
next unless $a eq 'n';
206
print "\n\nRestarting config procedure\n\n\n";
207
goto START;
208
}
209
210
print "\nGreat, start installation!\n\n";
211
212
print "Creating installation directory...\n";
213
mkdir $destdir, 0775 or die "Can't mkdir: $destdir - $!" unless -d $destdir;
214
215
print "Creating installation layout...\n";
216
system("cp -R $RealBin/../skel/* $destdir/") and die "Can't copy: skel - $!";
217
system("find $destdir -depth -type d -name .svn -exec rm -Rf {} \\;") and die "Can't clean - $!";
218
system("find $destdir -depth \\! -perm +20 -exec chmod g+w {} \\;") and die "Can't chmod - $!";
219
unlink "$destdir/config.mk.proto" or die $!;
220
221
print "Checking out Contenido core...\n";
222
system("$options->{svn_program} co $options->{core_repository} $destdir/src/core/") and
223
die <<EOM
224
225
****************************************************************
226
Fatal error occured, please resolve problem by hands.
227
Don't forget about your installation directory: $destdir
228
****************************************************************
229
230
EOM
231
;
232
print "done\n";
233
234
print "Creating installation config.mk...";
235
my $rewrites = {
236
OWNER => $user->name,
237
ROOT_DIR => $destdir,
238
SERVER => $options->{server},
239
HTTPD_PORT => $options->{httpd_port},
240
DB_TYPE => $db_types->{$options->{db_type}},
241
BACKUPS => $options->{backups},
242
CROSSLINKS => $options->{crosslinks},
243
SESSIONS => $options->{sessions},
244
};
245
open PROTO, "< $RealBin/../skel/config.mk.proto" or die "Can't read: config.mk.proto - $!";
246
open MK, "> $destdir/config.mk" or die "Can't create: config.mk - $!";
247
print MK @{ rewrite([<PROTO>], $rewrites) };
248
close MK;
249
close PROTO;
250
print " done\n";
251
252
print <<EOM
253
254
*****************************************************************
255
First step of Contenido installation finished.
256
Now change dir to '$destdir'.
257
Here, you can adjust some build options in 'config.mk' by hands.
258
After all run 'make install' and hope it will be successfull :)
259
*****************************************************************
260
EOM
261
;
262
263
exit 0;
264
265
266
### utils
267
268
sub user_prompt {
269
my ($prompt, %opts) = @_;
270
271
print $prompt.(exists $opts{default} ? " [$opts{default}]" : "").": ";
272
#if ($force && $opts{default} && !$opts{ignore_force}) {
273
if ($force && $opts{default}) {
274
print "[forced default answer]\n";
275
#print "$opts{default} [forced answer]\n";
276
sleep 1;
277
return $opts{default};
278
}
279
my $answer = <>;
280
chomp $answer;
281
return $answer ? $answer : $opts{default};
282
}
283
284
sub is_dir_empty {
285
my $dir = shift;
286
287
opendir D, $dir;
288
while ($_ = readdir D) {
289
next if $_ eq '.' || $_ eq '..';
290
return 0;
291
}
292
closedir D;
293
294
return 1;
295
}
296
297
sub load_conf {
298
my ($home, $options) = @_;
299
300
return save_conf($home, $options) unless -f "$home/.cndinst/install.conf";
301
302
open CONF, "< $home/.cndinst/install.conf" or die "Can't read: $home/.cndinst/install.conf - $!";
303
while (<CONF>) {
304
chomp;
305
next if /^\s*#/;
306
next unless /^\s*([^\s]+)\s*=\s*([^\s]+)/;
307
next unless exists $options->{$1};
308
$options->{$1} = $2;
309
}
310
close CONF;
311
return $options;
312
}
313
314
sub save_conf {
315
my ($home, $options) = @_;
316
317
mkdir "$home/.cndinst", 0775 or die "Can't mkdir: $home/.cndinst - $!" unless -d $home.'/.cndinst';
318
319
open CONF, "> $home/.cndinst/install.conf" or die "Can't create: $home/.cndinst/install.conf - $!";
320
print CONF "# Contenido installer config file\n\n";
321
printf CONF "%-20s = %s\n", $_, $options->{$_} for sort keys %{$options};
322
close CONF;
323
}
324
325
sub rewrite {
326
my ($lines, $rewrites) = @_;
327
s/\@([A-Z0-9\_]+)\@/$rewrites->{$1}/ms for @{$lines};
328
return $lines;
329
}
330
331
sub usage {
332
print <<EOM;
333
Usage:
334
$FindBin::Script options
335
336
Options:
337
-h, --help Print this message
338
-f, --force Force mode (automatically apply default answers
339
on none-critical questions)
340
EOM
341
}
utf8/install/skel/config.mk.proto
1
##############################################################################
2
# $HeadURL: http://svn.dev.rambler.ru/cndinst/trunk/skel/config.mk.proto $
3
# $Id: config.mk.proto 61 2009-11-13 14:47:29Z phoinix $
4
###############################################################################
5
6
# Main
7
OWNER = @OWNER@
8
ROOT_DIR = @ROOT_DIR@
9
CONTENIDO_VERSION = 7
10
11
# HTTP
12
HTTPD_PORT = @HTTPD_PORT@
13
SERVER = @SERVER@
14
HTTPD_SERVER = ${SERVER}:${HTTPD_PORT}
15
SERVER_ADMIN = ${OWNER}
16
17
# Database
18
DB_TYPE ?= @DB_TYPE@
19
#PGSQL_LOGGING = YES
20
21
# External directories
22
BACKUPS = @BACKUPS@
23
CROSSLINKS = @CROSSLINKS@
24
SESSIONS = @SESSIONS@
25
26
# Reloading
27
STATIC_SOURCE_ENABLE = YES
28
29
# Error handling
30
ERROR_MODE = fatal
31
32
# Debug & profiling
33
# Default DEBUG_FORMAT = %d %C:%L (%P) [%l]: "%m"%n
34
# %d - date (format [mday/mon/year hour:min:sec])
35
# %P - current process ID
36
# %C - name of package caused this log
37
# %L - code line in %C
38
# %l - log level
39
# %m - log text
40
# %n - "\n"
41
# Debug levels: [debug info notice warning error critical alert emergency]
42
DEBUG = NO
43
DEBUG_FORMAT ?=
44
DEBUG_MIN_LEVEL ?=
45
DEBUG_MAX_LEVEL ?=
46
DEBUG_STACK_TRACE = NO
47
DEBUG_SQL = NO
48
DEBUG_CORE = NO
49
DEBUG_WORKTIME = NO
50
PROFILING = NO
51
PROFILING_DBI = NO
52
53
# Tunable apache settings
54
# (see src/core/config.mk for default values)
55
#MIN_SPARE_SERVERS ?=
56
#MAX_SPARE_SERVERS ?=
57
#START_SERVERS ?=
58
#MAX_CLIENTS ?=
59
#MAX_REQUESTS_PER_CHILD ?=
60
61
# Development ('/src' instead '/usr')
62
# also flag for use test database/memcached etc
63
# also can be accessed via $state->is_dev_server or $state->development
64
DEVELOPMENT = NO
65
66
# Default repository
67
SVN_REPOSITORY ?= http://developers.rambler.ru/svn/
68
69
# Current project
70
PROJECT ?=
utf8/install/skel/GNUmakefile
1
##############################################################################
2
# $HeadURL: http://svn.dev.rambler.ru/cndinst/trunk/skel/GNUmakefile $
3
# $Id: GNUmakefile 59 2007-07-13 09:42:07Z lonerr $
4
###############################################################################
5
6
include config.mk
7
8
LOG = var/log/messages
9
10
.DEFAULT:
11
@echo -e "\n\n##############################" >> ${LOG} \
12
&& echo "Target: $@" >> ${LOG} \
13
&& echo "Date: "`date` >> ${LOG} \
14
&& echo "##############################" >> ${LOG} \
15
&& cd ./src/core \
16
&& unset MAKEFLAGS \
17
&& unset MFLAGS \
18
&& unset MAKELEVEL \
19
&& ${MAKE} $@
utf8/install/skel/Makefile
1
##############################################################################
2
# $HeadURL: http://svn.dev.rambler.ru/cndinst/trunk/skel/Makefile $
3
# $Id: Makefile 46 2006-06-06 12:32:29Z lonerr $
4
###############################################################################
5
6
.DEFAULT:
7
@gmake ${.TARGET}
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.