Browsed by
Month: April 2016

Gitlab DroneCI 配置记录

Gitlab DroneCI 配置记录

OJ的代码越来越多了, 功能也越来越多= = 也就导致bug越来越多, 测试的必要性就很高了, 因此我们需要用 CI平台鞋好的代码进行及时的测试, 因为OJ的代码是私有的,不能直接用DroneCI 或者是 TravisCI, 因而自己需要搭建一个DroneCI,具体操作如下, 根据DroneCI 官方文档说明  gitlab配置droneCI还有点麻烦, 之间也真遇到了几个坑= = 因此纪录一下过程 服务器端使用CentOS 首先安装docker, 并且 fetch DroneCI的镜像image到本地, 这就是一个基本的DroneCI环境了 根据DroneCI的说明 , 在  gitlab里首先创建一个application Oauth 接口,  配置为 Callback URL:即DroneCI所在的auth URL :http://202.118.31.226:3322/authorize这里为这个 然后会生成application id ****(A) 和 application secret *****(B) 将这两个写在 DroneCI Server的 /etc/drone/dronerc内 分别对应 A=> client_id B=> client_secret 注意REMOTE_DRIVER为 gitlab REMOTE_CONFIG为 http://example.yourgitlab.com?client_id=A&client_secret=B 然后将 这个保存为脚本 sudo docker run \ –volume /var/lib/drone:/var/lib/drone \ –volume /var/run/docker.sock:/var/run/docker.sock \ –env-file /etc/drone/dronerc \ –restart=always \ –publish=80:8000 \ –detach=true \ –name=drone \ drone/drone:0.4 然后运行脚本之后, DroneCI就搭建好了~…

Read More Read More

[NEUOJ日记] #1 Hello World

[NEUOJ日记] #1 Hello World

