summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Install
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Install')
-rw-r--r--Bugzilla/Install/DB.pm126
-rw-r--r--Bugzilla/Install/Filesystem.pm68
-rw-r--r--Bugzilla/Install/Requirements.pm27
-rw-r--r--Bugzilla/Install/Util.pm6
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;
}