Explorar el Código

Merge pull request #812 from sharelatex/bg-allow-changing-texlive-image

allow changing texlive image (connects to overleaf/sharelatex#756)
Brian Gough hace 8 años
padre
commit
791d395655

+ 7 - 0
services/web/app/coffee/Features/Editor/EditorController.coffee

@@ -163,6 +163,13 @@ module.exports = EditorController =
 			EditorRealTimeController.emitToRoom project_id, 'compilerUpdated', compiler
 			callback()
 
+	setImageName : (project_id, imageName, callback = (err) ->) ->
+		ProjectOptionsHandler.setImageName project_id, imageName, (err) ->
+			return callback(err) if err?
+			logger.log imageName:imageName, project_id:project_id, "setting imageName"
+			EditorRealTimeController.emitToRoom project_id, 'imageNameUpdated', imageName
+			callback()
+
 	setSpellCheckLanguage : (project_id, languageCode, callback = (err) ->) ->
 		ProjectOptionsHandler.setSpellCheckLanguage project_id, languageCode, (err) ->
 			return callback(err) if err?

+ 5 - 0
services/web/app/coffee/Features/Project/ProjectController.coffee

@@ -49,6 +49,10 @@ module.exports = ProjectController =
 			jobs.push (callback) ->
 				editorController.setCompiler project_id, req.body.compiler, callback
 
+		if req.body.imageName?
+			jobs.push (callback) ->
+				editorController.setImageName project_id, req.body.imageName, callback
+
 		if req.body.name?
 			jobs.push (callback) ->
 				editorController.renameProject project_id, req.body.name, callback
@@ -347,6 +351,7 @@ module.exports = ProjectController =
 					useV2History: !!project.overleaf?.history?.display
 					richTextEnabled: Features.hasFeature('rich-text')
 					showTestControls: req.query?.tc == 'true' || user.isAdmin
+					allowedImageNames: Settings.allowedImageNames || []
 				timer.done()
 
 	_buildProjectList: (allProjects, v1Projects = [])->

+ 2 - 1
services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee

@@ -1,5 +1,5 @@
 _ = require("underscore")
-
+Path = require 'path'
 
 module.exports = ProjectEditorHandler =
 	trackChangesAvailable: false
@@ -20,6 +20,7 @@ module.exports = ProjectEditorHandler =
 			members:     []
 			invites:     invites
 			tokens:      project.tokens
+			imageName:   if project.imageName? then Path.basename(project.imageName) else undefined
 
 		if !result.invites?
 			result.invites = []

+ 10 - 0
services/web/app/coffee/Features/Project/ProjectOptionsHandler.coffee

@@ -17,6 +17,16 @@ module.exports =
 			if callback?
 				callback()
 
+	setImageName : (project_id, imageName, callback = ()->)->
+		logger.log project_id:project_id, imageName:imageName, "setting the imageName"
+		imageName = imageName.toLowerCase()
+		if ! _.some(settings.allowedImageNames, (allowed) -> imageName is allowed.imageName)
+			return callback()
+		conditions = {_id:project_id}
+		update = {imageName: settings.imageRoot + '/' + imageName}
+		Project.update conditions, update, {}, (err)->
+			if callback?
+				callback()
 
 	setSpellCheckLanguage: (project_id, languageCode, callback = ()->)->
 		logger.log project_id:project_id, languageCode:languageCode, "setting the spell check language"

+ 9 - 0
services/web/app/views/project/editor/left-menu.pug

@@ -188,6 +188,15 @@ aside#left-menu.full-size(
 					option(value="pdfjs") #{translate("built_in")}
 					option(value="native") #{translate("native")}
 
+			if (getSessionUser() && getSessionUser().isAdmin && typeof(allowedImageNames) !== 'undefined' && allowedImageNames.length > 0)
+				.form-controls(ng-show="permissions.write")
+					label(for="imageName") #{translate("TeXLive")}
+					select(
+						name="imageName"
+						ng-model="project.imageName"
+					)
+						each image in allowedImageNames
+							option(value=image.imageName) #{image.imageDesc}
 
 	h4 #{translate("hotkeys")}
 	ul.list-unstyled.nav

+ 11 - 0
services/web/config/settings.defaults.coffee

@@ -472,3 +472,14 @@ module.exports = settings =
 		autoCompile:
 			everyone: 100
 			standard: 25
+
+	# currentImage: "texlive-full:2017.1"
+	# imageRoot: "<DOCKER REPOSITORY ROOT>" # without any trailing slash
+	
+	# allowedImageNames: [
+	# 	{imageName: 'texlive-full:2017.1', imageDesc: 'TeXLive 2017'}
+	# 	{imageName:   'wl_texlive:2018.1', imageDesc: 'Legacy OL TeXLive 2015'}
+	# 	{imageName: 'texlive-full:2016.1', imageDesc: 'Legacy SL TeXLive 2016'}
+	# 	{imageName: 'texlive-full:2015.1', imageDesc: 'Legacy SL TeXLive 2015'}
+	# 	{imageName: 'texlive-full:2014.2', imageDesc: 'Legacy SL TeXLive 2014.2'}
+	# ]

+ 11 - 0
services/web/public/coffee/ide/settings/controllers/SettingsController.coffee

@@ -67,6 +67,11 @@ define [
 			if oldCompiler? and compiler != oldCompiler
 				settings.saveProjectSettings({compiler: compiler})
 
+		$scope.$watch "project.imageName", (imageName, oldImageName) =>
+			return if @ignoreUpdates
+			if oldImageName? and imageName != oldImageName
+				settings.saveProjectSettings({imageName: imageName})
+
 		$scope.$watch "project.rootDoc_id", (rootDoc_id, oldRootDoc_id) =>
 			return if @ignoreUpdates
 			# don't save on initialisation, Angular passes oldRootDoc_id as
@@ -83,6 +88,12 @@ define [
 				$scope.project.compiler = compiler
 			delete @ignoreUpdates
 
+		ide.socket.on "imageNameUpdated", (imageName) =>
+			@ignoreUpdates = true
+			$scope.$apply () =>
+				$scope.project.imageName = imageName
+			delete @ignoreUpdates
+
 		ide.socket.on "spellCheckLanguageUpdated", (languageCode) =>
 			@ignoreUpdates = true
 			$scope.$apply () =>

+ 14 - 0
services/web/test/unit/coffee/Editor/EditorControllerTests.coffee

@@ -32,6 +32,7 @@ describe "EditorController", ->
 			'../Project/ProjectEntityUpdateHandler' : @ProjectEntityUpdateHandler = {}
 			'../Project/ProjectOptionsHandler' : @ProjectOptionsHandler =
 				setCompiler: sinon.stub().yields()
+				setImageName: sinon.stub().yields()
 				setSpellCheckLanguage: sinon.stub().yields()
 			'../Project/ProjectDetailsHandler': @ProjectDetailsHandler =
 				setProjectDescription: sinon.stub().yields()
@@ -377,6 +378,19 @@ describe "EditorController", ->
 				.calledWith(@project_id, "compilerUpdated", @compiler)
 				.should.equal true
 
+	describe "setImageName", ->
+		beforeEach ->
+			@imageName = "texlive-1234.5"
+			@EditorController.setImageName @project_id, @imageName, @callback
+
+		it "should send the new imageName and project id to the project options handler", ->
+			@ProjectOptionsHandler.setImageName
+				.calledWith(@project_id, @imageName)
+				.should.equal true
+			@EditorRealTimeController.emitToRoom
+				.calledWith(@project_id, "imageNameUpdated", @imageName)
+				.should.equal true
+
 	describe "setSpellCheckLanguage", ->
 		beforeEach ->
 			@languageCode = "fr"

+ 12 - 0
services/web/test/unit/coffee/Project/ProjectControllerTests.coffee

@@ -145,6 +145,18 @@ describe "ProjectController", ->
 				done()
 			@ProjectController.updateProjectSettings @req, @res
 
+		it "should update the imageName", (done) ->
+			@EditorController.setImageName = sinon.stub().callsArg(2)
+			@req.body =
+				imageName: @imageName = "texlive-1234.5"
+			@res.sendStatus = (code) =>
+				@EditorController.setImageName
+					.calledWith(@project_id, @imageName)
+					.should.equal true
+				code.should.equal 204
+				done()
+			@ProjectController.updateProjectSettings @req, @res
+
 		it "should update the spell check language", (done) ->
 			@EditorController.setSpellCheckLanguage = sinon.stub().callsArg(2)
 			@req.body =

+ 18 - 0
services/web/test/unit/coffee/Project/ProjectOptionsHandlerTests.coffee

@@ -19,6 +19,11 @@ describe 'creating a project', ->
 					{name: "English", code: "en"}
 					{name: "French", code: "fr"}
 				]
+				imageRoot: "docker-repo/subdir"
+				allowedImageNames: [
+					{imageName: "texlive-0000.0", imageDesc: "test image 0"}
+					{imageName: "texlive-1234.5", imageDesc: "test image 1"}
+				]
 			'logger-sharelatex':
 				log:->
 				err:->
@@ -37,6 +42,19 @@ describe 'creating a project', ->
 				@projectModel.update.called.should.equal false
 				done()
 
+	describe 'Setting the imageName', ->
+		it 'should perform and update on mongo', (done)->
+			@handler.setImageName project_id, "texlive-1234.5", (err)=>
+				args = @projectModel.update.args[0]
+				args[0]._id.should.equal project_id
+				args[1].imageName.should.equal "docker-repo/subdir/texlive-1234.5"
+				done()
+			@projectModel.update.args[0][3]()
+
+		it 'should not perform and update on mongo if it is not a reconised compiler', (done)->
+			@handler.setImageName project_id, "something", (err)=>
+				@projectModel.update.called.should.equal false
+				done()
 
 	describe "setting the spellCheckLanguage", ->