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 }
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 { } }
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 }
func checkSandbox(s *WorkerState) { s.SandboxKeyword, s.Sandboxed = IsSandboxed(s.Program) if s.Sandboxed { stats.Log("Worker", "Sandboxed", s.SandboxKeyword) panic("Failed in sandbox") } }
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()) }
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 }
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 }
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 }
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 }
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) } }