写在前面: NEUOJ的开发即将满五个月, 算是我在大学阶段做的最大的一个项目了(因为搞ACM的缘故没有在大一大二做什么项目出来) 在开发过程中遇到了很多问题  & 学到了很多东西, 谨以此系列文章记录开发过程以及开发心得体会 文章的格式: 每一篇文章都会以: 一个主标题 开头, 然后 分为多个副标题, 每个副标题后面会跟一个解释下面要讲的内容的commit-id Hello World Why we start (No commit id) 两年半的ACM生涯结束了, 老师征求我们对于重写OJ的想法, 我们队伍的大家早就有自己写一个OJ的想法了, 作为挖坑小能手的我 ( Qrz ) 本来还有点因为自己的时间+个人原因不是很想搞(其实内心是非常想搞的) 被两个队友拉着就果断入坑了, 我们想写出一个能够给大家一个梯度训练, 界面友好, 测评多样化, 符合当今Web开发潮流的新的Online judge 系统, 于是我们队伍+ sjm + wyf就开始了对OJ的开发, 最初的分工是 我们队伍搞 Web 后端开发, sjm 搞前端开发, wyf + 我搞测评端研究 How we design (No commit id) 开发OJ对我来说最陌生的就是测评后端的开发, 不知道如何下手, 好在老师给我们提供了一个开源的测评系统 domjudge, domjudge的后端judgehost已经非常完善了, 支持多语言多环境多测试样例的安全测评, 于是我们初期就直接使用judgehost来做我们的测评后端, 然后前端我们使用的是Bootstrap框架, Web后端使用Laravel框架, 然后我们初步设计了一下表的结构, 参考了hustoj的数据表结构 & 我们自己的表结构,对表进行了设计, 最初的表有   users: 用户登陆信息 problem: 题目相关信息 submissions: 用户提交相应信息 userinfo: 用户的详细信息,基本信息 (之后会在不同的阶段介绍表的具体结构…

Read More Read More

C语言可变参数函数实现 & 分析

C语言可变参数函数实现 & 分析

先给出一个样例程序, 实现一个打印每一个传给它的元素并且换行 /************************************************************************* > File Name: va_args_1.c > Author: VOID_133 > ################### > Mail: ################### > Created Time: Sun 17 Apr 2016 09:34:22 PM CST ************************************************************************/ #include<stdio.h> #include<stdarg.h> void print_list(char *begin, …) { va_list ap; char *p = NULL; va_start(ap, begin); p = va_arg(ap, char *); while(p != NULL) { fputs(p, stdout); putchar(‘\n’); p = va_arg(ap, char *); } va_end(ap); } int main(void) { print_list(0, “This”, “is”, “Multi”, “Line”, NULL); return 0; } 上面的代码已经很清晰了, 下面简单说明一下如何编写一个可变参数函数 1.定义函数, 注意参数列表的第一个参数一定要有,就算没有用到也不能为空, 而且必须有名字, 这个是提供给va_start作为参数的 void…

Read More Read More

[阳炎Project] 赏月独奏会 zh jp romaji

[阳炎Project] 赏月独奏会 zh jp romaji

ZH 赏月独奏(赏月recital) オツキミリサイタル 作词/作曲/编曲/Guitar:じん(自然之敌p) 「不管如何挽救都是白费力气了吧」 看见了你 快哭出来的脸 「别轻言放弃呀」 单凭这样一句话 根本不够的呐! 「因为这样才更需要提起精神 否则明天也会眼花缭乱呢!」的说著 拽著你跑到街上 会不会太任性呢 变得青蓝的阳光下 你的事情 仍然令我担心不已 热泪盈眶著 「这样懦弱的我、 肯定是办不到的」 我相信你、因为是你。 尽管笔直向前就对了吧? 实在到了不行的时候 还有我会对你给予支持。 把『固执己见』什么的丢在一边 因为绝对不能这麼做 呐、不一起走吗? 将『孤独感』击败吧、来吧 「不明白到底发生了什么事」 你看起来又想哭了 不断的叹气 闭上了双眼 你瞧 陷入窘境了! 「许多想令自己努力的念头 已经消失在昨天了!」的说著 强迫你一起上街 果然是太乱来了 黄昏后、天色变得幽蓝 阳光也渐渐消散 在那一瞬间 原是叹息的面容 悄无声息地、泪水 忽然间夺眶而出 残忍狭小的这个世界 受到巨大的獠牙剥离 「真的好想跟你呆在一起」 内心也跟著垂头丧气 尽管只言片语已经无法传达给你了 但还是想成为你的力量 「希望能帮助到你。传达到吧(快实现吧)、呐」 「我相信你哦,因为是你呀!」 直率的喊了出来 「没有什么是不可能的! 只要你希望的话、一定能够再次相会!」 深深的吸一口气 向远在天边的月亮先生 胆怯的你「这就做给你看!」地呐喊了出来 …这样的你有些帅气呢。嘛。 终わり JP & Romaji 「もう、どうやったって无駄かもな」 「mou , douyattatte muda kamona」 泣きそうな颜 见ていた naki souna kao miteita 「谛めないでよ」みたいな 「akirame naideyo」mitai na 言叶じゃ 全然足りない! kotoba…

Read More Read More

[NEUOJ] 测评后端分析 测评过程分析(judgedaemon.main.php)

[NEUOJ] 测评后端分析 测评过程分析(judgedaemon.main.php)

还没有整理, 先放生肉(Draft) DOMJudge 测评后端API分析 ==== ### 调用流程简介: 1. domserver存储有所有数据信息,包括测评必须的信息 2. domserver提供一套RESTful API供judgedaemon客户端调用, judgedaemon可以有多个实例同时运行 3. judgedaemon运行之后, 每隔一定时间向domserver的api请求数据, 如果有数据的话, server会返回给judgedaemon一个json包,包含要运行的judge所需要的所有信息 4. judgedaemon将信息解析之后, 制作出相应的程序执行,和编译脚本 compile.sh , run.sh 之后执行(可以选择在CHROOT环境下执行, 暂时没有考虑) 5. 执行后的结果通过参数和返回值的形式返回给judgedaemon , 之后judgedaemon将测评结果数据提交给domserver, domserver随即更新数据库内的信息 ### judgedaemon.main.php内函数分析 * dbconfig_get_rest * fetch_executable * judge * read_credentials * request * rest_encode_file * usage #### dbconfig_get_rest * arguments: $name: 用于表示想要get的配置的名称 * description: 获取服务器的配置信息 * retval 服务器的相应的配置信息 #### fetch_executable __核心函数,用于下载用户提交的代码,并且将代码编译, 生成运行测评的脚本run.sh 并且返回run.sh的绝对路径共后续调用使用__ * arguments: $workdirpath: 测评路径 $execid: 需要fetch的执行脚本archive的id $md5sum: zip的校验和 * description: 该函数根据提供的三个参数, 先检查是否本地已经存在运行本次测评需要的所有脚本(或者二进制文件), 如果不存在则从server 访问 REST/executable ,获取下来相应的execid对应的base64加密后的zip文件,解码,然后在本地的workdir/executable/$execid/下进行解压…

Read More Read More

[NEUOJ] 测评后端分析 judgehost文件结构分析

[NEUOJ] 测评后端分析 judgehost文件结构分析

NEUOJ的测评后端暂时使用的是domjudge 的 judgehost作为测评后端 下面分析一下judgehost的工作原理 首先分析一下judgehost的几个核心文件的功能 [这里省略了从clone domjudge repo 到编译安装好judgehost这个过程, 我认为来看这篇文章的应该都是已经可以自己安装好domjudge的人,不然可能这篇文章对于你来说还不适合阅读] 首先看bin下面的文件 runguard 是负责保证用户程序的安全运行, 不会对系统进行破坏的程序, 这个的代码利用了 rlmit, cgroup timeout等方式对用户程序进行限制 judgedaemon 一个php脚本, 测评后端的完整进程, 包括通过服务器下载数据, 到调用相应可执行文件对代码进行编译运行比对之后. 将结果返回给webserver的整个过程都是由这个程序进行的 runpipe: 用于在runjury(特殊的测评程序) 和 user program之间建立双向管道,进行交互式测评(目前只了解这些) create_cgroups: 在设置了enable_cgroup 的编译参数之后, 通过这个来创建domjudge的 control group, cgroup能够获得更精确的运行时间和使用资源情况 dj_make_chroot, dj_make_ubuntu_chroot: 用于让java程序可以在chroot环境下运行 再看etc文件夹下的文件 sudoers.domjudge: 这个文件配置好了 运行测评的时候的用户的sudo权限配置 common-config.php: 一些通常的config文件 judgehost-static.php: 通过make 和 make install生成的静态config文件,不要进行修改 restapi.secret: 里面存有向API请求的时候的API地址和认证信息 再看judgings文件夹 judgings文件夹下, 所有的文件都是测评的时候生成的, 他的第一级给每一个judgehost分配一个不同的文件夹,名字为 HOSTNAME-n  , 每一个judgehost都要以一个不同的用户来运行, 不然会产生问题 每个judgings文件夹下, 有多个endpoint, 每一个endpoint对应你再 restapi.secret里面配置的不同的名字 如endpoint-neuoj 每个endpoint下 , 有 这样的文件夹: c[n]-s[n]-j[n]  每一个文件夹内都是一次测评,如果这个测评之前被测过了, 重新测评的时候, 原来的测评会叫做 c[n]-s[n]-j[n]-old-timestamp , 除了每一个测评一个文件夹以外, 还有两个文件夹, 一个用于存从服务器fetch来的input output, 一个用于存从服务器fetch来的…

Read More Read More