LoginSignup
16
8

More than 5 years have passed since last update.

dockerでジャッジシステム作りたい時

Posted at

Aizu Online JudgeやAtcoderなどのオンラインジャッジシステムを作る時のメモ.

オンラインジャッジシステムを作る上で必要なことは

  • プログラムに入力を与えて期待する出力かどうか判定する
  • リソースを均等にする

細かく言えばたくさんありますが,こんな感じだと思います.

今までは一つ目しか満たしてなかった(とてもよくない
とりあえず安全に実行できる環境にするべきだろうということでdockerを導入した.
その上で,幾つかハマりどころが合ったので残しておく.

要件

  • 入力と出力は数MBになりえる
  • 実行時間制限を指定できる.
  • メモリ使用量を制限できる.
  • プロセス数を制限できる.
  • 生成されるファイルサイズを制限できる(今回は無し
  • cpu使用率を均等にする(今回は無し
  • 使用したメモリ量を取得できる.
  • 実行時間を取得できる.
  • プロセスのステータスを取得できる.

 仕様

  • サーバーの性能的に,同時に実行できるプログラムは1つ

プログラム

プログラムは以下.

require 'docker'

image = 'gcc:latest'
tmp_path = File.expand_path('../tmp', __FILE__)
memory = 128


options = {
    'Image': image,
    'Tty': true,
    'HostConfig': {
        'Binds': [ tmp_path + ":/tmp" ],
        'Memory': memory * 1024 * 1024,
        'PidsLimit': 10
    },
    'WorkingDir': '/tmp'
}

container = Docker::Container.create(options)
container.start

p container.exec(["sh", "-c", "g++ source.cpp"])
p container.exec(["sh", "-c", "/usr/bin/time -f \"%M KB\" ./a.out > result.log"])
container.delete(force: true)

createに渡すオプションは基本的に ここの構造をrubyで実現すればいい.

'Tty' を trueにしないといい感じに動かなかった.
'Memory'はByte指定なので適当に掛け算してMBにした.
'Binds'はマウントの指定.

 あと,createしただけではstartされないので注意

execの渡し方は基本的には配列だけど,まとめた長いコマンドとかはこんな感じにするといい.

終了後にdeleteするようにしておく.

16
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
8