2022-10-22 17:38:39 +08:00
|
|
|
package runner
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-07-14 21:47:11 +08:00
|
|
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
|
|
"git.0x7f.app/WOJ/woj-server/pkg/down"
|
2024-01-06 16:06:16 +08:00
|
|
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
2023-07-14 21:47:11 +08:00
|
|
|
"git.0x7f.app/WOJ/woj-server/pkg/unzip"
|
2022-10-22 17:38:39 +08:00
|
|
|
"go.uber.org/zap"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2024-01-06 16:06:53 +08:00
|
|
|
"time"
|
2022-10-22 17:38:39 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func (s *service) download(version uint, url string) e.Status {
|
|
|
|
zipPath := filepath.Join(TmpDir, fmt.Sprintf("%d.zip", version))
|
|
|
|
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", version))
|
|
|
|
|
|
|
|
err := down.Down(zipPath, url)
|
|
|
|
if err != nil {
|
2024-01-06 19:47:16 +08:00
|
|
|
s.log.Error("[new] download problem failed", zap.Error(err))
|
2022-10-22 17:38:39 +08:00
|
|
|
return e.RunnerDownloadFailed
|
|
|
|
}
|
|
|
|
|
|
|
|
err = unzip.Unzip(zipPath, problemPath)
|
|
|
|
if err != nil {
|
2024-01-06 19:47:16 +08:00
|
|
|
s.log.Warn("[new] unzip problem failed", zap.Error(err))
|
2022-10-22 17:38:39 +08:00
|
|
|
return e.RunnerUnzipFailed
|
|
|
|
}
|
|
|
|
|
|
|
|
return e.Success
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *service) prebuild(version uint, force bool) e.Status {
|
2022-10-23 17:29:35 +08:00
|
|
|
if !s.ProblemExists(version) {
|
2022-10-22 17:38:39 +08:00
|
|
|
return e.RunnerProblemNotExist
|
|
|
|
}
|
|
|
|
|
|
|
|
mark := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), ".mark.prebuild")
|
|
|
|
if force {
|
|
|
|
_ = os.Remove(mark)
|
2024-01-06 17:31:00 +08:00
|
|
|
} else if file.Exist(mark) {
|
2022-10-22 17:38:39 +08:00
|
|
|
return e.Success
|
|
|
|
}
|
|
|
|
|
2024-01-06 16:06:53 +08:00
|
|
|
prebuildScript := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), "judge", "prebuild.Makefile")
|
2024-01-06 17:31:00 +08:00
|
|
|
if !file.Exist(prebuildScript) {
|
2024-01-06 19:47:16 +08:00
|
|
|
s.log.Info("[new] prebuild script not found", zap.String("path", prebuildScript), zap.Uint("version", version))
|
2024-01-06 16:06:53 +08:00
|
|
|
return e.Success
|
|
|
|
}
|
|
|
|
|
2024-01-06 17:31:00 +08:00
|
|
|
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), "data")
|
|
|
|
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), "judge")
|
2024-01-06 16:06:53 +08:00
|
|
|
|
|
|
|
args := []string{
|
2024-01-06 19:21:37 +08:00
|
|
|
"-v", fmt.Sprintf("%s:/woj/problem/data", dataDir),
|
|
|
|
"-v", fmt.Sprintf("%s:/woj/problem/judge", judgeDir),
|
2024-01-06 16:06:53 +08:00
|
|
|
"-e", "PREFIX=/woj/problem",
|
|
|
|
"git.0x7f.app/woj/ubuntu-full:latest",
|
|
|
|
"sh", "-c", "cd /woj/problem/judge && make -f prebuild.Makefile prebuild && touch .mark.prebuild",
|
|
|
|
}
|
|
|
|
runArgs := &podmanArgs{
|
|
|
|
executeArgs: executeArgs{
|
|
|
|
args: args,
|
|
|
|
timeout: 300 * time.Second,
|
|
|
|
},
|
|
|
|
memory: "1g",
|
|
|
|
}
|
|
|
|
err := s.podmanRun(runArgs)
|
2022-10-22 17:38:39 +08:00
|
|
|
|
|
|
|
if err != nil {
|
2024-01-06 19:47:16 +08:00
|
|
|
s.log.Warn("[new] prebuild problem failed", zap.Error(err), zap.Uint("version", version))
|
2022-10-22 17:38:39 +08:00
|
|
|
return e.RunnerProblemPrebuildFailed
|
|
|
|
}
|
|
|
|
|
|
|
|
return e.Success
|
|
|
|
}
|
|
|
|
|
2022-10-23 17:29:35 +08:00
|
|
|
func (s *service) NewProblem(version uint, url string, force bool) (Config, e.Status) {
|
|
|
|
if force {
|
|
|
|
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", version))
|
|
|
|
_ = os.RemoveAll(problemPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !s.ProblemExists(version) {
|
|
|
|
status := s.download(version, url)
|
|
|
|
if status != e.Success {
|
|
|
|
return Config{}, status
|
|
|
|
}
|
2022-10-22 17:38:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cfg, err := s.ParseConfig(version, false)
|
|
|
|
if err != nil {
|
2024-01-06 19:47:16 +08:00
|
|
|
s.log.Info("[new] parse problem failed", zap.Error(err), zap.Uint("version", version))
|
2022-10-22 17:38:39 +08:00
|
|
|
return Config{}, e.RunnerProblemParseFailed
|
|
|
|
}
|
|
|
|
|
2022-10-23 17:29:35 +08:00
|
|
|
status := s.prebuild(version, true)
|
2022-10-22 17:38:39 +08:00
|
|
|
if status != e.Success {
|
|
|
|
return Config{}, status
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfg, e.Success
|
|
|
|
}
|