Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This is only possible for “Split Mongo” courses, i.e. those whose course keys are in the form with course-v1:ORG+COURSE+RUN. It is not possible to restore an a deprecated “Old Mongo” course, i.e. those whose course keys are in the form ORG/COURSE/RUN.

...

Unfortunately, there is no way to undo destructive changes via the Studio UI. So, stop editing the course. Close Studio.

...

edXers: versions are more likely to be pruned (permanently deleted) if they are further back (~10 versions) in the version chain. Pruning generally occurs weekly on Sunday, via automated jobs (which can be paused as necessary). If it’s getting close to Sunday, then the urgency of this is higher.

edX engineers: Contact SRE and have them pause the modulestore pruning job for correct environment.

Communication

TODO: This section could use input from Partner Support.

...

The restoration process has two steps: find the ID of the correct version, and then tell modulestore to point the course run at that version.

1. Find the

...

correct version

...

via the MongoDB shell

Currently, there’s no easy way to introspect course run versions via Studio. So, we need to dive into a MongoDB shell. Ideally, this shell should be read-only, as we don’t want to be making any edits to Mongo here by accident.

...

Once in the shell, run use edxapp. Then, copy this entire script in, substituting in the correct values of for ORG, COURSE, and RUN at the top.

Code Block
languagejs
var ORG = "...";
var COURSE = "...";
var RUN = "...";

function getLatestCourseStructure(org, course, run) {
	var courseIndex = db.modulestore.active_versions.findOne({
		org: org, course: course, run: run
	});
	return db.modulestore.structures.findOne({
		_id: courseIndex.versions["draft-branch"]
	});
}

function structureToCourseTitle(structure) {
	var rootCourseBlock = structure.blocks.find(function(block) {
		return (
			block.block_type === structure.root[0] &&
			block.block_id === structure.root[1]
		)
	});
	return rootCourseBlock.fields.display_name;
}

function examineStructure(structure) {
	return (
		"  version_guid = " + structure._id + "\n" +
		"  title		= " + structureToCourseTitle(structure) + "\n" +
		"  edited_on	= " + structure.edited_on
	);
}

function lookBackNVersions(structure, numVersionsBack) {
	for (var i = 0; i < numVersionsBack; i++) {
		structure = db.modulestore.structures.findOne({
			_id: structure.previous_version
		})
		if (!structure) return null;
	}
	return structure;
}

function examineAllAvailableVersions(structure) {
	var output = "";
	output += "Current version:\n";
	output += examineStructure(structure) + "\n";

	for (var i = 1; ; i++) {
		var olderStructure = lookBackNVersions(structure, i);
		if (!olderStructure) break;

		output += "\n";
		output += i + " version(s) back:\n";
		output += examineStructure(olderStructure) + "\n";
	}

	output += "\n";
	output += "Showing all available (non-pruned) versions."
	return output;
}

var latestCourseStructure = getLatestCourseStructure(ORG, COURSE, RUN);
examineAllAvailableVersions(latestCourseStructure);

...

Code Block
> examineAllAvailableVersions(latestCourseStructure);
Current version:
  version_guid = 5fbc16d7a9e30dc3e5a2eef4
  title        = Demonstration Course
  edited_on    = Mon Nov 23 2020 20:08:55 GMT+0000 (UTC)

1 version(s) back:
  version_guid = 5f19c8940ed7e0e9d7044419
  title        = Demonstration Course
  edited_on    = Thu Jul 23 2020 17:27:48 GMT+0000 (UTC)

2 version(s) back:
  version_guid = 5f19c8890ed7e0e9d7043a40
  title        = Demonstration Course
  edited_on    = Thu Jul 23 2020 17:27:37 GMT+0000 (UTC)

3 version(s) back:
  version_guid = 5f19c8890ed7e0e9d7043a3a
  title        = undefined
  edited_on    = Thu Jul 23 2020 17:27:37 GMT+0000 (UTC)

Showing all available (non-pruned) versions.

...