Merge branch 'stable-2.10'
* stable-2.10: Update version to 2.10 Remove the archetypeRepository property from the mvn archetype:generate Update the Gerrit version in the plugin development documentation Update 2.10 release notes Drop broken Schema migrations Update version to 2.10-rc2 Conflicts: VERSION gerrit-extension-api/pom.xml gerrit-plugin-api/pom.xml gerrit-plugin-archetype/pom.xml gerrit-plugin-gwt-archetype/pom.xml gerrit-plugin-gwtui/pom.xml gerrit-plugin-js-archetype/pom.xml gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_52.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_53.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_57.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_59.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_63.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_64.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_65.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_67.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_68.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_69.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_71.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_73.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_74.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_77.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_81.java gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_82.java gerrit-war/pom.xml Change-Id: I44b2635bfb6b4011cc10f1fe29db5e6e734a9e3c
This commit is contained in:
commit
b67addf513
@ -36,8 +36,7 @@ plugin project.
|
||||
----
|
||||
mvn archetype:generate -DarchetypeGroupId=com.google.gerrit \
|
||||
-DarchetypeArtifactId=gerrit-plugin-archetype \
|
||||
-DarchetypeVersion=2.10-SNAPSHOT \
|
||||
-DarchetypeRepository=https://oss.sonatype.org/content/repositories/snapshots/ \
|
||||
-DarchetypeVersion=2.10 \
|
||||
-DgroupId=com.googlesource.gerrit.plugins.testplugin \
|
||||
-DartifactId=testplugin
|
||||
----
|
||||
|
@ -21,7 +21,6 @@ Important Notes
|
||||
*WARNING:* This release contains schema changes. To upgrade:
|
||||
----
|
||||
java -jar gerrit.war init -d site_path
|
||||
java -jar gerrit.war reindex --recheck-mergeable -d site_path
|
||||
----
|
||||
|
||||
*WARNING:* When upgrading from an existing site that was initialized with Gerrit
|
||||
@ -32,8 +31,8 @@ rather than only copying the .war file over the existing one.
|
||||
It is recommended to run the `init` program in interactive mode. Warnings will
|
||||
be suppressed in batch mode.
|
||||
|
||||
*WARNING:* Upgrading to 2.10.x requires the server be first upgraded to 2.1.7 (or
|
||||
a later 2.1.x version), and then to 2.10.x. If you are upgrading from 2.2.x.x or
|
||||
*WARNING:* Upgrading to 2.10.x requires the server be first upgraded to 2.8
|
||||
(or 2.9) and then to 2.10.x. If you are upgrading from 2.8.x or
|
||||
later, you may ignore this warning and upgrade directly to 2.10.x.
|
||||
|
||||
*WARNING:* The `auth.allowGoogleAccountUpgrade` setting is no longer supported.
|
||||
|
@ -1,31 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
|
||||
public class Schema_52 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_52() {
|
||||
super(new Provider<SchemaVersion>() {
|
||||
@Override
|
||||
public SchemaVersion get() {
|
||||
throw new ProvisionException("Cannot upgrade from 51");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,478 +0,0 @@
|
||||
// Copyright (C) 2010 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import static com.google.gerrit.common.data.Permission.CREATE;
|
||||
import static com.google.gerrit.common.data.Permission.FORGE_AUTHOR;
|
||||
import static com.google.gerrit.common.data.Permission.FORGE_COMMITTER;
|
||||
import static com.google.gerrit.common.data.Permission.FORGE_SERVER;
|
||||
import static com.google.gerrit.common.data.Permission.LABEL;
|
||||
import static com.google.gerrit.common.data.Permission.OWNER;
|
||||
import static com.google.gerrit.common.data.Permission.PUSH;
|
||||
import static com.google.gerrit.common.data.Permission.PUSH_MERGE;
|
||||
import static com.google.gerrit.common.data.Permission.PUSH_TAG;
|
||||
import static com.google.gerrit.common.data.Permission.READ;
|
||||
import static com.google.gerrit.common.data.Permission.SUBMIT;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.common.data.LabelType;
|
||||
import com.google.gerrit.common.data.Permission;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.extensions.client.InheritableBoolean;
|
||||
import com.google.gerrit.extensions.client.SubmitType;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.LabelId;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.client.SystemConfig;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.account.GroupUUID;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.group.SystemGroupBackend;
|
||||
import com.google.gerrit.server.schema.Schema_77.LegacyLabelTypes;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class Schema_53 extends SchemaVersion {
|
||||
private final GitRepositoryManager mgr;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
private SystemConfig systemConfig;
|
||||
private Map<AccountGroup.Id, GroupReference> groupMap;
|
||||
private LegacyLabelTypes labelTypes;
|
||||
private GroupReference projectOwners;
|
||||
|
||||
private Map<Project.NameKey, Project.NameKey> parentsByProject;
|
||||
private Map<Project.NameKey, List<OldRefRight>> rightsByProject;
|
||||
|
||||
private final String OLD_SUBMIT = "SUBM";
|
||||
private final String OLD_READ = "READ";
|
||||
private final String OLD_OWN = "OWN";
|
||||
private final String OLD_PUSH_TAG = "pTAG";
|
||||
private final String OLD_PUSH_HEAD = "pHD";
|
||||
private final String OLD_FORGE_IDENTITY = "FORG";
|
||||
|
||||
@Inject
|
||||
Schema_53(Provider<Schema_52> prior, GitRepositoryManager mgr,
|
||||
@GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
|
||||
SQLException {
|
||||
systemConfig = db.systemConfig().get(new SystemConfig.Key());
|
||||
labelTypes = Schema_77.getLegacyTypes(db);
|
||||
|
||||
assignGroupUUIDs(db);
|
||||
readOldRefRights(db);
|
||||
readProjectParents(db);
|
||||
exportProjectConfig(db);
|
||||
|
||||
deleteActionCategories(db);
|
||||
}
|
||||
|
||||
private void deleteActionCategories(ReviewDb db) throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
stmt.executeUpdate("DELETE FROM approval_categories WHERE position < 0");
|
||||
}
|
||||
}
|
||||
|
||||
private void assignGroupUUIDs(ReviewDb db) throws OrmException {
|
||||
groupMap = new HashMap<>();
|
||||
List<AccountGroup> groups = db.accountGroups().all().toList();
|
||||
for (AccountGroup g : groups) {
|
||||
if (g.getId().equals(systemConfig.ownerGroupId)) {
|
||||
g.setGroupUUID(SystemGroupBackend.PROJECT_OWNERS);
|
||||
projectOwners = GroupReference.forGroup(g);
|
||||
|
||||
} else if (g.getId().equals(systemConfig.anonymousGroupId)) {
|
||||
g.setGroupUUID(SystemGroupBackend.ANONYMOUS_USERS);
|
||||
|
||||
} else if (g.getId().equals(systemConfig.registeredGroupId)) {
|
||||
g.setGroupUUID(SystemGroupBackend.REGISTERED_USERS);
|
||||
|
||||
} else {
|
||||
g.setGroupUUID(GroupUUID.make(g.getName(), serverUser));
|
||||
}
|
||||
groupMap.put(g.getId(), GroupReference.forGroup(g));
|
||||
}
|
||||
db.accountGroups().update(groups);
|
||||
|
||||
systemConfig.adminGroupUUID = toUUID(systemConfig.adminGroupId);
|
||||
systemConfig.batchUsersGroupUUID = toUUID(systemConfig.batchUsersGroupId);
|
||||
db.systemConfig().update(Collections.singleton(systemConfig));
|
||||
}
|
||||
|
||||
private AccountGroup.UUID toUUID(AccountGroup.Id id) {
|
||||
return groupMap.get(id).getUUID();
|
||||
}
|
||||
|
||||
private void exportProjectConfig(ReviewDb db) throws OrmException,
|
||||
SQLException {
|
||||
try (Statement s = newStatement(db);
|
||||
ResultSet rs = s.executeQuery("SELECT * FROM projects ORDER BY name")) {
|
||||
while (rs.next()) {
|
||||
final String name = rs.getString("name");
|
||||
final Project.NameKey nameKey = new Project.NameKey(name);
|
||||
|
||||
Repository git;
|
||||
try {
|
||||
git = mgr.openRepository(nameKey);
|
||||
} catch (RepositoryNotFoundException notFound) {
|
||||
// A repository may be missing if this project existed only to store
|
||||
// inheritable permissions. For example 'All-Projects'.
|
||||
try {
|
||||
git = mgr.createRepository(nameKey);
|
||||
} catch (IOException err) {
|
||||
throw new OrmException("Cannot create repository " + name, err);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, nameKey, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
loadProject(rs, config.getProject());
|
||||
config.getAccessSections().clear();
|
||||
convertRights(config);
|
||||
|
||||
// Grant out read on the config branch by default.
|
||||
//
|
||||
if (config.getProject().getNameKey().equals(systemConfig.wildProjectName)) {
|
||||
AccessSection meta = config.getAccessSection(RefNames.REFS_CONFIG, true);
|
||||
Permission read = meta.getPermission(READ, true);
|
||||
read.getRule(config.resolve(projectOwners), true);
|
||||
}
|
||||
|
||||
md.setMessage("Import project configuration from SQL\n");
|
||||
config.commit(md);
|
||||
} catch (ConfigInvalidException err) {
|
||||
throw new OrmException("Cannot read project " + name, err);
|
||||
} catch (IOException err) {
|
||||
throw new OrmException("Cannot export project " + name, err);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadProject(ResultSet rs, Project project) throws SQLException,
|
||||
OrmException {
|
||||
project.setDescription(rs.getString("description"));
|
||||
project.setUseContributorAgreements(asInheritableBoolean(rs, "use_contributor_agreements"));
|
||||
|
||||
switch (rs.getString("submit_type").charAt(0)) {
|
||||
case 'F':
|
||||
project.setSubmitType(SubmitType.FAST_FORWARD_ONLY);
|
||||
break;
|
||||
case 'M':
|
||||
project.setSubmitType(SubmitType.MERGE_IF_NECESSARY);
|
||||
break;
|
||||
case 'A':
|
||||
project.setSubmitType(SubmitType.MERGE_ALWAYS);
|
||||
break;
|
||||
case 'C':
|
||||
project.setSubmitType(SubmitType.CHERRY_PICK);
|
||||
break;
|
||||
default:
|
||||
throw new OrmException("Unsupported submit_type="
|
||||
+ rs.getString("submit_type") + " on project " + project.getName());
|
||||
}
|
||||
|
||||
project.setUseSignedOffBy(asInheritableBoolean(rs, "use_signed_off_by"));
|
||||
project.setRequireChangeID(asInheritableBoolean(rs, "require_change_id"));
|
||||
project.setUseContentMerge(asInheritableBoolean(rs, "use_content_merge"));
|
||||
project.setParentName(rs.getString("parent_name"));
|
||||
}
|
||||
|
||||
private static InheritableBoolean asInheritableBoolean(ResultSet rs, String col)
|
||||
throws SQLException {
|
||||
return "Y".equals(rs.getString(col))
|
||||
? InheritableBoolean.TRUE
|
||||
: InheritableBoolean.INHERIT;
|
||||
}
|
||||
|
||||
private void readOldRefRights(ReviewDb db) throws SQLException {
|
||||
rightsByProject = new HashMap<>();
|
||||
|
||||
try (Statement s = newStatement(db);
|
||||
ResultSet rs = s.executeQuery("SELECT * FROM ref_rights")) {
|
||||
while (rs.next()) {
|
||||
OldRefRight right = new OldRefRight(rs);
|
||||
if (right.group == null || right.category == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<OldRefRight> list;
|
||||
|
||||
list = rightsByProject.get(right.project);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
rightsByProject.put(right.project, list);
|
||||
}
|
||||
list.add(right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readProjectParents(ReviewDb db) throws SQLException {
|
||||
parentsByProject = new HashMap<>();
|
||||
try (Statement s = newStatement(db);
|
||||
ResultSet rs = s.executeQuery("SELECT * FROM projects")) {
|
||||
while (rs.next()) {
|
||||
String name = rs.getString("name");
|
||||
String parent_name = rs.getString("parent_name");
|
||||
if (parent_name == null) {
|
||||
parent_name = systemConfig.wildProjectName.get();
|
||||
}
|
||||
parentsByProject.put(new Project.NameKey(name), //
|
||||
new Project.NameKey(parent_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void convertRights(ProjectConfig config) {
|
||||
List<OldRefRight> myRights =
|
||||
rightsByProject.get(config.getProject().getNameKey());
|
||||
if (myRights == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (OldRefRight old : myRights) {
|
||||
AccessSection section = config.getAccessSection(old.ref_pattern, true);
|
||||
GroupReference group = config.resolve(old.group);
|
||||
|
||||
if (OLD_SUBMIT.equals(old.category)) {
|
||||
PermissionRule submit = rule(group);
|
||||
if (old.max_value <= 0) {
|
||||
submit.setDeny();
|
||||
}
|
||||
add(section, SUBMIT, old.exclusive, submit);
|
||||
|
||||
} else if (OLD_READ.equals(old.category)) {
|
||||
if (old.exclusive) {
|
||||
section.getPermission(READ, true).setExclusiveGroup(true);
|
||||
newChangePermission(config, old.ref_pattern).setExclusiveGroup(true);
|
||||
}
|
||||
|
||||
PermissionRule read = rule(group);
|
||||
if (old.max_value <= 0) {
|
||||
read.setDeny();
|
||||
}
|
||||
add(section, READ, old.exclusive, read);
|
||||
|
||||
if (3 <= old.max_value) {
|
||||
newMergePermission(config, old.ref_pattern).add(rule(group));
|
||||
} else if (3 <= inheritedMax(config, old)) {
|
||||
newMergePermission(config, old.ref_pattern).add(deny(group));
|
||||
}
|
||||
|
||||
if (2 <= old.max_value) {
|
||||
newChangePermission(config, old.ref_pattern).add(rule(group));
|
||||
} else if (2 <= inheritedMax(config, old)) {
|
||||
newChangePermission(config, old.ref_pattern).add(deny(group));
|
||||
}
|
||||
|
||||
} else if (OLD_OWN.equals(old.category)) {
|
||||
add(section, OWNER, false, rule(group));
|
||||
|
||||
} else if (OLD_PUSH_TAG.equals(old.category)) {
|
||||
PermissionRule push = rule(group);
|
||||
if (old.max_value <= 0) {
|
||||
push.setDeny();
|
||||
}
|
||||
add(section, PUSH_TAG, old.exclusive, push);
|
||||
|
||||
} else if (OLD_PUSH_HEAD.equals(old.category)) {
|
||||
if (old.exclusive) {
|
||||
section.getPermission(PUSH, true).setExclusiveGroup(true);
|
||||
section.getPermission(CREATE, true).setExclusiveGroup(true);
|
||||
}
|
||||
|
||||
PermissionRule push = rule(group);
|
||||
if (old.max_value <= 0) {
|
||||
push.setDeny();
|
||||
}
|
||||
push.setForce(3 <= old.max_value);
|
||||
add(section, PUSH, old.exclusive, push);
|
||||
|
||||
if (2 <= old.max_value) {
|
||||
add(section, CREATE, old.exclusive, rule(group));
|
||||
} else if (2 <= inheritedMax(config, old)) {
|
||||
add(section, CREATE, old.exclusive, deny(group));
|
||||
}
|
||||
|
||||
} else if (OLD_FORGE_IDENTITY.equals(old.category)) {
|
||||
if (old.exclusive) {
|
||||
section.getPermission(FORGE_AUTHOR, true).setExclusiveGroup(true);
|
||||
section.getPermission(FORGE_COMMITTER, true).setExclusiveGroup(true);
|
||||
section.getPermission(FORGE_SERVER, true).setExclusiveGroup(true);
|
||||
}
|
||||
|
||||
if (1 <= old.max_value) {
|
||||
add(section, FORGE_AUTHOR, old.exclusive, rule(group));
|
||||
}
|
||||
|
||||
if (2 <= old.max_value) {
|
||||
add(section, FORGE_COMMITTER, old.exclusive, rule(group));
|
||||
} else if (2 <= inheritedMax(config, old)) {
|
||||
add(section, FORGE_COMMITTER, old.exclusive, deny(group));
|
||||
}
|
||||
|
||||
if (3 <= old.max_value) {
|
||||
add(section, FORGE_SERVER, old.exclusive, rule(group));
|
||||
} else if (3 <= inheritedMax(config, old)) { add(section, FORGE_SERVER, old.exclusive, deny(group));
|
||||
}
|
||||
|
||||
} else {
|
||||
PermissionRule rule = rule(group);
|
||||
rule.setRange(old.min_value, old.max_value);
|
||||
if (old.min_value == 0 && old.max_value == 0) {
|
||||
rule.setDeny();
|
||||
}
|
||||
LabelType type = labelTypes.byLabel(new LabelId(old.category));
|
||||
String name = type != null ? type.getName() : old.category;
|
||||
add(section, LABEL + name, old.exclusive, rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Permission newChangePermission(ProjectConfig config,
|
||||
String name) {
|
||||
if (name.startsWith(AccessSection.REGEX_PREFIX)) {
|
||||
name = AccessSection.REGEX_PREFIX
|
||||
+ "refs/for/"
|
||||
+ name.substring(AccessSection.REGEX_PREFIX.length());
|
||||
} else {
|
||||
name = "refs/for/" + name;
|
||||
}
|
||||
return config.getAccessSection(name, true).getPermission(PUSH, true);
|
||||
}
|
||||
|
||||
private static Permission newMergePermission(ProjectConfig config,
|
||||
String name) {
|
||||
if (name.startsWith(AccessSection.REGEX_PREFIX)) {
|
||||
name = AccessSection.REGEX_PREFIX
|
||||
+ "refs/for/"
|
||||
+ name.substring(AccessSection.REGEX_PREFIX.length());
|
||||
} else {
|
||||
name = "refs/for/" + name;
|
||||
}
|
||||
return config.getAccessSection(name, true).getPermission(PUSH_MERGE, true);
|
||||
}
|
||||
|
||||
private static PermissionRule rule(GroupReference group) {
|
||||
return new PermissionRule(group);
|
||||
}
|
||||
|
||||
private static PermissionRule deny(GroupReference group) {
|
||||
PermissionRule rule = rule(group);
|
||||
rule.setDeny();
|
||||
return rule;
|
||||
}
|
||||
|
||||
private int inheritedMax(ProjectConfig config, OldRefRight old) {
|
||||
int max = 0;
|
||||
|
||||
String ref = old.ref_pattern;
|
||||
String category = old.category;
|
||||
AccountGroup.UUID group = old.group.getUUID();
|
||||
|
||||
Project.NameKey project = config.getProject().getParent();
|
||||
if (project == null) {
|
||||
project = systemConfig.wildProjectName;
|
||||
}
|
||||
do {
|
||||
List<OldRefRight> rights = rightsByProject.get(project);
|
||||
if (rights != null) {
|
||||
for (OldRefRight r : rights) {
|
||||
if (r.ref_pattern.equals(ref) //
|
||||
&& r.group.getUUID().equals(group) //
|
||||
&& r.category.equals(category)) {
|
||||
max = Math.max(max, r.max_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
project = parentsByProject.get(project);
|
||||
} while (!project.equals(systemConfig.wildProjectName));
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
private static void add(AccessSection section, String name,
|
||||
boolean exclusive, PermissionRule rule) {
|
||||
Permission p = section.getPermission(name, true);
|
||||
if (exclusive) {
|
||||
p.setExclusiveGroup(true);
|
||||
}
|
||||
p.add(rule);
|
||||
}
|
||||
|
||||
private class OldRefRight {
|
||||
final int min_value;
|
||||
final int max_value;
|
||||
final String ref_pattern;
|
||||
final boolean exclusive;
|
||||
final GroupReference group;
|
||||
final String category;
|
||||
final Project.NameKey project;
|
||||
|
||||
OldRefRight(ResultSet rs) throws SQLException {
|
||||
min_value = rs.getInt("min_value");
|
||||
max_value = rs.getInt("max_value");
|
||||
project = new Project.NameKey(rs.getString("project_name"));
|
||||
|
||||
String r = rs.getString("ref_pattern");
|
||||
exclusive = r.startsWith("-");
|
||||
if (exclusive) {
|
||||
r = r.substring(1);
|
||||
}
|
||||
ref_pattern = r;
|
||||
|
||||
category = rs.getString("category_id");
|
||||
group = groupMap.get(new AccountGroup.Id(rs.getInt("group_id")));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_54 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_54(Provider<Schema_53> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.SystemConfig;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Schema_55 extends SchemaVersion {
|
||||
private final GitRepositoryManager mgr;
|
||||
|
||||
@Inject
|
||||
Schema_55(Provider<Schema_54> prior, GitRepositoryManager mgr) {
|
||||
super(prior);
|
||||
this.mgr = mgr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
|
||||
SystemConfig sc = db.systemConfig().get(new SystemConfig.Key());
|
||||
String oldName = sc.wildProjectName.get();
|
||||
String newName = "All-Projects";
|
||||
if ("-- All Projects --".equals(oldName)) {
|
||||
ui.message("Renaming \"" + oldName + "\" to \"" + newName + "\"");
|
||||
|
||||
File base = ((LocalDiskRepositoryManager) mgr).getBasePath();
|
||||
File oldDir = FileKey.resolve(new File(base, oldName), FS.DETECTED);
|
||||
File newDir = new File(base, newName + Constants.DOT_GIT_EXT);
|
||||
if (!oldDir.renameTo(newDir)) {
|
||||
throw new OrmException("Cannot rename " + oldDir.getAbsolutePath()
|
||||
+ " to " + newDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
sc.wildProjectName = new Project.NameKey(newName);
|
||||
db.systemConfig().update(Collections.singleton(sc));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefDatabase;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Schema_56 extends SchemaVersion {
|
||||
private final GitRepositoryManager mgr;
|
||||
private final Set<String> keysOne;
|
||||
private final Set<String> keysTwo;
|
||||
|
||||
@Inject
|
||||
Schema_56(Provider<Schema_55> prior, GitRepositoryManager mgr) {
|
||||
super(prior);
|
||||
this.mgr = mgr;
|
||||
|
||||
keysOne = new HashSet<>();
|
||||
keysTwo = new HashSet<>();
|
||||
|
||||
keysOne.add(RefNames.REFS_CONFIG);
|
||||
keysTwo.add(RefNames.REFS_CONFIG);
|
||||
keysTwo.add(Constants.HEAD);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) {
|
||||
for (Project.NameKey name : mgr.list()) {
|
||||
Repository git;
|
||||
try {
|
||||
git = mgr.openRepository(name);
|
||||
} catch (IOException e) {
|
||||
ui.message("warning: Cannot open " + name.get());
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Map<String, Ref> all;
|
||||
try {
|
||||
all = git.getRefDatabase().getRefs(RefDatabase.ALL);
|
||||
} catch (IOException e) {
|
||||
ui.message("warning: " + name.get() + ": Cannot read refs: "
|
||||
+ e.getMessage());
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
if (all.keySet().equals(keysOne) || all.keySet().equals(keysTwo)) {
|
||||
try {
|
||||
RefUpdate update = git.updateRef(Constants.HEAD);
|
||||
update.disableRefLog();
|
||||
update.link(RefNames.REFS_CONFIG);
|
||||
} catch (IOException err) {
|
||||
ui.message("warning: " + name.get() + ": Cannot update HEAD to "
|
||||
+ RefNames.REFS_CONFIG + ": " + err.getMessage());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.common.data.PermissionRule.Action;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.SystemConfig;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.config.AllProjectsNameProvider;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Schema_57 extends SchemaVersion {
|
||||
private final SitePaths site;
|
||||
private final GitRepositoryManager mgr;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
@Inject
|
||||
Schema_57(Provider<Schema_56> prior, SitePaths site,
|
||||
GitRepositoryManager mgr, @GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.site = site;
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
|
||||
SystemConfig sc = db.systemConfig().get(new SystemConfig.Key());
|
||||
Project.NameKey allProjects = sc.wildProjectName;
|
||||
|
||||
FileBasedConfig cfg = new FileBasedConfig(site.gerrit_config, FS.DETECTED);
|
||||
boolean cfgDirty = false;
|
||||
try {
|
||||
cfg.load();
|
||||
} catch (ConfigInvalidException err) {
|
||||
throw new OrmException("Cannot read " + site.gerrit_config, err);
|
||||
} catch (IOException err) {
|
||||
throw new OrmException("Cannot read " + site.gerrit_config, err);
|
||||
}
|
||||
|
||||
if (!allProjects.get().equals(AllProjectsNameProvider.DEFAULT)) {
|
||||
ui.message("Setting gerrit.allProjects = " + allProjects.get());
|
||||
cfg.setString("gerrit", null, "allProjects", allProjects.get());
|
||||
cfgDirty = true;
|
||||
}
|
||||
|
||||
try {
|
||||
Repository git = mgr.openRepository(allProjects);
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
AccessSection cap = config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true);
|
||||
|
||||
// Move the Administrators group reference to All-Projects.
|
||||
cap.getPermission(GlobalCapability.ADMINISTRATE_SERVER, true)
|
||||
.add(new PermissionRule(config.resolve(db.accountGroups().get(sc.adminGroupId))));
|
||||
|
||||
// Move the repository.*.createGroup to Create Project.
|
||||
String[] createGroupList = cfg.getStringList("repository", "*", "createGroup");
|
||||
|
||||
// Prepare the account_group_includes query
|
||||
boolean isAccountGroupEmpty = false;
|
||||
try (PreparedStatement stmt = prepareStatement(db,
|
||||
"SELECT COUNT(1) FROM account_group_includes WHERE group_id = ?")) {
|
||||
stmt.setInt(1, sc.batchUsersGroupId.get());
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
isAccountGroupEmpty = rs.getInt(1) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : createGroupList) {
|
||||
AccountGroup.NameKey key = new AccountGroup.NameKey(name);
|
||||
AccountGroupName groupName = db.accountGroupNames().get(key);
|
||||
if (groupName == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AccountGroup group = db.accountGroups().get(groupName.getId());
|
||||
if (group == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cap.getPermission(GlobalCapability.CREATE_PROJECT, true)
|
||||
.add(new PermissionRule(config.resolve(group)));
|
||||
}
|
||||
if (createGroupList.length != 0) {
|
||||
ui.message("Moved repository.*.createGroup to 'Create Project' capability");
|
||||
cfg.unset("repository", "*", "createGroup");
|
||||
cfgDirty = true;
|
||||
}
|
||||
|
||||
AccountGroup batch = db.accountGroups().get(sc.batchUsersGroupId);
|
||||
|
||||
if (batch != null
|
||||
&& db.accountGroupMembers().byGroup(sc.batchUsersGroupId).toList().isEmpty()
|
||||
&& !isAccountGroupEmpty) {
|
||||
// If the batch user group is not used, delete it.
|
||||
//
|
||||
db.accountGroups().delete(Collections.singleton(batch));
|
||||
|
||||
AccountGroupName name = db.accountGroupNames().get(batch.getNameKey());
|
||||
if (name != null) {
|
||||
db.accountGroupNames().delete(Collections.singleton(name));
|
||||
}
|
||||
} else if (batch != null) {
|
||||
cap.getPermission(GlobalCapability.PRIORITY, true)
|
||||
.getRule(config.resolve(batch), true)
|
||||
.setAction(Action.BATCH);
|
||||
}
|
||||
|
||||
md.setMessage("Upgrade to Gerrit Code Review schema 57\n");
|
||||
config.commit(md);
|
||||
} catch (SQLException err) {
|
||||
throw new OrmException( "Cannot read account_group_includes", err);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
} catch (ConfigInvalidException err) {
|
||||
throw new OrmException("Cannot read " + allProjects, err);
|
||||
} catch (IOException err) {
|
||||
throw new OrmException("Cannot update " + allProjects, err);
|
||||
}
|
||||
|
||||
if (cfgDirty) {
|
||||
try {
|
||||
cfg.save();
|
||||
} catch (IOException err) {
|
||||
throw new OrmException("Cannot update " + site.gerrit_config, err);
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot set the columns to NULL, so use 0 and a DELETED tag.
|
||||
sc.adminGroupId = new AccountGroup.Id(0);
|
||||
sc.adminGroupUUID = new AccountGroup.UUID("DELETED");
|
||||
sc.anonymousGroupId = new AccountGroup.Id(0);
|
||||
sc.registeredGroupId = new AccountGroup.Id(0);
|
||||
sc.wildProjectName = new Project.NameKey("DELETED");
|
||||
sc.ownerGroupId = new AccountGroup.Id(0);
|
||||
sc.batchUsersGroupId = new AccountGroup.Id(0);
|
||||
sc.batchUsersGroupUUID = new AccountGroup.UUID("DELETED");
|
||||
sc.registerEmailPrivateKey = "DELETED";
|
||||
|
||||
db.systemConfig().update(Collections.singleton(sc));
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_58 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_58(Provider<Schema_57> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_59 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_59(Provider<Schema_58> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
// Don't migrate columns; they are removed in Schema_100.
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.ResultSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class Schema_60 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_60(Provider<Schema_59> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
|
||||
Pattern patternA = Pattern.compile("Patch Set ([0-9]+):.*", Pattern.DOTALL);
|
||||
Pattern patternB = Pattern.compile("Uploaded patch set ([0-9]+).");
|
||||
ResultSet<ChangeMessage> results = db.changeMessages().all();
|
||||
List<ChangeMessage> updates = new LinkedList<>();
|
||||
for (ChangeMessage cm : results) {
|
||||
Change.Id id = cm.getKey().getParentKey();
|
||||
String msg = cm.getMessage();
|
||||
Matcher matcherA = patternA.matcher(msg);
|
||||
Matcher matcherB = patternB.matcher(msg);
|
||||
PatchSet.Id newId = null;
|
||||
if (matcherA.matches()) {
|
||||
int patchSetNum = Integer.parseInt(matcherA.group(1));
|
||||
newId = new PatchSet.Id(id, patchSetNum);
|
||||
} else if (matcherB.matches()) {
|
||||
int patchSetNum = Integer.parseInt(matcherB.group(1));
|
||||
newId = new PatchSet.Id(id, patchSetNum);
|
||||
}
|
||||
if (newId != null) {
|
||||
cm.setPatchSetId(newId);
|
||||
updates.add(cm);
|
||||
}
|
||||
if (updates.size() >= 100) {
|
||||
db.changeMessages().update(updates);
|
||||
updates.clear();
|
||||
}
|
||||
}
|
||||
if (!updates.isEmpty()) {
|
||||
db.changeMessages().update(updates);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_61 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_61(Provider<Schema_60> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2011 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_62 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_62(Provider<Schema_61> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||
import com.google.gwtorm.schema.sql.DialectPostgreSQL;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class Schema_63 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_63(Provider<Schema_62> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
if (((JdbcSchema) db).getDialect() instanceof DialectPostgreSQL) {
|
||||
stmt.execute("CREATE INDEX changes_byBranchClosed"
|
||||
+ " ON changes (status, dest_project_name, dest_branch_name, sort_key)"
|
||||
+ " WHERE open = 'N'");
|
||||
} else {
|
||||
stmt.execute("CREATE INDEX changes_byBranchClosed"
|
||||
+ " ON changes (status, dest_project_name, dest_branch_name, sort_key)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.common.data.Permission;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
public class Schema_64 extends SchemaVersion {
|
||||
private final AllProjectsName allProjects;
|
||||
private final GitRepositoryManager mgr;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
@Inject
|
||||
Schema_64(Provider<Schema_63> prior,
|
||||
AllProjectsName allProjects,
|
||||
GitRepositoryManager mgr,
|
||||
@GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.allProjects = allProjects;
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui)
|
||||
throws OrmException, SQLException {
|
||||
List<GroupReference> groups = Lists.newArrayList();
|
||||
try (Statement stmt = newStatement(db);
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT group_uuid, name FROM account_groups WHERE email_only_authors = 'Y'")) {
|
||||
while (rs.next()) {
|
||||
AccountGroup.UUID uuid = new AccountGroup.UUID(rs.getString(1));
|
||||
GroupReference group = new GroupReference(uuid, rs.getString(2));
|
||||
groups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
if (groups.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ui.message("Moved account_groups.email_only_authors to 'Email Reviewers' capability");
|
||||
|
||||
Repository git;
|
||||
try {
|
||||
git = mgr.openRepository(allProjects);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
AccessSection section =
|
||||
config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true);
|
||||
Permission capability =
|
||||
section.getPermission(GlobalCapability.EMAIL_REVIEWERS, true);
|
||||
for (GroupReference group : groups) {
|
||||
capability.getRule(config.resolve(group), true).setDeny();
|
||||
}
|
||||
|
||||
md.setMessage("Upgrade to Gerrit Code Review schema 64\n");
|
||||
config.commit(md);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (ConfigInvalidException e) {
|
||||
throw new OrmException(e);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,451 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.common.TimeUtil;
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.ContributorAgreement;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.common.data.PermissionRule.Action;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupMember;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.account.GroupUUID;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.AnonymousCowardName;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.git.VersionedMetaData.BatchMetaDataUpdate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.CommitBuilder;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.util.SystemReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class Schema_65 extends SchemaVersion {
|
||||
private final AllProjectsName allProjects;
|
||||
private final GitRepositoryManager mgr;
|
||||
private final PersonIdent serverUser;
|
||||
private final @AnonymousCowardName String anonymousCowardName;
|
||||
|
||||
@Inject
|
||||
Schema_65(Provider<Schema_64> prior,
|
||||
AllProjectsName allProjects,
|
||||
GitRepositoryManager mgr,
|
||||
@GerritPersonIdent PersonIdent serverUser,
|
||||
@AnonymousCowardName String anonymousCowardName) {
|
||||
super(prior);
|
||||
this.allProjects = allProjects;
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
this.anonymousCowardName = anonymousCowardName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui)
|
||||
throws OrmException, SQLException {
|
||||
Repository git;
|
||||
try {
|
||||
git = mgr.openRepository(allProjects);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
Map<Integer, ContributorAgreement> agreements = getAgreementToAdd(db, config);
|
||||
if (agreements.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ui.message("Moved contributor agreements to project.config");
|
||||
|
||||
// Create the auto verify groups.
|
||||
List<AccountGroup.UUID> adminGroupUUIDs = getAdministrateServerGroups(config);
|
||||
for (ContributorAgreement agreement : agreements.values()) {
|
||||
if (agreement.getAutoVerify() != null) {
|
||||
getOrCreateGroupForIndividuals(db, config, adminGroupUUIDs, agreement);
|
||||
}
|
||||
}
|
||||
|
||||
// Scan AccountAgreement
|
||||
long minTime = addAccountAgreements(db, config, adminGroupUUIDs, agreements);
|
||||
|
||||
ProjectConfig base = ProjectConfig.read(md, null);
|
||||
for (ContributorAgreement agreement : agreements.values()) {
|
||||
base.replace(agreement);
|
||||
}
|
||||
base.getAccountsSection().setSameGroupVisibility(
|
||||
config.getAccountsSection().getSameGroupVisibility());
|
||||
|
||||
BatchMetaDataUpdate batch = base.openUpdate(md);
|
||||
try {
|
||||
// Scan AccountGroupAgreement
|
||||
List<AccountGroupAgreement> groupAgreements =
|
||||
getAccountGroupAgreements(db, agreements);
|
||||
|
||||
// Find the earliest change
|
||||
for (AccountGroupAgreement aga : groupAgreements) {
|
||||
minTime = Math.min(minTime, aga.getTime());
|
||||
}
|
||||
minTime -= 60 * 1000; // 1 Minute
|
||||
|
||||
CommitBuilder commit = new CommitBuilder();
|
||||
commit.setAuthor(new PersonIdent(serverUser, new Date(minTime)));
|
||||
commit.setCommitter(new PersonIdent(serverUser, new Date(minTime)));
|
||||
commit.setMessage("Add the ContributorAgreements for upgrade to Gerrit Code Review schema 65\n");
|
||||
batch.write(commit);
|
||||
|
||||
for (AccountGroupAgreement aga : groupAgreements) {
|
||||
AccountGroup group = db.accountGroups().get(aga.groupId);
|
||||
if (group == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ContributorAgreement agreement = agreements.get(aga.claId);
|
||||
agreement.getAccepted().add(new PermissionRule(config.resolve(group)));
|
||||
base.replace(agreement);
|
||||
|
||||
PersonIdent ident = null;
|
||||
if (aga.reviewedBy != null) {
|
||||
Account ua = db.accounts().get(aga.reviewedBy);
|
||||
if (ua != null) {
|
||||
String name = ua.getFullName();
|
||||
String email = ua.getPreferredEmail();
|
||||
|
||||
if (email == null || email.isEmpty()) {
|
||||
// No preferred email is configured. Use a generic identity so we
|
||||
// don't leak an address the user may have given us, but doesn't
|
||||
// necessarily want to publish through Git records.
|
||||
//
|
||||
String user = ua.getUserName();
|
||||
if (user == null || user.isEmpty()) {
|
||||
user = "account-" + ua.getId().toString();
|
||||
}
|
||||
|
||||
String host = SystemReader.getInstance().getHostname();
|
||||
email = user + "@" + host;
|
||||
}
|
||||
|
||||
if (name == null || name.isEmpty()) {
|
||||
final int at = email.indexOf('@');
|
||||
if (0 < at) {
|
||||
name = email.substring(0, at);
|
||||
} else {
|
||||
name = anonymousCowardName;
|
||||
}
|
||||
}
|
||||
|
||||
ident = new PersonIdent(name, email, new Date(aga.getTime()), TimeZone.getDefault());
|
||||
}
|
||||
}
|
||||
if (ident == null) {
|
||||
ident = new PersonIdent(serverUser, new Date(aga.getTime()));
|
||||
}
|
||||
|
||||
// Build the commits such that it keeps track of the date added and
|
||||
// who added it.
|
||||
commit = new CommitBuilder();
|
||||
commit.setAuthor(ident);
|
||||
commit.setCommitter(new PersonIdent(serverUser, new Date(aga.getTime())));
|
||||
|
||||
String msg = String.format("Accept %s contributor agreement for %s\n",
|
||||
agreement.getName(), group.getName());
|
||||
if (!Strings.isNullOrEmpty(aga.reviewComments)) {
|
||||
msg += "\n" + aga.reviewComments + "\n";
|
||||
}
|
||||
commit.setMessage(msg);
|
||||
batch.write(commit);
|
||||
}
|
||||
|
||||
// Merge the agreements with the other data in project.config.
|
||||
commit = new CommitBuilder();
|
||||
commit.setAuthor(serverUser);
|
||||
commit.setCommitter(serverUser);
|
||||
commit.setMessage("Upgrade to Gerrit Code Review schema 65\n");
|
||||
commit.addParentId(config.getRevision());
|
||||
batch.write(config, commit);
|
||||
|
||||
// Save the the final metadata.
|
||||
batch.commitAt(config.getRevision());
|
||||
} finally {
|
||||
batch.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (ConfigInvalidException e) {
|
||||
throw new OrmException(e);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Integer, ContributorAgreement> getAgreementToAdd(
|
||||
ReviewDb db, ProjectConfig config) throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT short_name, id, require_contact_information," +
|
||||
" short_description, agreement_url, auto_verify " +
|
||||
"FROM contributor_agreements WHERE active = 'Y'");
|
||||
try {
|
||||
Map<Integer, ContributorAgreement> agreements = Maps.newHashMap();
|
||||
while (rs.next()) {
|
||||
String name = rs.getString(1);
|
||||
if (config.getContributorAgreement(name) != null) {
|
||||
continue; // already exists
|
||||
}
|
||||
ContributorAgreement a = config.getContributorAgreement(name, true);
|
||||
agreements.put(rs.getInt(2), a);
|
||||
|
||||
a.setRequireContactInformation("Y".equals(rs.getString(3)));
|
||||
a.setDescription(rs.getString(4));
|
||||
a.setAgreementUrl(rs.getString(5));
|
||||
if ("Y".equals(rs.getString(6))) {
|
||||
a.setAutoVerify(new GroupReference(null, null));
|
||||
}
|
||||
}
|
||||
return agreements;
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AccountGroup createGroup(ReviewDb db, String groupName,
|
||||
AccountGroup.UUID adminGroupUUID, String description)
|
||||
throws OrmException {
|
||||
final AccountGroup.Id groupId =
|
||||
new AccountGroup.Id(db.nextAccountGroupId());
|
||||
final AccountGroup.NameKey nameKey = new AccountGroup.NameKey(groupName);
|
||||
final AccountGroup.UUID uuid = GroupUUID.make(groupName, serverUser);
|
||||
final AccountGroup group = new AccountGroup(nameKey, groupId, uuid);
|
||||
group.setOwnerGroupUUID(adminGroupUUID);
|
||||
group.setDescription(description);
|
||||
final AccountGroupName gn = new AccountGroupName(group);
|
||||
// first insert the group name to validate that the group name hasn't
|
||||
// already been used to create another group
|
||||
db.accountGroupNames().insert(Collections.singleton(gn));
|
||||
db.accountGroups().insert(Collections.singleton(group));
|
||||
return group;
|
||||
}
|
||||
|
||||
private List<AccountGroup.UUID> getAdministrateServerGroups(
|
||||
ProjectConfig cfg) {
|
||||
List<PermissionRule> rules = cfg.getAccessSection(AccessSection.GLOBAL_CAPABILITIES)
|
||||
.getPermission(GlobalCapability.ADMINISTRATE_SERVER)
|
||||
.getRules();
|
||||
|
||||
List<AccountGroup.UUID> groups =
|
||||
Lists.newArrayListWithExpectedSize(rules.size());
|
||||
for (PermissionRule rule : rules) {
|
||||
if (rule.getAction() == Action.ALLOW) {
|
||||
groups.add(rule.getGroup().getUUID());
|
||||
}
|
||||
}
|
||||
if (groups.isEmpty()) {
|
||||
throw new IllegalStateException("no administrator group found");
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
private GroupReference getOrCreateGroupForIndividuals(ReviewDb db,
|
||||
ProjectConfig config, List<AccountGroup.UUID> adminGroupUUIDs,
|
||||
ContributorAgreement agreement)
|
||||
throws OrmException {
|
||||
if (!agreement.getAccepted().isEmpty()) {
|
||||
return agreement.getAccepted().get(0).getGroup();
|
||||
}
|
||||
|
||||
String name = "CLA Accepted - " + agreement.getName();
|
||||
AccountGroupName agn =
|
||||
db.accountGroupNames().get(new AccountGroup.NameKey(name));
|
||||
AccountGroup ag;
|
||||
if (agn != null) {
|
||||
ag = db.accountGroups().get(agn.getId());
|
||||
if (ag == null) {
|
||||
throw new IllegalStateException(
|
||||
"account group name exists but account group does not: " + name);
|
||||
}
|
||||
|
||||
if (!adminGroupUUIDs.contains(ag.getOwnerGroupUUID())) {
|
||||
throw new IllegalStateException(
|
||||
"individual group exists with non admin owner group: " + name);
|
||||
}
|
||||
} else {
|
||||
ag = createGroup(db, name, adminGroupUUIDs.get(0),
|
||||
String.format("Users who have accepted the %s CLA", agreement.getName()));
|
||||
}
|
||||
GroupReference group = config.resolve(ag);
|
||||
agreement.setAccepted(Lists.newArrayList(new PermissionRule(group)));
|
||||
if (agreement.getAutoVerify() != null) {
|
||||
agreement.setAutoVerify(group);
|
||||
}
|
||||
|
||||
// Don't allow accounts in the same individual CLA group to see each
|
||||
// other in same group visibility mode.
|
||||
List<PermissionRule> sameGroupVisibility =
|
||||
config.getAccountsSection().getSameGroupVisibility();
|
||||
PermissionRule rule = new PermissionRule(group);
|
||||
rule.setDeny();
|
||||
if (!sameGroupVisibility.contains(rule)) {
|
||||
sameGroupVisibility.add(rule);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
private long addAccountAgreements(ReviewDb db, ProjectConfig config,
|
||||
List<AccountGroup.UUID> adminGroupUUIDs,
|
||||
Map<Integer, ContributorAgreement> agreements)
|
||||
throws SQLException, OrmException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT account_id, cla_id, accepted_on, reviewed_by," +
|
||||
" reviewed_on, review_comments " +
|
||||
"FROM account_agreements WHERE status = 'V'");
|
||||
try {
|
||||
long minTime = TimeUtil.nowMs();
|
||||
while (rs.next()) {
|
||||
Account.Id accountId = new Account.Id(rs.getInt(1));
|
||||
Account.Id reviewerId = new Account.Id(rs.getInt(4));
|
||||
if (rs.wasNull()) {
|
||||
reviewerId = accountId;
|
||||
}
|
||||
|
||||
int claId = rs.getInt(2);
|
||||
ContributorAgreement agreement = agreements.get(claId);
|
||||
if (agreement == null) {
|
||||
continue; // Agreement is invalid
|
||||
}
|
||||
|
||||
Timestamp acceptedOn = rs.getTimestamp(3);
|
||||
minTime = Math.min(minTime, acceptedOn.getTime());
|
||||
|
||||
// Enter Agreement
|
||||
GroupReference individualGroup =
|
||||
getOrCreateGroupForIndividuals(db, config, adminGroupUUIDs, agreement);
|
||||
AccountGroup.Id groupId = db.accountGroups()
|
||||
.byUUID(individualGroup.getUUID())
|
||||
.toList()
|
||||
.get(0)
|
||||
.getId();
|
||||
|
||||
final AccountGroupMember.Key key =
|
||||
new AccountGroupMember.Key(accountId, groupId);
|
||||
AccountGroupMember m = db.accountGroupMembers().get(key);
|
||||
if (m == null) {
|
||||
m = new AccountGroupMember(key);
|
||||
db.accountGroupMembersAudit().insert(
|
||||
Collections.singleton(
|
||||
new AccountGroupMemberAudit(m, reviewerId, acceptedOn)));
|
||||
db.accountGroupMembers().insert(Collections.singleton(m));
|
||||
}
|
||||
}
|
||||
return minTime;
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class AccountGroupAgreement {
|
||||
private AccountGroup.Id groupId;
|
||||
private int claId;
|
||||
private Timestamp acceptedOn;
|
||||
private Account.Id reviewedBy;
|
||||
private Timestamp reviewedOn;
|
||||
private String reviewComments;
|
||||
|
||||
private long getTime() {
|
||||
return (reviewedOn == null) ? acceptedOn.getTime() : reviewedOn.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
private List<AccountGroupAgreement> getAccountGroupAgreements(
|
||||
ReviewDb db, Map<Integer, ContributorAgreement> agreements)
|
||||
throws SQLException {
|
||||
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT group_id, cla_id, accepted_on, reviewed_by, reviewed_on, " +
|
||||
" review_comments " +
|
||||
"FROM account_group_agreements");
|
||||
try {
|
||||
List<AccountGroupAgreement> groupAgreements = Lists.newArrayList();
|
||||
while (rs.next()) {
|
||||
AccountGroupAgreement a = new AccountGroupAgreement();
|
||||
a.groupId = new AccountGroup.Id(rs.getInt(1));
|
||||
a.claId = rs.getInt(2);
|
||||
if (!agreements.containsKey(a.claId)) {
|
||||
continue; // Agreement is invalid
|
||||
}
|
||||
a.acceptedOn = rs.getTimestamp(3);
|
||||
a.reviewedBy = new Account.Id(rs.getInt(4));
|
||||
if (rs.wasNull()) {
|
||||
a.reviewedBy = null;
|
||||
}
|
||||
|
||||
a.reviewedOn = rs.getTimestamp(5);
|
||||
if (rs.wasNull()) {
|
||||
a.reviewedOn = null;
|
||||
}
|
||||
|
||||
a.reviewComments = rs.getString(6);
|
||||
if (rs.wasNull()) {
|
||||
a.reviewComments = null;
|
||||
}
|
||||
groupAgreements.add(a);
|
||||
}
|
||||
Collections.sort(groupAgreements, new Comparator<AccountGroupAgreement>() {
|
||||
@Override
|
||||
public int compare(
|
||||
AccountGroupAgreement a1, AccountGroupAgreement a2) {
|
||||
return Long.compare(a1.getTime(), a2.getTime());
|
||||
}
|
||||
});
|
||||
return groupAgreements;
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_66 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_66(Provider<Schema_65> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class Schema_67 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_67(Provider<Schema_66> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui)
|
||||
throws OrmException, SQLException {
|
||||
ui.message("Update ownerGroupId to ownerGroupUUID");
|
||||
|
||||
// Scan all AccountGroup, and find the ones that need the owner_group_id
|
||||
// migrated to owner_group_uuid.
|
||||
Map<AccountGroup.Id, AccountGroup.Id> idMap = Maps.newHashMap();
|
||||
try (Statement stmt = newStatement(db);
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT group_id, owner_group_id FROM account_groups"
|
||||
+ " WHERE owner_group_uuid is NULL or owner_group_uuid =''")) {
|
||||
while (rs.next()) {
|
||||
AccountGroup.Id groupId = new AccountGroup.Id(rs.getInt(1));
|
||||
AccountGroup.Id ownerId = new AccountGroup.Id(rs.getInt(2));
|
||||
idMap.put(groupId, ownerId);
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup up all groups by ID.
|
||||
Set<AccountGroup.Id> all =
|
||||
Sets.newHashSet(Iterables.concat(idMap.keySet(), idMap.values()));
|
||||
Map<AccountGroup.Id, AccountGroup> groups = Maps.newHashMap();
|
||||
com.google.gwtorm.server.ResultSet<AccountGroup> rs =
|
||||
db.accountGroups().get(all);
|
||||
try {
|
||||
for (AccountGroup group : rs) {
|
||||
groups.put(group.getId(), group);
|
||||
}
|
||||
} finally {
|
||||
rs.close();
|
||||
}
|
||||
|
||||
// Update the ownerGroupUUID.
|
||||
List<AccountGroup> toUpdate = Lists.newArrayListWithCapacity(idMap.size());
|
||||
for (Entry<AccountGroup.Id, AccountGroup.Id> entry : idMap.entrySet()) {
|
||||
AccountGroup group = groups.get(entry.getKey());
|
||||
AccountGroup owner = groups.get(entry.getValue());
|
||||
group.setOwnerGroupUUID(owner.getGroupUUID());
|
||||
toUpdate.add(group);
|
||||
}
|
||||
|
||||
db.accountGroups().update(toUpdate);
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class Schema_68 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_68(Provider<Schema_67> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(final ReviewDb db, final UpdateUI ui)
|
||||
throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
stmt.execute("CREATE INDEX submodule_subscription_access_bySubscription"
|
||||
+ " ON submodule_subscriptions (submodule_project_name, submodule_branch_name)");
|
||||
} catch (SQLException e) {
|
||||
// the index creation might have failed because the index exists already,
|
||||
// in this case the exception can be safely ignored,
|
||||
// but there are also other possible reasons for an exception here that
|
||||
// should not be ignored,
|
||||
// -> ask the user whether to ignore this exception or not
|
||||
ui.message("warning: Cannot create index for submodule subscriptions");
|
||||
ui.message(e.getMessage());
|
||||
|
||||
if (ui.isBatch()) {
|
||||
ui.message("you may ignore this warning when running in interactive mode");
|
||||
throw e;
|
||||
} else {
|
||||
final boolean answer = ui.yesno(false, "Ignore warning and proceed with schema upgrade");
|
||||
if (!answer) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
public class Schema_69 extends SchemaVersion {
|
||||
private final GitRepositoryManager mgr;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
@Inject
|
||||
Schema_69(Provider<Schema_68> prior,
|
||||
GitRepositoryManager mgr,
|
||||
@GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui)
|
||||
throws OrmException, SQLException {
|
||||
|
||||
// Find all groups that have an LDAP type.
|
||||
Map<AccountGroup.UUID, GroupReference> ldapUUIDMap = Maps.newHashMap();
|
||||
Set<AccountGroup.UUID> toResolve = Sets.newHashSet();
|
||||
List<AccountGroup.Id> toDelete = Lists.newArrayList();
|
||||
List<AccountGroup.NameKey> namesToDelete = Lists.newArrayList();
|
||||
try (Statement stmt = newStatement(db);
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT group_id, group_uuid, external_name, name FROM account_groups"
|
||||
+ " WHERE group_type ='LDAP'")) {
|
||||
while (rs.next()) {
|
||||
AccountGroup.Id groupId = new AccountGroup.Id(rs.getInt(1));
|
||||
AccountGroup.UUID groupUUID = new AccountGroup.UUID(rs.getString(2));
|
||||
AccountGroup.NameKey name = new AccountGroup.NameKey(rs.getString(4));
|
||||
String dn = rs.getString(3);
|
||||
|
||||
if (isNullOrEmpty(dn)) {
|
||||
// The LDAP group does not have a DN. Determine if the UUID is used.
|
||||
toResolve.add(groupUUID);
|
||||
} else {
|
||||
toDelete.add(groupId);
|
||||
namesToDelete.add(name);
|
||||
GroupReference ref = groupReference(dn);
|
||||
ldapUUIDMap.put(groupUUID, ref);
|
||||
}
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (toDelete.isEmpty() && toResolve.isEmpty()) {
|
||||
return; // No ldap groups. Nothing to do.
|
||||
}
|
||||
|
||||
ui.message("Update LDAP groups to be GroupReferences.");
|
||||
|
||||
// Update the groupOwnerUUID for LDAP groups to point to the new UUID.
|
||||
List<AccountGroup> toUpdate = Lists.newArrayList();
|
||||
Set<AccountGroup.UUID> resolveToUpdate = Sets.newHashSet();
|
||||
Map<AccountGroup.UUID, AccountGroup> resolveGroups = Maps.newHashMap();
|
||||
for (AccountGroup g : db.accountGroups().all()) {
|
||||
if (ldapUUIDMap.containsKey(g.getGroupUUID())) {
|
||||
continue; // Ignore the LDAP groups with a valid DN.
|
||||
} else if (toResolve.contains(g.getGroupUUID())) {
|
||||
resolveGroups.put(g.getGroupUUID(), g); // Keep the ones to resolve.
|
||||
continue;
|
||||
}
|
||||
|
||||
GroupReference ref = ldapUUIDMap.get(g.getOwnerGroupUUID());
|
||||
if (ref != null) {
|
||||
// Update the owner group UUID to the new ldap UUID scheme.
|
||||
g.setOwnerGroupUUID(ref.getUUID());
|
||||
toUpdate.add(g);
|
||||
} else if (toResolve.contains(g.getOwnerGroupUUID())) {
|
||||
// The unresolved group is used as an owner.
|
||||
// Add to the list of LDAP groups to be made INTERNAL.
|
||||
resolveToUpdate.add(g.getOwnerGroupUUID());
|
||||
}
|
||||
}
|
||||
|
||||
toResolve.removeAll(resolveToUpdate);
|
||||
|
||||
// Update project.config group references to use the new LDAP GroupReference
|
||||
for (Project.NameKey name : mgr.list()) {
|
||||
Repository git;
|
||||
try {
|
||||
git = mgr.openRepository(name);
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, name, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
|
||||
// Update the existing refences to the new reference.
|
||||
boolean updated = false;
|
||||
for (Map.Entry<AccountGroup.UUID, GroupReference> entry: ldapUUIDMap.entrySet()) {
|
||||
GroupReference ref = config.getGroup(entry.getKey());
|
||||
if (ref != null) {
|
||||
updated = true;
|
||||
ref.setName(entry.getValue().getName());
|
||||
ref.setUUID(entry.getValue().getUUID());
|
||||
config.resolve(ref);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if a toResolve group is used and should be made INTERNAL.
|
||||
Iterator<AccountGroup.UUID> iter = toResolve.iterator();
|
||||
while (iter.hasNext()) {
|
||||
AccountGroup.UUID uuid = iter.next();
|
||||
if (config.getGroup(uuid) != null) {
|
||||
resolveToUpdate.add(uuid);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
continue;
|
||||
}
|
||||
|
||||
md.setMessage("Switch LDAP group UUIDs to DNs\n");
|
||||
config.commit(md);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (ConfigInvalidException e) {
|
||||
throw new OrmException(e);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
|
||||
for (AccountGroup.UUID uuid : resolveToUpdate) {
|
||||
AccountGroup group = resolveGroups.get(uuid);
|
||||
ui.message(String.format(
|
||||
"*** Group has no DN and is in use: %s",
|
||||
group.getName()));
|
||||
}
|
||||
|
||||
for (AccountGroup.UUID uuid : toResolve) {
|
||||
AccountGroup group = resolveGroups.get(uuid);
|
||||
toDelete.add(group.getId());
|
||||
namesToDelete.add(group.getNameKey());
|
||||
}
|
||||
|
||||
// Update group owners
|
||||
db.accountGroups().update(toUpdate);
|
||||
// Delete existing LDAP groups
|
||||
db.accountGroupNames().deleteKeys(namesToDelete);
|
||||
db.accountGroups().deleteKeys(toDelete);
|
||||
}
|
||||
|
||||
private static GroupReference groupReference(String dn)
|
||||
throws NamingException {
|
||||
LdapName name = new LdapName(dn);
|
||||
Preconditions.checkState(!name.isEmpty(), "Invalid LDAP dn: %s", dn);
|
||||
String cn = name.get(name.size() - 1);
|
||||
int index = cn.indexOf('=');
|
||||
if (index >= 0) {
|
||||
cn = cn.substring(index + 1);
|
||||
}
|
||||
return new GroupReference(new AccountGroup.UUID("ldap:" + dn), "ldap/" + cn);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_70 extends SchemaVersion {
|
||||
@Inject
|
||||
protected Schema_70(Provider<Schema_69> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
|
||||
public class Schema_71 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_71(Provider<Schema_70> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(final ReviewDb db, final UpdateUI ui)
|
||||
throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
stmt.executeUpdate("UPDATE account_diff_preferences SET show_line_endings='Y'");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_72 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_72(Provider<Schema_71> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class Schema_73 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_73(Provider<Schema_72> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(final ReviewDb db, final UpdateUI ui)
|
||||
throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
stmt.executeUpdate("CREATE INDEX change_messages_byPatchset ON change_messages (patchset_change_id, patchset_patch_set_id )");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
// Copyright (C) 2012 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupById;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/* Handles copying all entries from AccountGroupIncludes(Audit) to the new tables */
|
||||
public class Schema_74 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_74(Provider<Schema_73> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(final ReviewDb db, final UpdateUI ui)
|
||||
throws SQLException, OrmException {
|
||||
// Grab all the groups since we don't have the cache available
|
||||
HashMap<AccountGroup.Id, AccountGroup.UUID> allGroups = new HashMap<>();
|
||||
for (AccountGroup ag : db.accountGroups().all()) {
|
||||
allGroups.put(ag.getId(), ag.getGroupUUID());
|
||||
}
|
||||
|
||||
// Initialize some variables
|
||||
ArrayList<AccountGroupById> newIncludes = new ArrayList<>();
|
||||
ArrayList<AccountGroupByIdAud> newIncludeAudits = new ArrayList<>();
|
||||
|
||||
// Iterate over all entries in account_group_includes
|
||||
try (Statement oldGroupIncludesStmt = newStatement(db);
|
||||
ResultSet oldGroupIncludes = oldGroupIncludesStmt.executeQuery(
|
||||
"SELECT * FROM account_group_includes")) {
|
||||
while (oldGroupIncludes.next()) {
|
||||
AccountGroup.Id oldGroupId =
|
||||
new AccountGroup.Id(oldGroupIncludes.getInt("group_id"));
|
||||
AccountGroup.Id oldIncludeId =
|
||||
new AccountGroup.Id(oldGroupIncludes.getInt("include_id"));
|
||||
AccountGroup.UUID uuidFromIncludeId = allGroups.get(oldIncludeId);
|
||||
|
||||
// If we've got an include, but the group no longer exists, don't bother converting
|
||||
if (uuidFromIncludeId == null) {
|
||||
ui.message("Skipping group_id = \"" + oldIncludeId.get() +
|
||||
"\", not a current group");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create the new include entry
|
||||
AccountGroupById destIncludeEntry = new AccountGroupById(
|
||||
new AccountGroupById.Key(oldGroupId, uuidFromIncludeId));
|
||||
|
||||
// Iterate over all the audits (for this group)
|
||||
try (PreparedStatement oldAuditsQueryStmt = prepareStatement(db,
|
||||
"SELECT * FROM account_group_includes_audit WHERE group_id=? AND include_id=?")) {
|
||||
oldAuditsQueryStmt.setInt(1, oldGroupId.get());
|
||||
oldAuditsQueryStmt.setInt(2, oldIncludeId.get());
|
||||
try (ResultSet oldGroupIncludeAudits = oldAuditsQueryStmt.executeQuery()) {
|
||||
while (oldGroupIncludeAudits.next()) {
|
||||
Account.Id addedBy = new Account.Id(oldGroupIncludeAudits.getInt("added_by"));
|
||||
int removedBy = oldGroupIncludeAudits.getInt("removed_by");
|
||||
|
||||
// Create the new audit entry
|
||||
AccountGroupByIdAud destAuditEntry =
|
||||
new AccountGroupByIdAud(destIncludeEntry, addedBy,
|
||||
oldGroupIncludeAudits.getTimestamp("added_on"));
|
||||
|
||||
// If this was a "removed on" entry, note that
|
||||
if (removedBy > 0) {
|
||||
destAuditEntry.removed(new Account.Id(removedBy),
|
||||
oldGroupIncludeAudits.getTimestamp("removed_on"));
|
||||
}
|
||||
newIncludeAudits.add(destAuditEntry);
|
||||
}
|
||||
}
|
||||
newIncludes.add(destIncludeEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now insert all of the new entries to the database
|
||||
db.accountGroupById().insert(newIncludes);
|
||||
db.accountGroupByIdAud().insert(newIncludeAudits);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_75 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_75(Provider<Schema_74> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_76 extends SchemaVersion {
|
||||
@Inject
|
||||
Schema_76(Provider<Schema_75> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,241 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.common.data.LabelType;
|
||||
import com.google.gerrit.common.data.LabelTypes;
|
||||
import com.google.gerrit.common.data.LabelValue;
|
||||
import com.google.gerrit.reviewdb.client.LabelId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||
import com.google.gwtorm.schema.sql.DialectH2;
|
||||
import com.google.gwtorm.schema.sql.DialectMySQL;
|
||||
import com.google.gwtorm.schema.sql.DialectPostgreSQL;
|
||||
import com.google.gwtorm.schema.sql.SqlDialect;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Schema_77 extends SchemaVersion {
|
||||
private final GitRepositoryManager mgr;
|
||||
private final AllProjectsName allProjects;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
@Inject
|
||||
Schema_77(Provider<Schema_76> prior, AllProjectsName allProjects,
|
||||
GitRepositoryManager mgr, @GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.allProjects = allProjects;
|
||||
this.mgr = mgr;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
|
||||
try {
|
||||
LegacyLabelTypes labelTypes = getLegacyTypes(db);
|
||||
SqlDialect dialect = ((JdbcSchema) db).getDialect();
|
||||
if (dialect instanceof DialectH2) {
|
||||
alterTable(db, "ALTER TABLE %s ALTER COLUMN %s varchar(255)");
|
||||
} else if (dialect instanceof DialectPostgreSQL) {
|
||||
alterTable(db, "ALTER TABLE %s ALTER %s TYPE varchar(255)");
|
||||
} else if (dialect instanceof DialectMySQL) {
|
||||
alterTable(db, "ALTER TABLE %s MODIFY %s varchar(255) BINARY");
|
||||
} else {
|
||||
alterTable(db, "ALTER TABLE %s MODIFY %s varchar(255)");
|
||||
}
|
||||
migratePatchSetApprovals(db, labelTypes);
|
||||
migrateLabelsToAllProjects(labelTypes);
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (SQLException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (IOException e) {
|
||||
throw new OrmException(e);
|
||||
} catch (ConfigInvalidException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
ui.message(
|
||||
"Migrated label types from database to All-Projects project.config");
|
||||
}
|
||||
|
||||
private void alterTable(ReviewDb db, String sqlFormat) throws SQLException {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
stmt.executeUpdate(
|
||||
String.format(sqlFormat, "patch_set_approvals", "category_id"));
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateLabelsToAllProjects(LegacyLabelTypes labelTypes)
|
||||
throws RepositoryNotFoundException, IOException, ConfigInvalidException {
|
||||
Repository git = mgr.openRepository(allProjects);
|
||||
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
Map<String, LabelType> configTypes = config.getLabelSections();
|
||||
List<LabelType> newTypes = Lists.newArrayList();
|
||||
for (LegacyLabelType type : labelTypes.getLegacyLabelTypes()) {
|
||||
if (!configTypes.containsKey(type.getName())) {
|
||||
newTypes.add(type);
|
||||
}
|
||||
}
|
||||
newTypes.addAll(configTypes.values());
|
||||
configTypes.clear();
|
||||
for (LabelType type : newTypes) {
|
||||
configTypes.put(type.getName(), type);
|
||||
}
|
||||
md.setMessage("Upgrade to Gerrit Code Review schema 77\n");
|
||||
config.commit(md);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void migratePatchSetApprovals(ReviewDb db,
|
||||
LegacyLabelTypes labelTypes) throws SQLException {
|
||||
try (PreparedStatement stmt = prepareStatement(db,
|
||||
"UPDATE patch_set_approvals SET category_id = ?, granted=granted"
|
||||
+ " WHERE category_id = ?")) {
|
||||
for (LegacyLabelType type : labelTypes.getLegacyLabelTypes()) {
|
||||
stmt.setString(1, type.getName());
|
||||
stmt.setString(2, type.getId());
|
||||
stmt.addBatch();
|
||||
}
|
||||
stmt.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
static class LegacyLabelType extends LabelType {
|
||||
private String id;
|
||||
|
||||
private LegacyLabelType(String name, List<LabelValue> values) {
|
||||
super(name, values);
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
private void setId(String id) {
|
||||
checkArgument(id.length() <= 4, "Invalid legacy label ID: \"%s\"", id);
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
static class LegacyLabelTypes extends LabelTypes {
|
||||
private final List<LegacyLabelType> legacyTypes;
|
||||
|
||||
private final Map<String, LegacyLabelType> byId;
|
||||
|
||||
private LegacyLabelTypes(List<LegacyLabelType> types) {
|
||||
super(types);
|
||||
legacyTypes = types;
|
||||
byId = Maps.newHashMap();
|
||||
for (LegacyLabelType type : types) {
|
||||
byId.put(type.getId(), type);
|
||||
}
|
||||
}
|
||||
|
||||
List<LegacyLabelType> getLegacyLabelTypes() {
|
||||
return legacyTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegacyLabelType byLabel(LabelId labelId) {
|
||||
LegacyLabelType t = byId.get(labelId.get());
|
||||
return t != null ? t : (LegacyLabelType) super.byLabel(labelId);
|
||||
}
|
||||
|
||||
LegacyLabelType byId(LabelId id) {
|
||||
return byId.get(id.get());
|
||||
}
|
||||
}
|
||||
|
||||
static LegacyLabelTypes getLegacyTypes(ReviewDb db) throws SQLException {
|
||||
List<LegacyLabelType> types = Lists.newArrayListWithCapacity(2);
|
||||
try (Statement catStmt = newStatement(db);
|
||||
ResultSet catRs = catStmt.executeQuery(
|
||||
"SELECT category_id, name, function_name, copy_min_score"
|
||||
+ " FROM approval_categories"
|
||||
+ " ORDER BY position, name");
|
||||
PreparedStatement valStmt = prepareStatement(db,
|
||||
"SELECT value, name"
|
||||
+ " FROM approval_category_values"
|
||||
+ " WHERE category_id = ?")) {
|
||||
while (catRs.next()) {
|
||||
String id = catRs.getString("category_id");
|
||||
valStmt.setString(1, id);
|
||||
List<LabelValue> values = Lists.newArrayListWithCapacity(5);
|
||||
try (ResultSet valRs = valStmt.executeQuery()) {
|
||||
while (valRs.next()) {
|
||||
values.add(new LabelValue(
|
||||
valRs.getShort("value"), valRs.getString("name")));
|
||||
}
|
||||
}
|
||||
LegacyLabelType type =
|
||||
new LegacyLabelType(getLabelName(catRs.getString("name")), values);
|
||||
type.setId(id);
|
||||
type.setFunctionName(catRs.getString("function_name"));
|
||||
type.setCopyMinScore("Y".equals(catRs.getString("copy_min_score")));
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
return new LegacyLabelTypes(types);
|
||||
}
|
||||
|
||||
private static String getLabelName(String name) {
|
||||
StringBuilder r = new StringBuilder();
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (('0' <= c && c <= '9') //
|
||||
|| ('a' <= c && c <= 'z') //
|
||||
|| ('A' <= c && c <= 'Z') //
|
||||
|| (c == '-')) {
|
||||
r.append(c);
|
||||
} else if (c == ' ') {
|
||||
r.append('-');
|
||||
}
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_78 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_78(Provider<Schema_77> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_79 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_79(Provider<Schema_78> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class Schema_80 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_80(Provider<Schema_79> prior) {
|
||||
super(prior);
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.Permission;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.SitePaths;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class Schema_81 extends SchemaVersion {
|
||||
|
||||
private final File pluginsDir;
|
||||
private final GitRepositoryManager mgr;
|
||||
private final AllProjectsName allProjects;
|
||||
private final PersonIdent serverUser;
|
||||
|
||||
@Inject
|
||||
Schema_81(Provider<Schema_80> prior, SitePaths sitePaths,
|
||||
AllProjectsName allProjects, GitRepositoryManager mgr,
|
||||
@GerritPersonIdent PersonIdent serverUser) {
|
||||
super(prior);
|
||||
this.pluginsDir = sitePaths.plugins_dir;
|
||||
this.mgr = mgr;
|
||||
this.allProjects = allProjects;
|
||||
this.serverUser = serverUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
|
||||
SQLException {
|
||||
try {
|
||||
migrateStartReplicationCapability(scanForReplicationPlugin());
|
||||
} catch (IOException | ConfigInvalidException e) {
|
||||
throw new OrmException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private File[] scanForReplicationPlugin() {
|
||||
File[] matches = null;
|
||||
if (pluginsDir != null && pluginsDir.exists()) {
|
||||
matches = pluginsDir.listFiles(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
String n = pathname.getName();
|
||||
return (n.endsWith(".jar") || n.endsWith(".jar.disabled"))
|
||||
&& pathname.isFile() && n.contains("replication");
|
||||
}
|
||||
});
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
private void migrateStartReplicationCapability(File[] matches)
|
||||
throws RepositoryNotFoundException, IOException, ConfigInvalidException {
|
||||
Description d = new Description();
|
||||
if (matches == null || matches.length == 0) {
|
||||
d.what = Description.Action.REMOVE;
|
||||
} else {
|
||||
d.what = Description.Action.RENAME;
|
||||
d.prefix = nameOf(matches[0]);
|
||||
}
|
||||
migrateStartReplicationCapability(d);
|
||||
}
|
||||
|
||||
private void migrateStartReplicationCapability(Description d)
|
||||
throws RepositoryNotFoundException, IOException,
|
||||
ConfigInvalidException {
|
||||
Repository git = mgr.openRepository(allProjects);
|
||||
try {
|
||||
MetaDataUpdate md =
|
||||
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||
md.getCommitBuilder().setAuthor(serverUser);
|
||||
md.getCommitBuilder().setCommitter(serverUser);
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
AccessSection capabilities =
|
||||
config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES);
|
||||
Permission startReplication =
|
||||
capabilities.getPermission("startReplication");
|
||||
if (startReplication == null) {
|
||||
return;
|
||||
}
|
||||
String msg = null;
|
||||
switch (d.what) {
|
||||
case REMOVE:
|
||||
capabilities.remove(startReplication);
|
||||
msg = "Remove startReplication capability, plugin not installed\n";
|
||||
break;
|
||||
case RENAME:
|
||||
capabilities.remove(startReplication);
|
||||
Permission pluginStartReplication =
|
||||
capabilities.getPermission(
|
||||
String.format("%s-startReplication", d.prefix), true);
|
||||
pluginStartReplication.setRules(startReplication.getRules());
|
||||
msg = "Rename startReplication capability to match updated plugin\n";
|
||||
break;
|
||||
}
|
||||
config.replace(capabilities);
|
||||
md.setMessage(msg);
|
||||
config.commit(md);
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static String nameOf(File jar) {
|
||||
String name = jar.getName();
|
||||
if (name.endsWith(".disabled")) {
|
||||
name = name.substring(0, name.lastIndexOf('.'));
|
||||
}
|
||||
int ext = name.lastIndexOf('.');
|
||||
return 0 < ext ? name.substring(0, ext) : name;
|
||||
}
|
||||
|
||||
private static class Description {
|
||||
private enum Action {
|
||||
REMOVE, RENAME
|
||||
}
|
||||
Action what;
|
||||
String prefix;
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gwtorm.jdbc.JdbcExecutor;
|
||||
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||
import com.google.gwtorm.schema.sql.DialectMySQL;
|
||||
import com.google.gwtorm.schema.sql.SqlDialect;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.StatementExecutor;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Schema_82 extends SchemaVersion {
|
||||
|
||||
private Map<String,String> tables = ImmutableMap.of(
|
||||
"account_group_includes_by_uuid", "account_group_by_id",
|
||||
"account_group_includes_by_uuid_audit", "account_group_by_id_aud");
|
||||
|
||||
private Map<String,Index> indexes = ImmutableMap.of(
|
||||
"account_project_watches_byProject",
|
||||
new Index("account_project_watches", "account_project_watches_byP"),
|
||||
"patch_set_approvals_closedByUser",
|
||||
new Index("patch_set_approvals", "patch_set_approvals_closedByU"),
|
||||
"submodule_subscription_access_bySubscription",
|
||||
new Index("submodule_subscriptions", "submodule_subscr_acc_byS")
|
||||
);
|
||||
|
||||
@Inject
|
||||
Schema_82(Provider<Schema_81> prior) {
|
||||
super(prior);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preUpdateSchema(ReviewDb db) throws OrmException, SQLException {
|
||||
JdbcSchema s = (JdbcSchema) db;
|
||||
try (JdbcExecutor e = new JdbcExecutor(s)) {
|
||||
renameTables(db, s, e);
|
||||
renameColumn(db, s, e);
|
||||
}
|
||||
renameIndexes(db);
|
||||
}
|
||||
|
||||
private void renameTables(final ReviewDb db, final JdbcSchema s,
|
||||
final JdbcExecutor e) throws OrmException, SQLException {
|
||||
SqlDialect dialect = ((JdbcSchema) db).getDialect();
|
||||
final Set<String> existingTables = dialect.listTables(s.getConnection());
|
||||
for (Map.Entry<String, String> entry : tables.entrySet()) {
|
||||
// Does source table exist?
|
||||
if (existingTables.contains(entry.getKey())) {
|
||||
// Does target table exist?
|
||||
if (!existingTables.contains(entry.getValue())) {
|
||||
s.renameTable(e, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renameColumn(final ReviewDb db, final JdbcSchema s,
|
||||
final JdbcExecutor e) throws SQLException, OrmException {
|
||||
SqlDialect dialect = ((JdbcSchema) db).getDialect();
|
||||
final Set<String> existingColumns =
|
||||
dialect.listColumns(s.getConnection(), "accounts");
|
||||
// Does source column exist?
|
||||
if (!existingColumns.contains("show_username_in_review_category")) {
|
||||
return;
|
||||
}
|
||||
// Does target column exist?
|
||||
if (existingColumns.contains("show_user_in_review")) {
|
||||
return;
|
||||
}
|
||||
s.renameColumn(e, "accounts", "show_username_in_review_category",
|
||||
"show_user_in_review");
|
||||
// MySQL loose check constraint during the column renaming.
|
||||
// Well it doesn't implemented anyway,
|
||||
// check constraints are get parsed but do nothing
|
||||
if (dialect instanceof DialectMySQL) {
|
||||
try (Statement stmt = newStatement(db)) {
|
||||
addCheckConstraint(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renameIndexes(ReviewDb db) {
|
||||
SqlDialect dialect = ((JdbcSchema) db).getDialect();
|
||||
// Use a new executor so we can ignore errors.
|
||||
try (StatementExecutor e = newExecutor(db)) {
|
||||
// MySQL doesn't have alter index stmt, drop & create
|
||||
if (dialect instanceof DialectMySQL) {
|
||||
for (Map.Entry<String, Index> entry : indexes.entrySet()) {
|
||||
dialect.dropIndex(e, entry.getValue().table, entry.getKey());
|
||||
}
|
||||
e.execute("CREATE INDEX account_project_watches_byP ON " +
|
||||
"account_project_watches (project_name)");
|
||||
e.execute("CREATE INDEX patch_set_approvals_closedByU ON " +
|
||||
"patch_set_approvals (change_open, account_id, change_sort_key)");
|
||||
e.execute("CREATE INDEX submodule_subscr_acc_bys ON " +
|
||||
"submodule_subscriptions (submodule_project_name, " +
|
||||
"submodule_branch_name)");
|
||||
} else {
|
||||
for (Map.Entry<String, Index> entry : indexes.entrySet()) {
|
||||
e.execute("ALTER INDEX " + entry.getKey() + " RENAME TO "
|
||||
+ entry.getValue().index);
|
||||
}
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
// We don't care; better, we could check if index was already renamed, but
|
||||
// gwtorm didn't expose this functionality at the time this schema upgrade
|
||||
// was written.
|
||||
}
|
||||
}
|
||||
|
||||
private void addCheckConstraint(Statement stmt) throws SQLException {
|
||||
// add check constraint for the destination column
|
||||
stmt.executeUpdate("ALTER TABLE accounts ADD CONSTRAINT "
|
||||
+ "show_user_in_review_check CHECK "
|
||||
+ "(show_user_in_review IN('Y', 'N'))");
|
||||
}
|
||||
|
||||
static class Index {
|
||||
String table;
|
||||
String index;
|
||||
|
||||
Index(String tableName, String indexName) {
|
||||
this.table = tableName;
|
||||
this.index = indexName;
|
||||
}
|
||||
}
|
||||
}
|
@ -16,11 +16,17 @@ package com.google.gerrit.server.schema;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
|
||||
public class Schema_83 extends SchemaVersion {
|
||||
|
||||
@Inject
|
||||
Schema_83(Provider<Schema_82> prior) {
|
||||
super(prior);
|
||||
Schema_83() {
|
||||
super(new Provider<SchemaVersion>() {
|
||||
@Override
|
||||
public SchemaVersion get() {
|
||||
throw new ProvisionException("Upgrade first to 2.8 or 2.9");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user