Пример #1
0
func createBuildFile(s *WorkerState) {
	var buildFileBaseName string
	switch OperatingSystem {
	case "Windows":
		buildFileBaseName = "build.bat"
	default:
		buildFileBaseName = "build.sh"
	}
	buildFile := filepath.Join(s.TemporaryDirectory, buildFileBaseName)
	fo, err := os.Create(buildFile)
	if err != nil {
		stats.Log("Worker", "Error", "Failed to create build file")
		panic("Failed to create build file")
	}
	defer func() {
		if fo.Close() != nil {
			stats.Log("Worker", "Error", "Failed to close build file")
			panic("Failed to close build file")
		}
	}()
	compileCommand := makeCompileCommand(s)
	if _, err = fo.Write([]byte(compileCommand)); err != nil {
		stats.Log("Worker", "Error", "Failed to write build file")
		panic("Failed to write build file")
	}
	os.Chmod(buildFile, 0777)
	s.BuildFileName = buildFile
}
Пример #2
0
func createTempDir(s *WorkerState) {
	runId := strings.Replace(s.RunId, "-", "", -1)
	tmpDir1, runId := runId[:5], runId[5:]
	tmpDir2, runId := runId[:5], runId[5:]
	tmp := filepath.Join(SystemTemporaryDirectory, tmpDir1, tmpDir2, "wb"+runId)
	if !directoryExists(tmp) {
		if err := os.MkdirAll(tmp, 0777); err != nil {
			stats.Log("Worker", "Error", "Failed to create temporary directory")
			panic("Failed to create tempDir")
		}
		stats.Log("Worker", "CreateTemporaryDirectory", tmp)
		s.TemporaryDirectory = tmp
		return
	}

	create := func() bool {
		idx := <-Uniq
		tmp := filepath.Join(SystemTemporaryDirectory, "wb"+fmt.Sprint(idx))
		if directoryExists(tmp) {
			return false
		}
		if err := os.MkdirAll(tmp, 0777); err != nil {
			stats.Log("Worker", "Error", "Failed to create temporary directory")
			panic("Failed to create tempDir")
		}
		stats.Log("Worker", "CreateTemporaryDirectory", tmp)
		s.TemporaryDirectory = tmp
		return true
	}
	for create() == false {
	}
}
Пример #3
0
func CompileAndRun(req *WorkerRequest) (res []WorkerState) {

	stats.Incr("Worker", "Compilations")

	conf, _ := ReadMachineProblemConfig(req.MachineProblemNumber)

	stats.Log("Worker", "CompileMP", "MP"+
		strconv.Itoa(req.MachineProblemNumber))
	stats.Log("Worker", "DatasetRun", "MP"+
		strconv.Itoa(req.MachineProblemNumber)+"::"+
		strconv.Itoa(req.DatasetId))

	if req.DatasetId == -1 && len(conf.Datasets) != 0 {
		res = make([]WorkerState, len(conf.Datasets))
		s := compile(req, 0)
		s.OnAllDatasets = true

		for i := range conf.Datasets {
			res[i] = *s
			res[i].DatasetId = i
			run(&res[i])
		}

		/*
			if directoryExists(s.TemporaryDirectory) {
				go func() {
					os.RemoveAll(s.TemporaryDirectory)
				}()
			}
		*/
	} else {
		res = make([]WorkerState, 1)
		s := compile(req, req.DatasetId)
		if req.DatasetId == -1 {
			s.OnAllDatasets = true
		} else {
			s.OnAllDatasets = false
		}
		run(s)
		res[0] = *s

		/*
			if directoryExists(s.TemporaryDirectory) {
				go func() {
					os.RemoveAll(s.TemporaryDirectory)
				}()
			}
		*/
	}
	return
}
Пример #4
0
func checkSandbox(s *WorkerState) {
	s.SandboxKeyword, s.Sandboxed = IsSandboxed(s.Program)
	if s.Sandboxed {
		stats.Log("Worker", "Sandboxed", s.SandboxKeyword)
		panic("Failed in sandbox")
	}
}
Пример #5
0
func (c CourseraApplication) LTIAuthenticate() revel.Result {
	var values string
	var form string
	var userid string

	user := c.connected()
	if user.Id == 0 {
		c.Flash.Error("Must log in before connecting user to coursera")
		return c.Redirect(routes.PublicApplication.Login())
	}

	c.Params.Bind(&values, "Values")
	c.Params.Bind(&form, "Form")
	c.Params.Bind(&userid, "user_id")

	if userid == "" {
		c.Flash.Error("Cannot get user identity from coursera!")
		stats.Incr("User", "CourseraAuthenticationFailed")
		return c.Redirect(routes.PublicApplication.Index())
	}
	revel.TRACE.Println("identity = ", userid)
	stats.Log("User", "Coursera", "Connected to coursera with identity: "+userid)
	models.SetUserCourseraCredentials(user, form, values, userid)

	c.Flash.Success("Connected to coursera!")
	return c.Redirect(routes.PublicApplication.Index())

}
Пример #6
0
func CheckUser(c0 *revel.Controller) revel.Result {
	c := PublicApplication{c0}
	stats.Log("App", "EndRequest", c.Action)
	if user := c.connected(); user.Id == 0 {
		c.Flash.Error("Please login first")
		return c.Redirect(routes.PublicApplication.Index())
	}
	return nil
}
Пример #7
0
func (c PublicApplication) AddUser() revel.Result {
	if IsMaster {
		if user := c.connected(); user.Id != 0 {
			c.RenderArgs["user"] = user
		}
		stats.Log("App", "StartRequest", c.Action)
	}
	return nil
}
Пример #8
0
func writeProgramToFile(s *WorkerState) {
	programFileName := filepath.Join(s.TemporaryDirectory, s.ProgramFileName)
	fo, err := os.Create(programFileName)
	if err != nil {
		stats.Log("Worker", "Error", "Failed to create program file")
		panic("Failed to create program file")
	}
	defer func() {
		if fo.Close() != nil {
			stats.Log("Worker", "Error", "Failed to close program file")
			panic("Failed to close program file")
		}
	}()
	if _, err = fo.Write([]byte(s.Program)); err != nil {
		stats.Log("Worker", "Error", "Failed to write program file")
		panic("Failed to write program file")
	}
	os.Chmod(programFileName, 0666)
	s.ProgramFileName = programFileName
}
Пример #9
0
func chooseWorker() (w *WorkerInfo, err error) {
	var workers []*WorkerInfo
	for _, k := range Workers {
		workers = append(workers, k)
	}
	sz := len(workers)
	if sz == 0 {
		stats.Log("Master", "Error", "Was not able to find a worker.")
		stats.ERROR.Println("Was not able to find a worker.")
		err = errors.New("No workers")
	} else if sz == 1 {
		w = workers[0]
	} else {
		w = workers[rand.Int31n(int32(sz))]
	}
	return
}
Пример #10
0
func runProgram(s *WorkerState) {
	var stdout, stderr bytes.Buffer

	stats.Incr("Worker", "Run")

	conf := s.MachineProblemConfig

	outputFileExtension := func() string {
		if conf.OutputType == "image" {
			return "ppm"
		} else {
			return "raw"
		}
	}

	getInputs := func() []string {
		if s.DatasetId < 0 {
			return []string{"none"}
		} else {
			datasetConfig := conf.Datasets[s.DatasetId]
			inputs := make([]string, len(datasetConfig.Input))
			for i, input := range datasetConfig.Input {
				inputs[i] = filepath.Join(s.MachineProblemDirectory, "data", input)
			}
			return inputs
		}
	}

	getOutput := func() string {
		if s.DatasetId < 0 {
			return "none"
		} else {
			datasetConfig := conf.Datasets[s.DatasetId]
			output := datasetConfig.Output
			return filepath.Join(s.MachineProblemDirectory, "data", output)
		}
	}

	s.UserOutput = filepath.Join(s.TemporaryDirectory, "output."+outputFileExtension())

	runCommand := []string{
		filepath.Join(s.TemporaryDirectory, s.ExecutableFileName),
		"-i ", strings.Join(getInputs(), ","),
		//"-o ", s.UserOutput,
		"-e ", getOutput(),
		"-t ", conf.OutputType,
	}

	s.RunStartTime = time.Now()
	_, err := runOutput(RuntimeTimeout,
		nil, /* env */
		&stdout,
		&stderr,
		filepath.Dir(s.BuildFileName),
		runCommand,
	)
	s.RunEndTime = time.Now()

	stats.LogTime("Worker", "RunTime", s.RunStartTime, s.RunEndTime)

	s.RunStdout = string(stdout.Bytes())
	s.RunStderr = string(stderr.Bytes())

	removeInternalData := func(s string) string {
		ss := strings.Split(s, seperator)
		return ss[0]
	}

	switch err.(type) {
	case TimeoutError:
		revel.TRACE.Println("Terminated....")
		s.TimeoutError = true
		s.TimeoutValue = err.(TimeoutError).Timeout
		stats.Incr("Worker", "RunTimeout")
		panic("Failed to run program")
	}

	if strings.Contains(s.RunStderr, "<<SANDBOXED>>") {
		s.Sandboxed = true
		s.SandboxKeyword = "Program sandboxed because of use of " +
			removeInternalData(strings.TrimPrefix(s.RunStdout, "<<SANDBOXED>>::")) +
			" keyword."
		stats.Log("Worker", "RunSandboxed", s.SandboxKeyword)
		panic("Failed to run program")
	} else if strings.Contains(s.RunStderr, "<<MEMORY>>") {
		s.RunFailed = true
		s.RunStdout = ""
		s.RunStderr = "Program teminated because it is allocating too much memory."
		stats.Incr("Worker", "MemoryLimit")
		panic("Failed to run program")
	} else if err != nil {
		s.RunFailed = true
		s.RunStdout = removeInternalData(s.RunStdout)
		stats.Incr("Worker", "RunFailed")
		panic("Failed to run program")
	}

	ss := strings.Split(s.RunStdout, seperator)
	s.RunStdout = ss[0]

	var wbData InternalCData

	normalizeString := func(s string) string {
		res := s
		if !utf8.ValidString(s) {
			v := make([]rune, 0, len(s))
			for i, r := range s {
				if r == utf8.RuneError {
					if _, size := utf8.DecodeRuneInString(s[i:]); size == 1 {
						continue
					}
				}
				v = append(v, r)
			}
			res = string(v)
		}
		return res
	}

	err = json.Unmarshal([]byte(normalizeString(ss[1])), &wbData)
	if err != nil {
		stats.Incr("Worker", "InternalDataReadError")
		s.RunFailed = true
		s.RunStdout = s.RunStdout
		s.RunStderr = "Failed to read program output. Make sure you do not have special characters in your code."
		stats.Log("Worker", "Error", "Failed to read internal data  "+fmt.Sprint(err))
		return
	}

	if s.DatasetId < 0 {
		wbData.SolutionExists = false
		wbData.Solution.CorrectQ = true
		wbData.Solution.Message = "No solution expected."
	}

	s.SolutionCorrect = wbData.Solution.CorrectQ
	s.SolutionMessage = wbData.Solution.Message
	s.InternalCData = wbData

	if !s.SolutionCorrect {
		stats.Log("Worker", "IncorrectSolution", 1)
	} else {
		stats.Log("Worker", "CorrectSolution", 1)
	}
}