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 – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.