1. Qiita
  2. 投稿
  3. docker

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

  • 2
    いいね
  • 0
    コメント
に投稿

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するようにしておく.

Comments Loading...