diff options
Diffstat (limited to 'Bugzilla/Install')
-rw-r--r-- | Bugzilla/Install/DB.pm | 126 | ||||
-rw-r--r-- | Bugzilla/Install/Filesystem.pm | 68 | ||||
-rw-r--r-- | Bugzilla/Install/Requirements.pm | 27 | ||||
-rw-r--r-- | Bugzilla/Install/Util.pm | 6 |
4 files changed, 212 insertions, 15 deletions
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index 3ac83775a..4fb1f1c83 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -261,7 +261,7 @@ sub update_table_definitions { $dbh->bz_add_column("bugs", "cclist_accessible", {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); - $dbh->bz_add_column("bugs_activity", "attach_id", {TYPE => 'INT3'}); + $dbh->bz_add_column("bugs_activity", "attach_id", {TYPE => 'INT5'}); _delete_logincookies_cryptpassword_and_handle_invalid_cookies(); @@ -398,7 +398,7 @@ sub update_table_definitions { "WHERE initialqacontact = 0"); _migrate_email_prefs_to_new_table(); - _initialize_dependency_tree_changes_email_pref(); + _initialize_new_email_prefs(); _change_all_mysql_booleans_to_tinyint(); # make classification_id field type be consistent with DB:Schema @@ -455,7 +455,7 @@ sub update_table_definitions { # 2005-12-07 altlst@sonic.net -- Bug 225221 $dbh->bz_add_column('longdescs', 'comment_id', - {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); _stop_storing_inactive_flags(); _change_short_desc_from_mediumtext_to_varchar(); @@ -607,7 +607,7 @@ sub update_table_definitions { _fix_series_creator_fk(); # 2009-11-14 dkl@redhat.com - Bug 310450 - $dbh->bz_add_column('bugs_activity', 'comment_id', {TYPE => 'INT3'}); + $dbh->bz_add_column('bugs_activity', 'comment_id', {TYPE => 'INT4'}); # 2010-04-07 LpSolit@gmail.com - Bug 69621 $dbh->bz_drop_column('bugs', 'keywords'); @@ -660,6 +660,9 @@ sub update_table_definitions { # 2011-10-11 miketosh - Bug 690173 _on_delete_set_null_for_audit_log_userid(); + # 2011-11-01 glob@mozilla.com - Bug 240437 + $dbh->bz_add_column('profiles', 'last_seen_date', {TYPE => 'DATETIME'}); + # 2011-11-28 dkl@mozilla.com - Bug 685611 _fix_notnull_defaults(); @@ -669,6 +672,45 @@ sub update_table_definitions { $dbh->bz_add_index('profile_search', 'profile_search_user_id_idx', [qw(user_id)]); } + # 2012-06-06 dkl@mozilla.com - Bug 762288 + $dbh->bz_alter_column('bugs_activity', 'removed', + { TYPE => 'varchar(255)' }); + $dbh->bz_add_index('bugs_activity', 'bugs_activity_removed_idx', ['removed']); + + # 2012-06-13 dkl@mozilla.com - Bug 764457 + $dbh->bz_add_column('bugs_activity', 'id', + {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + # 2012-06-13 dkl@mozilla.com - Bug 764466 + $dbh->bz_add_column('profiles_activity', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + # 2012-07-24 dkl@mozilla.com - Bug 776972 + # BMO - we change this to BIGSERIAL further down + #$dbh->bz_alter_column('bugs_activity', 'id', + # {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + + # 2012-07-24 dkl@mozilla.com - Bug 776982 + _fix_longdescs_primary_key(); + + # 2012-08-02 dkl@mozilla.com - Bug 756953 + _fix_dependencies_dupes(); + + # 2013-02-04 dkl@mozilla.com - Bug 824346 + _fix_flagclusions_indexes(); + + # 2012-04-15 Frank@Frank-Becker.de - Bug 740536 + $dbh->bz_add_index('audit_log', 'audit_log_class_idx', ['class', 'at_time']); + + # 2013-08-16 glob@mozilla.com - Bug 905925 + $dbh->bz_add_index('attachments', 'attachments_ispatch_idx', ['ispatch']); + + # 2014-06-09 dylan@mozilla.com - Bug 1022923 + $dbh->bz_add_index('bug_user_last_visit', + 'bug_user_last_visit_last_visit_ts_idx', + ['last_visit_ts']); + ################################################################ # New --TABLE-- changes should go *** A B O V E *** this point # ################################################################ @@ -2396,13 +2438,16 @@ sub _migrate_email_prefs_to_new_table { } } -sub _initialize_dependency_tree_changes_email_pref { +sub _initialize_new_email_prefs { my $dbh = Bugzilla->dbh; # Check for any "new" email settings that wouldn't have been ported over # during the block above. Since these settings would have otherwise # fallen under EVT_OTHER, we'll just clone those settings. That way if # folks have already disabled all of that mail, there won't be any change. - my %events = ("Dependency Tree Changes" => EVT_DEPEND_BLOCK); + my %events = ( + "Dependency Tree Changes" => EVT_DEPEND_BLOCK, + "Product/Component Changes" => EVT_COMPONENT, + ); foreach my $desc (keys %events) { my $event = $events{$desc}; @@ -3220,6 +3265,11 @@ sub _populate_bugs_fulltext { print "Populating bugs_fulltext with $num_bugs entries..."; print " (this can take a long time.)\n"; } + + # As recommended by Monty Widenius for GNOME's upgrade. + # mkanat and justdave concur it'll be helpful for bmo, too. + $dbh->do('SET SESSION myisam_sort_buffer_size = 3221225472'); + my $newline = $dbh->quote("\n"); $dbh->do( qq{$command INTO bugs_fulltext (bug_id, short_desc, comments, @@ -3682,6 +3732,70 @@ sub _fix_notnull_defaults { } } +sub _fix_longdescs_primary_key { + my $dbh = Bugzilla->dbh; + if ($dbh->bz_column_info('longdescs', 'comment_id')->{TYPE} ne 'INTSERIAL') { + $dbh->bz_drop_related_fks('longdescs', 'comment_id'); + $dbh->bz_alter_column('bugs_activity', 'comment_id', {TYPE => 'INT4'}); + $dbh->bz_alter_column('longdescs', 'comment_id', + {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + } +} + +sub _fix_dependencies_dupes { + my $dbh = Bugzilla->dbh; + my $blocked_idx = $dbh->bz_index_info('dependencies', 'dependencies_blocked_idx'); + if ($blocked_idx && scalar @{$blocked_idx->{'FIELDS'}} < 2) { + # Remove duplicated entries + my $dupes = $dbh->selectall_arrayref(" + SELECT blocked, dependson, COUNT(*) AS count + FROM dependencies " . + $dbh->sql_group_by('blocked, dependson') . " + HAVING COUNT(*) > 1", + { Slice => {} }); + print "Removing duplicated entries from the 'dependencies' table...\n" if @$dupes; + foreach my $dupe (@$dupes) { + $dbh->do("DELETE FROM dependencies + WHERE blocked = ? AND dependson = ?", + undef, $dupe->{blocked}, $dupe->{dependson}); + $dbh->do("INSERT INTO dependencies (blocked, dependson) VALUES (?, ?)", + undef, $dupe->{blocked}, $dupe->{dependson}); + } + $dbh->bz_drop_index('dependencies', 'dependencies_blocked_idx'); + $dbh->bz_add_index('dependencies', 'dependencies_blocked_idx', + { FIELDS => [qw(blocked dependson)], TYPE => 'UNIQUE' }); + } +} + +sub _fix_flagclusions_indexes { + my $dbh = Bugzilla->dbh; + foreach my $table ('flaginclusions', 'flagexclusions') { + my $index = $table . '_type_id_idx'; + my $idx_info = $dbh->bz_index_info($table, $index); + if ($idx_info && $idx_info->{'TYPE'} ne 'UNIQUE') { + # Remove duplicated entries + my $dupes = $dbh->selectall_arrayref(" + SELECT type_id, product_id, component_id, COUNT(*) AS count + FROM $table " . + $dbh->sql_group_by('type_id, product_id, component_id') . " + HAVING COUNT(*) > 1", + { Slice => {} }); + print "Removing duplicated entries from the '$table' table...\n" if @$dupes; + foreach my $dupe (@$dupes) { + $dbh->do("DELETE FROM $table + WHERE type_id = ? AND product_id = ? AND component_id = ?", + undef, $dupe->{type_id}, $dupe->{product_id}, $dupe->{component_id}); + $dbh->do("INSERT INTO $table (type_id, product_id, component_id) VALUES (?, ?, ?)", + undef, $dupe->{type_id}, $dupe->{product_id}, $dupe->{component_id}); + } + $dbh->bz_drop_index($table, $index); + $dbh->bz_add_index($table, $index, + { FIELDS => [qw(type_id product_id component_id)], + TYPE => 'UNIQUE' }); + } + } +} + 1; __END__ diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index c5215ecfa..621ece803 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -38,6 +38,7 @@ use File::Find; use File::Path; use File::Basename; use File::Copy qw(move); +use File::Slurp; use IO::File; use POSIX (); @@ -125,6 +126,7 @@ sub FILESYSTEM { my $localconfig = bz_locations()->{'localconfig'}; my $template_cache = bz_locations()->{'template_cache'}; my $graphsdir = bz_locations()->{'graphsdir'}; + my $assetsdir = bz_locations()->{'assetsdir'}; # We want to set the permissions the same for all localconfig files # across all PROJECTs, so we do something special with $localconfig, @@ -159,7 +161,10 @@ sub FILESYSTEM { 'runtests.pl' => { perms => OWNER_EXECUTE }, 'jobqueue.pl' => { perms => OWNER_EXECUTE }, 'migrate.pl' => { perms => OWNER_EXECUTE }, + 'sentry.pl' => { perms => WS_EXECUTE }, + 'metrics.pl' => { perms => WS_EXECUTE }, 'install-module.pl' => { perms => OWNER_EXECUTE }, + 'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE }, 'Bugzilla.pm' => { perms => CGI_READ }, "$localconfig*" => { perms => CGI_READ }, @@ -170,6 +175,7 @@ sub FILESYSTEM { 'contrib/README' => { perms => OWNER_WRITE }, 'contrib/*/README' => { perms => OWNER_WRITE }, + 'contrib/sendunsentbugmail.pl' => { perms => WS_EXECUTE }, 'docs/bugzilla.ent' => { perms => OWNER_WRITE }, 'docs/makedocs.pl' => { perms => OWNER_EXECUTE }, 'docs/style.css' => { perms => WS_SERVE }, @@ -179,13 +185,16 @@ sub FILESYSTEM { "$datadir/old-params.txt" => { perms => OWNER_WRITE }, "$extensionsdir/create.pl" => { perms => OWNER_EXECUTE }, "$extensionsdir/*/*.pl" => { perms => WS_EXECUTE }, + "$extensionsdir/*/bin/*" => { perms => WS_EXECUTE }, ); # Directories that we want to set the perms on, but not # recurse through. These are directories we didn't create # in checkesetup.pl. + # + # Purpose of BMO change: unknown. my %non_recurse_dirs = ( - '.' => DIR_WS_SERVE, + '.' => 0755, docs => DIR_WS_SERVE, ); @@ -205,6 +214,8 @@ sub FILESYSTEM { dirs => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE }, "$datadir/db" => { files => CGI_WRITE, dirs => DIR_CGI_WRITE }, + $assetsdir => { files => WS_SERVE, + dirs => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE }, # Readable directories "$datadir/mining" => { files => CGI_READ, @@ -243,10 +254,13 @@ sub FILESYSTEM { dirs => DIR_WS_SERVE }, "$extensionsdir/*/web" => { files => WS_SERVE, dirs => DIR_WS_SERVE }, - + + # Purpose: allow webserver to read .bzr so we execute bzr commands + # in backticks and look at the result over the web. Used to show + # bzr history. + '.bzr' => { files => WS_SERVE, + dirs => DIR_WS_SERVE }, # Directories only for the owner, not for the webserver. - '.bzr' => { files => OWNER_WRITE, - dirs => DIR_OWNER_WRITE }, t => { files => OWNER_WRITE, dirs => DIR_OWNER_WRITE }, xt => { files => OWNER_WRITE, @@ -264,7 +278,8 @@ sub FILESYSTEM { # The name of each directory that we should actually *create*, # pointing at its default permissions. my %create_dirs = ( - # This is DIR_ALSO_WS_SERVE because it contains $webdotdir. + # This is DIR_ALSO_WS_SERVE because it contains $webdotdir and + # $assetsdir. $datadir => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE, # Directories that are read-only for cgi scripts "$datadir/mining" => DIR_CGI_READ, @@ -275,6 +290,7 @@ sub FILESYSTEM { $attachdir => DIR_CGI_WRITE, $graphsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE, $webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE, + $assetsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE, # Directories that contain content served directly by the web server. "$skinsdir/custom" => DIR_WS_SERVE, "$skinsdir/contrib" => DIR_WS_SERVE, @@ -364,6 +380,18 @@ EOT Deny from all EOT }, + + "$assetsdir/.htaccess" => { perms => WS_SERVE, contents => <<EOT +# Allow access to .css files +<FilesMatch \\.(css|js)\$> + Allow from all +</FilesMatch> + +# And no directory listings, either. +Deny from all +EOT + }, + ); Bugzilla::Hook::process('install_filesystem', { @@ -398,6 +426,7 @@ sub update_filesystem { my $datadir = bz_locations->{'datadir'}; my $graphsdir = bz_locations->{'graphsdir'}; + my $assetsdir = bz_locations->{'assetsdir'}; # If the graphs/ directory doesn't exist, we're upgrading from # a version old enough that we need to update the $datadir/mining # format. @@ -431,6 +460,13 @@ sub update_filesystem { _rename_file($oldparamsfile, "$datadir/$oldparamsfile"); } + # Remove old assets htaccess file to force recreation with correct values. + if (-e "$assetsdir/.htaccess") { + if (read_file("$assetsdir/.htaccess") =~ /<FilesMatch \\\.css\$>/) { + unlink("$assetsdir/.htaccess"); + } + } + _create_files(%files); if ($params->{index_html}) { _create_files(%{$fs->{index_html}}); @@ -474,6 +510,7 @@ EOT _remove_empty_css_files(); _convert_single_file_skins(); + _remove_dynamic_assets(); } sub _remove_empty_css_files { @@ -518,6 +555,27 @@ sub _convert_single_file_skins { } } +# delete all automatically generated css/js files to force recreation at the +# next request. +sub _remove_dynamic_assets { + my @files = ( + glob(bz_locations()->{assetsdir} . '/*.css'), + glob(bz_locations()->{assetsdir} . '/*.js'), + ); + foreach my $file (@files) { + unlink($file); + } + + # remove old skins/assets directory + my $old_path = bz_locations()->{skinsdir} . '/assets'; + if (-d $old_path) { + foreach my $file (glob("$old_path/*.css")) { + unlink($file); + } + rmdir($old_path); + } +} + sub create_htaccess { _create_files(%{FILESYSTEM()->{htaccess}}); diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm index 2e67457ab..1c9c91345 100644 --- a/Bugzilla/Install/Requirements.pm +++ b/Bugzilla/Install/Requirements.pm @@ -288,7 +288,7 @@ sub OPTIONAL_MODULES { package => 'JSON-RPC', module => 'JSON::RPC', version => 0, - feature => ['jsonrpc'], + feature => ['jsonrpc', 'rest'], }, { package => 'JSON-XS', @@ -301,7 +301,7 @@ sub OPTIONAL_MODULES { package => 'Test-Taint', module => 'Test::Taint', version => 0, - feature => ['jsonrpc', 'xmlrpc'], + feature => ['jsonrpc', 'xmlrpc', 'rest'], }, { # We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber. @@ -372,6 +372,27 @@ sub OPTIONAL_MODULES { version => '0.96', feature => ['mod_perl'], }, + + # memcached + { + package => 'URI-Escape', + module => 'URI::Escape', + version => 0, + feature => ['memcached'], + }, + { + package => 'Cache-Memcached', + module => 'Cache::Memcached', + version => '0', + feature => ['memcached'], + }, + + # BMO - metrics + { + package => 'ElasticSearch', + module => 'ElasticSearch', + version => '0', + }, ); my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES'); @@ -385,6 +406,7 @@ use constant FEATURE_FILES => ( jsonrpc => ['Bugzilla/WebService/Server/JSONRPC.pm', 'jsonrpc.cgi'], xmlrpc => ['Bugzilla/WebService/Server/XMLRPC.pm', 'xmlrpc.cgi', 'Bugzilla/WebService.pm', 'Bugzilla/WebService/*.pm'], + rest => ['Bugzilla/WebService/Server/REST.pm', 'rest.cgi'], moving => ['importxml.pl'], auth_ldap => ['Bugzilla/Auth/Verify/LDAP.pm'], auth_radius => ['Bugzilla/Auth/Verify/RADIUS.pm'], @@ -393,6 +415,7 @@ use constant FEATURE_FILES => ( 'Bugzilla/JobQueue/*', 'jobqueue.pl'], patch_viewer => ['Bugzilla/Attachment/PatchReader.pm'], updates => ['Bugzilla/Update.pm'], + memcached => ['Bugzilla/Memcache.pm'], ); # This implements the REQUIRED_MODULES and OPTIONAL_MODULES stuff diff --git a/Bugzilla/Install/Util.pm b/Bugzilla/Install/Util.pm index bd8942507..5f6c8bceb 100644 --- a/Bugzilla/Install/Util.pm +++ b/Bugzilla/Install/Util.pm @@ -382,7 +382,10 @@ sub include_languages { # Basically, the way this works is that we have a list of languages # that we *want*, and a list of languages that Bugzilla actually - # supports. + # supports. If there is only one language installed, we take it. + my $supported = supported_languages(); + return @$supported if @$supported == 1; + my $wanted; if ($params->{language}) { # We can pass several languages at once as an arrayref @@ -393,7 +396,6 @@ sub include_languages { else { $wanted = _wanted_languages(); } - my $supported = supported_languages(); my $actual = _wanted_to_actual_languages($wanted, $supported); return @$actual; } |