)]}'
{"oslo_concurrency/prlimit.py":[{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"bfce4f7b3fd7d7d5c66a6ee496fd135f091cf286","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def main():"},{"line_number":22,"context_line":"    if len(sys.argv) \u003c 3:"},{"line_number":23,"context_line":"        print(\"%s -m oslo_concurrency.prlimit MEMLIMIT_MB program arg1 ...\")"},{"line_number":24,"context_line":"        sys.exit(1)"},{"line_number":25,"context_line":"    limit \u003d sys.argv[1]"},{"line_number":26,"context_line":"    program_argv \u003d sys.argv[2:]"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_a0c11f56","line":23,"updated":"2015-11-10 21:50:44.000000000","message":"Tristan told me that we need to support also RLIMIT_CPU (time limit). Maybe we should adopt the same command line than the existing prlimit system tool?","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"57e2ef3aadebdbf0862c7e63fe16bfcbc1bc5c71","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def main():"},{"line_number":22,"context_line":"    if len(sys.argv) \u003c 3:"},{"line_number":23,"context_line":"        print(\"%s -m oslo_concurrency.prlimit MEMLIMIT_MB program arg1 ...\")"},{"line_number":24,"context_line":"        sys.exit(1)"},{"line_number":25,"context_line":"    limit \u003d sys.argv[1]"},{"line_number":26,"context_line":"    program_argv \u003d sys.argv[2:]"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_e0a88779","line":23,"in_reply_to":"da85f559_a0c11f56","updated":"2015-11-10 21:54:49.000000000","message":"Yes, that would makes this module more compatible","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"91d385be68b9c182140c4c5839309030ed566615","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def main():"},{"line_number":22,"context_line":"    if len(sys.argv) \u003c 3:"},{"line_number":23,"context_line":"        print(\"%s -m oslo_concurrency.prlimit MEMLIMIT_MB program arg1 ...\")"},{"line_number":24,"context_line":"        sys.exit(1)"},{"line_number":25,"context_line":"    limit \u003d sys.argv[1]"},{"line_number":26,"context_line":"    program_argv \u003d sys.argv[2:]"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a8ffd7b_05229d52","line":23,"in_reply_to":"da85f559_e0a88779","updated":"2015-11-25 23:15:31.000000000","message":"Agree","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"dba236961dd3c343775809c0ef4e9b0bee22d465","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    program_argv \u003d [args.program] + args.program_args"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    if not os.path.isabs(program_argv[0]):"},{"line_number":43,"context_line":"        print(\"oslo_concurrency.prlimit: program path must be absolute\")"},{"line_number":44,"context_line":"        sys.exit(1)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    for arg_name, rlimit in ("}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_a892e155","line":43,"updated":"2016-01-27 16:21:32.000000000","message":"You should from __future__ import print_function to avoid possible hickups later for this.","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3b9892323d5ef7e50ed014e65e79825dd055de8","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    program_argv \u003d [args.program] + args.program_args"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    if not os.path.isabs(program_argv[0]):"},{"line_number":43,"context_line":"        print(\"oslo_concurrency.prlimit: program path must be absolute\")"},{"line_number":44,"context_line":"        sys.exit(1)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    for arg_name, rlimit in ("}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_691124ac","line":43,"in_reply_to":"7a5de9d1_a892e155","updated":"2016-01-28 11:57:06.000000000","message":"Done","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"3393b88ff2b00e4915bfe3b53b47aca59a06f69e","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    ):"},{"line_number":50,"context_line":"        value \u003d getattr(args, arg_name)"},{"line_number":51,"context_line":"        if value:"},{"line_number":52,"context_line":"            resource.setrlimit(rlimit, (value, value))"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    os.execv(program_argv[0], program_argv)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_4376ae3f","line":52,"range":{"start_line":52,"start_character":21,"end_line":52,"end_character":30},"updated":"2016-01-27 15:49:40.000000000","message":"What if the system call fails?","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3b9892323d5ef7e50ed014e65e79825dd055de8","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    ):"},{"line_number":50,"context_line":"        value \u003d getattr(args, arg_name)"},{"line_number":51,"context_line":"        if value:"},{"line_number":52,"context_line":"            resource.setrlimit(rlimit, (value, value))"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    os.execv(program_argv[0], program_argv)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_a97e3ce2","line":52,"range":{"start_line":52,"start_character":21,"end_line":52,"end_character":30},"in_reply_to":"7a5de9d1_4376ae3f","updated":"2016-01-28 11:57:06.000000000","message":"Done","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"4d56ff29c2699ec53ea1ef572e7dd70d86fd0e99","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    ):"},{"line_number":50,"context_line":"        value \u003d getattr(args, arg_name)"},{"line_number":51,"context_line":"        if value:"},{"line_number":52,"context_line":"            resource.setrlimit(rlimit, (value, value))"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    os.execv(program_argv[0], program_argv)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_4e4b355a","line":52,"range":{"start_line":52,"start_character":21,"end_line":52,"end_character":30},"in_reply_to":"7a5de9d1_4376ae3f","updated":"2016-01-27 15:55:42.000000000","message":"You get an ugly traceback. Hum. Maybe we should mimick the prlimit command and write a short message?\n \n $ prlimit --as\u003d102410241024 bash -c \u0027prlimit --as\u003d102410241025 true\u0027\n prlimit: failed to set the AS resource limit: Operation not permitted","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"dd97d85a534ec3e00dd818818c85308eddfff204","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    ):"},{"line_number":50,"context_line":"        value \u003d getattr(args, arg_name)"},{"line_number":51,"context_line":"        if value:"},{"line_number":52,"context_line":"            resource.setrlimit(rlimit, (value, value))"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    os.execv(program_argv[0], program_argv)"},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_8e6dad34","line":52,"range":{"start_line":52,"start_character":21,"end_line":52,"end_character":30},"in_reply_to":"7a5de9d1_4e4b355a","updated":"2016-01-27 16:08:46.000000000","message":"I wouldn\u0027t mind an ugly traceback here since prlimit is a pretty safe syscall, and it will failed mostly because of incorrect values or for other reasons that could use a full traceback","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"7d1f596540b01e5668c1a0eb65da612c4f29aaab","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    if not os.path.isabs(program):"},{"line_number":56,"context_line":"        # program uses a relative path: try to find the absolute path"},{"line_number":57,"context_line":"        # to the executable"},{"line_number":58,"context_line":"        if sys.version_info \u003e\u003d (3, 3):"},{"line_number":59,"context_line":"            import shutil"},{"line_number":60,"context_line":"            program_abs \u003d shutil.which(program)"},{"line_number":61,"context_line":"        else:"},{"line_number":62,"context_line":"            import distutils.spawn"},{"line_number":63,"context_line":"            program_abs \u003d distutils.spawn.find_executable(program)"},{"line_number":64,"context_line":"        if program_abs:"},{"line_number":65,"context_line":"            program \u003d program_abs"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_5f996c1e","line":63,"range":{"start_line":58,"start_character":0,"end_line":63,"end_character":66},"updated":"2016-01-28 15:22:10.000000000","message":"It looks like you\u0027re better off trying to import shutil.which and if that fails use distutils version.","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"414d2323fc86cd6aee6557f63678e46a0c8f956f","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    if not os.path.isabs(program):"},{"line_number":56,"context_line":"        # program uses a relative path: try to find the absolute path"},{"line_number":57,"context_line":"        # to the executable"},{"line_number":58,"context_line":"        if sys.version_info \u003e\u003d (3, 3):"},{"line_number":59,"context_line":"            import shutil"},{"line_number":60,"context_line":"            program_abs \u003d shutil.which(program)"},{"line_number":61,"context_line":"        else:"},{"line_number":62,"context_line":"            import distutils.spawn"},{"line_number":63,"context_line":"            program_abs \u003d distutils.spawn.find_executable(program)"},{"line_number":64,"context_line":"        if program_abs:"},{"line_number":65,"context_line":"            program \u003d program_abs"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_76c6ca4a","line":63,"range":{"start_line":58,"start_character":0,"end_line":63,"end_character":66},"in_reply_to":"7a5de9d1_5f996c1e","updated":"2016-01-28 16:58:36.000000000","message":"Hum, why do you prefer to try to import shutil.which on Python 2, since it will always fail? What\u0027s wrong with testing the Python version?","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"86b7743e346921fa49e85a538ff1195b5467e790","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    if not os.path.isabs(program):"},{"line_number":56,"context_line":"        # program uses a relative path: try to find the absolute path"},{"line_number":57,"context_line":"        # to the executable"},{"line_number":58,"context_line":"        if sys.version_info \u003e\u003d (3, 3):"},{"line_number":59,"context_line":"            import shutil"},{"line_number":60,"context_line":"            program_abs \u003d shutil.which(program)"},{"line_number":61,"context_line":"        else:"},{"line_number":62,"context_line":"            import distutils.spawn"},{"line_number":63,"context_line":"            program_abs \u003d distutils.spawn.find_executable(program)"},{"line_number":64,"context_line":"        if program_abs:"},{"line_number":65,"context_line":"            program \u003d program_abs"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_11a0c09e","line":63,"range":{"start_line":58,"start_character":0,"end_line":63,"end_character":66},"in_reply_to":"7a5de9d1_76c6ca4a","updated":"2016-01-28 17:13:28.000000000","message":"I don\u0027t remember the reason right now, but we usually do import check and fall back to another version. That was just a suggestion, it\u0027s ok as it is.","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"}],"oslo_concurrency/processutils.py":[{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"91d385be68b9c182140c4c5839309030ed566615","unresolved":false,"context_lines":[{"line_number":192,"context_line":"    :param memory_limit_mb: Memory limit in megabytes. Default: no memory limit"},{"line_number":193,"context_line":"                            (on UNIX, it means inheriting limits of the parent"},{"line_number":194,"context_line":"                            process)."},{"line_number":195,"context_line":"    :type memory_limit_mb:  int"},{"line_number":196,"context_line":"    :returns:               (stdout, stderr) from process execution"},{"line_number":197,"context_line":"    :raises:                :class:`UnknownArgumentError` on"},{"line_number":198,"context_line":"                            receiving unknown arguments"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a8ffd7b_82bbe3e4","line":195,"updated":"2015-11-25 23:15:31.000000000","message":"Please add a versionchanged line for this.\n\nI also think that we should add a limits dict (probably with predefined Enum of keys) here instead to allow us to add more limits later (CPU, RSS, whatnot) if it\u0027s needed.","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"95874470b71276751df575c66725040a4852b873","unresolved":false,"context_lines":[{"line_number":192,"context_line":"    :param memory_limit_mb: Memory limit in megabytes. Default: no memory limit"},{"line_number":193,"context_line":"                            (on UNIX, it means inheriting limits of the parent"},{"line_number":194,"context_line":"                            process)."},{"line_number":195,"context_line":"    :type memory_limit_mb:  int"},{"line_number":196,"context_line":"    :returns:               (stdout, stderr) from process execution"},{"line_number":197,"context_line":"    :raises:                :class:`UnknownArgumentError` on"},{"line_number":198,"context_line":"                            receiving unknown arguments"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a5de9d1_fd241db0","line":195,"in_reply_to":"9a8ffd7b_82bbe3e4","updated":"2016-01-27 15:11:25.000000000","message":"\u003e Please add a versionchanged line for this.\n\nDone","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"57e2ef3aadebdbf0862c7e63fe16bfcbc1bc5c71","unresolved":false,"context_lines":[{"line_number":232,"context_line":"    on_execute \u003d kwargs.pop(\u0027on_execute\u0027, None)"},{"line_number":233,"context_line":"    on_completion \u003d kwargs.pop(\u0027on_completion\u0027, None)"},{"line_number":234,"context_line":"    preexec_fn \u003d kwargs.pop(\u0027preexec_fn\u0027, None)"},{"line_number":235,"context_line":"    memory_limit_mb \u003d kwargs.pop(\u0027memory_limit_mb\u0027, None)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    if isinstance(check_exit_code, bool):"},{"line_number":238,"context_line":"        ignore_exit_code \u003d not check_exit_code"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_c0746337","line":235,"updated":"2015-11-10 21:54:49.000000000","message":"We also needs CPU time limit:\ncpu_limit_seconds \u003d kwargs.pop(\u0027cpu_limit_seconds\u0027, None)","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"57e2ef3aadebdbf0862c7e63fe16bfcbc1bc5c71","unresolved":false,"context_lines":[{"line_number":269,"context_line":"        if not os.path.isabs(cmd[0]):"},{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_e09ac76d","line":272,"updated":"2015-11-10 21:54:49.000000000","message":"To support fallback to native prlimit, this needs something like:\n\nif distutils.spaw.find_executable(\u0027prlimit\u0027): cmd\u003d[\u0027prlimit\u0027, ...\u0027]\nelse: oslo_concurrency.prlimit","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"change_message_id":"f879384f2fbe376bc7e44807142e7f78d41bd185","unresolved":false,"context_lines":[{"line_number":269,"context_line":"        if not os.path.isabs(cmd[0]):"},{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_d742820e","line":272,"in_reply_to":"da85f559_8444221b","updated":"2015-11-12 15:51:13.000000000","message":"Hey ChangBo, the spawn namespace is not imported by default, you need to:\n\n\u003e\u003e\u003e import distutils.spawn","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9796,"name":"ChangBo Guo","email":"glongwave@gmail.com","username":"gcb"},"change_message_id":"61e11d2426cb39368f29f659ce674c9cca8e2283","unresolved":false,"context_lines":[{"line_number":269,"context_line":"        if not os.path.isabs(cmd[0]):"},{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_8444221b","line":272,"in_reply_to":"da85f559_e09ac76d","updated":"2015-11-11 06:29:15.000000000","message":"I can find mehtod \u0027find_executable\u0027 is documented in  https://docs.python.org/2/distutils/apiref.html#module-distutils.spawn.\nbut I got an attribute error:\n \n[gcb@localhost oslo-incubator]$ python\nPython 2.7.5 (default, Apr 10 2015, 08:09:05) \n[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e import distutils\n\u003e\u003e\u003e distutils.spawn.find_executable(\u0027prlimit\u0027)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nAttributeError: \u0027module\u0027 object has no attribute \u0027spawn\u0027","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"91d385be68b9c182140c4c5839309030ed566615","unresolved":false,"context_lines":[{"line_number":269,"context_line":"        if not os.path.isabs(cmd[0]):"},{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a8ffd7b_c2fd6b3b","line":272,"in_reply_to":"da85f559_e09ac76d","updated":"2015-11-25 23:15:31.000000000","message":"I don\u0027t think we should fall back to linux-utils here. Method\u0027s behavior should not change depending on prlimit executable available. It should either fail without it or always use Python implementation.","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"647e331b5387ef030a0b56286cf9411ff54c71ff","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"},{"line_number":276,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_80609ba6","line":273,"updated":"2015-11-10 21:49:30.000000000","message":"In term of security, here you must trust the system.\n\nIf an attacker is able to write a temporary file somewhere and control the Python path (ex: set the PYTHONPATH environment variable), you may execute arbitrary Python code.\n\nWell, you maybe already lost the game if the attacker is able to write on disk (even if it\u0027s restricted to a temporary directory) and control things like the Python path, no?\n\nIt\u0027s just to say that a system prlimit program can be *more* secure than a Python script executed like that.\n\nPython 3 has a nice -I (isolate) command line argument which makes Python a little bit more secure, but it may break if oslo.concurrency is not installed \"as expected\". The option ignores user modules, all environment variables starting with \"PYTHON\" (like PYTHONPATH), etc. I\u0027m not sure that we can use it here?","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"91d385be68b9c182140c4c5839309030ed566615","unresolved":false,"context_lines":[{"line_number":270,"context_line":"            raise ValueError(\"program path must be absolute when memory \""},{"line_number":271,"context_line":"                             \"limit is used\")"},{"line_number":272,"context_line":"        prlimit \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":273,"context_line":"                   str(memory_limit_mb)]"},{"line_number":274,"context_line":"        prlimit.extend(cmd)"},{"line_number":275,"context_line":"        cmd \u003d prlimit"},{"line_number":276,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a8ffd7b_c591f59a","line":273,"in_reply_to":"da85f559_80609ba6","updated":"2015-11-25 23:15:31.000000000","message":"We still support Python 2.x, so using -I option is not an option. Besides if attacker can control PYTHONPATH, we already are not running the code that is written here since it can be replaced by attacker with anything.","commit_id":"49ecf8b265200c0c04075ab1687515193d49fed4"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"f179267eb3d104f28373541e03b90203b591d485","unresolved":false,"context_lines":[{"line_number":190,"context_line":"                            ValueError)"},{"line_number":191,"context_line":"    :type preexec_fn:       function()"},{"line_number":192,"context_line":"    :param prlimit:         Set resource limits on the child process. See"},{"line_number":193,"context_line":"                            above for a detailed description."},{"line_number":194,"context_line":"    :type prlimit:          dict"},{"line_number":195,"context_line":"    :returns:               (stdout, stderr) from process execution"},{"line_number":196,"context_line":"    :raises:                :class:`UnknownArgumentError` on"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a5de9d1_178d5b31","line":193,"range":{"start_line":193,"start_character":60,"end_line":193,"end_character":61},"updated":"2016-01-27 13:57:38.000000000","message":"s/above/below/","commit_id":"1dad137b9b5ddddbc8162b4cc87d7ebbefa1c83b"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"7b7130bc24cec467b81ab181b501244a3f95d2bb","unresolved":false,"context_lines":[{"line_number":190,"context_line":"                            ValueError)"},{"line_number":191,"context_line":"    :type preexec_fn:       function()"},{"line_number":192,"context_line":"    :param prlimit:         Set resource limits on the child process. See"},{"line_number":193,"context_line":"                            above for a detailed description."},{"line_number":194,"context_line":"    :type prlimit:          dict"},{"line_number":195,"context_line":"    :returns:               (stdout, stderr) from process execution"},{"line_number":196,"context_line":"    :raises:                :class:`UnknownArgumentError` on"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a5de9d1_5d4bf159","line":193,"range":{"start_line":193,"start_character":60,"end_line":193,"end_character":61},"in_reply_to":"7a5de9d1_178d5b31","updated":"2016-01-27 15:11:21.000000000","message":"Done","commit_id":"1dad137b9b5ddddbc8162b4cc87d7ebbefa1c83b"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"f179267eb3d104f28373541e03b90203b591d485","unresolved":false,"context_lines":[{"line_number":204,"context_line":"    must use an absolute path to the executable. Supported keys:"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    * ``\u0027as\u0027`` (``int``): Address space limit in bytes."},{"line_number":207,"context_line":"    * ``\u0027rss\u0027`` (``int``): Maximum Resident Set Size (RSS) in bytes."},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    .. versionchanged:: 1.5"},{"line_number":210,"context_line":"       Added *cwd* optional parameter."}],"source_content_type":"text/x-python","patch_set":2,"id":"7a5de9d1_f703df74","line":207,"range":{"start_line":207,"start_character":67,"end_line":207,"end_character":68},"updated":"2016-01-27 13:57:38.000000000","message":"I\u0027d suggest you define a python object for this rather than a dict\n\neg\n\n  class ProcessLimits(object):\n\n      def __init__(self, **kwargs):\n\n         self.address_space \u003d kwargs.get(\"address_space\", None)\n         self.resident_set_size \u003d kwargs.get(\"resident_set_size\")\n         ...etc for other settings...\n\nSpelling out the attribute names is far clearer than using the obscure abbreviatiosn from the prlimit system call.\n\n\nThen you can just pass in an ProcessLimits instance to the execute() call.","commit_id":"1dad137b9b5ddddbc8162b4cc87d7ebbefa1c83b"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"7b7130bc24cec467b81ab181b501244a3f95d2bb","unresolved":false,"context_lines":[{"line_number":204,"context_line":"    must use an absolute path to the executable. Supported keys:"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    * ``\u0027as\u0027`` (``int``): Address space limit in bytes."},{"line_number":207,"context_line":"    * ``\u0027rss\u0027`` (``int``): Maximum Resident Set Size (RSS) in bytes."},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    .. versionchanged:: 1.5"},{"line_number":210,"context_line":"       Added *cwd* optional parameter."}],"source_content_type":"text/x-python","patch_set":2,"id":"7a5de9d1_bd3785e2","line":207,"range":{"start_line":207,"start_character":67,"end_line":207,"end_character":68},"in_reply_to":"7a5de9d1_f703df74","updated":"2016-01-27 15:11:21.000000000","message":"\u003e I\u0027d suggest you define a python object for this rather than a dict\n\nGood idea.","commit_id":"1dad137b9b5ddddbc8162b4cc87d7ebbefa1c83b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"16e0a70fb9a8b7632316d793e0817a5f35c4ba49","unresolved":false,"context_lines":[{"line_number":234,"context_line":"    process.  If this parameter is used, the child process will be spawned by a"},{"line_number":235,"context_line":"    wrapper process which will set limits before spawning the command."},{"line_number":236,"context_line":""},{"line_number":237,"context_line":"    .. versionchanged:: 3.4"},{"line_number":238,"context_line":"       Added *prlimit* optional parameter."},{"line_number":239,"context_line":""},{"line_number":240,"context_line":"    .. versionchanged:: 1.5"}],"source_content_type":"text/x-python","patch_set":7,"id":"5a9d85d2_1e56155c","line":237,"updated":"2016-06-21 15:42:17.000000000","message":"This looks pretty screwy given this is a mitaka series version but now it\u0027s in stable/liberty code...","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"}],"oslo_concurrency/tests/unit/test_processutils.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"8dca999333bc2d122ef5321ecd4ceea880b6bae1","unresolved":false,"context_lines":[{"line_number":732,"context_line":"    def test_bin_true(self):"},{"line_number":733,"context_line":"        # Simple test running a program with no parameter"},{"line_number":734,"context_line":"        prlimit \u003d processutils.ProcessLimits(address_space\u003dself.MAX_MEMORY)"},{"line_number":735,"context_line":"        stdout, stderr \u003d processutils.execute(\u0027/bin/true\u0027, prlimit\u003dprlimit)"},{"line_number":736,"context_line":"        self.assertEqual(stdout.rstrip(), \u0027\u0027)"},{"line_number":737,"context_line":"        self.assertEqual(stderr.rstrip(), \u0027\u0027)"},{"line_number":738,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_93d05155","line":735,"updated":"2016-01-28 10:27:45.000000000","message":"/bin/true does not exist on all systems, and it does no on Darwin.","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3b9892323d5ef7e50ed014e65e79825dd055de8","unresolved":false,"context_lines":[{"line_number":732,"context_line":"    def test_bin_true(self):"},{"line_number":733,"context_line":"        # Simple test running a program with no parameter"},{"line_number":734,"context_line":"        prlimit \u003d processutils.ProcessLimits(address_space\u003dself.MAX_MEMORY)"},{"line_number":735,"context_line":"        stdout, stderr \u003d processutils.execute(\u0027/bin/true\u0027, prlimit\u003dprlimit)"},{"line_number":736,"context_line":"        self.assertEqual(stdout.rstrip(), \u0027\u0027)"},{"line_number":737,"context_line":"        self.assertEqual(stderr.rstrip(), \u0027\u0027)"},{"line_number":738,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_89eee089","line":735,"in_reply_to":"7a5de9d1_93d05155","updated":"2016-01-28 11:57:06.000000000","message":"Done","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"dba236961dd3c343775809c0ef4e9b0bee22d465","unresolved":false,"context_lines":[{"line_number":745,"context_line":"        expected \u003d (value, value)"},{"line_number":746,"context_line":"        self.assertEqual(stdout.rstrip(), str(expected))"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":"    def test_as(self):"},{"line_number":749,"context_line":"        self.check_limit(\u0027address_space\u0027, self.MAX_MEMORY, \u0027RLIMIT_AS\u0027)"},{"line_number":750,"context_line":""},{"line_number":751,"context_line":"    def test_rss(self):"},{"line_number":752,"context_line":"        self.check_limit(\u0027resident_set_size\u0027, self.MAX_MEMORY, \u0027RLIMIT_RSS\u0027)"},{"line_number":753,"context_line":""},{"line_number":754,"context_line":"    def test_unsupported_prlimit(self):"},{"line_number":755,"context_line":"        self.assertRaises(ValueError, processutils.ProcessLimits, xxx\u003d33)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_895e0744","line":752,"range":{"start_line":748,"start_character":0,"end_line":752,"end_character":76},"updated":"2016-01-27 16:21:32.000000000","message":"These two tests depend on these limits on machine where they are run to not be set to 1G. Otherwise they can be false positive.\n\nMaybe we should check for it?","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3b9892323d5ef7e50ed014e65e79825dd055de8","unresolved":false,"context_lines":[{"line_number":745,"context_line":"        expected \u003d (value, value)"},{"line_number":746,"context_line":"        self.assertEqual(stdout.rstrip(), str(expected))"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":"    def test_as(self):"},{"line_number":749,"context_line":"        self.check_limit(\u0027address_space\u0027, self.MAX_MEMORY, \u0027RLIMIT_AS\u0027)"},{"line_number":750,"context_line":""},{"line_number":751,"context_line":"    def test_rss(self):"},{"line_number":752,"context_line":"        self.check_limit(\u0027resident_set_size\u0027, self.MAX_MEMORY, \u0027RLIMIT_RSS\u0027)"},{"line_number":753,"context_line":""},{"line_number":754,"context_line":"    def test_unsupported_prlimit(self):"},{"line_number":755,"context_line":"        self.assertRaises(ValueError, processutils.ProcessLimits, xxx\u003d33)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a5de9d1_49e8e87c","line":752,"range":{"start_line":748,"start_character":0,"end_line":752,"end_character":76},"in_reply_to":"7a5de9d1_895e0744","updated":"2016-01-28 11:57:06.000000000","message":"Done","commit_id":"290132d04bc3bf27158dbb0de779ae2317326128"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"7d1f596540b01e5668c1a0eb65da612c4f29aaab","unresolved":false,"context_lines":[{"line_number":816,"context_line":""},{"line_number":817,"context_line":"        # trying to set a limit higher than the current hard limit"},{"line_number":818,"context_line":"        # with setrlimit() should fail."},{"line_number":819,"context_line":"        higher_limit \u003d prlimit.address_space + 1024"},{"line_number":820,"context_line":""},{"line_number":821,"context_line":"        args \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":822,"context_line":"                \u0027--as\u003d%s\u0027 % higher_limit,"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_9fd7e4ec","line":819,"updated":"2016-01-28 15:22:10.000000000","message":"This is not current hard limit, this is either current soft limit or 1G, isn\u0027t it?","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"},{"author":{"_account_id":708,"name":"Yuriy Taraday","email":"yuriy@taraday.nl","username":"yorik-sar"},"change_message_id":"86b7743e346921fa49e85a538ff1195b5467e790","unresolved":false,"context_lines":[{"line_number":816,"context_line":""},{"line_number":817,"context_line":"        # trying to set a limit higher than the current hard limit"},{"line_number":818,"context_line":"        # with setrlimit() should fail."},{"line_number":819,"context_line":"        higher_limit \u003d prlimit.address_space + 1024"},{"line_number":820,"context_line":""},{"line_number":821,"context_line":"        args \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":822,"context_line":"                \u0027--as\u003d%s\u0027 % higher_limit,"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_d12c684c","line":819,"in_reply_to":"7a5de9d1_8b99df70","updated":"2016-01-28 17:13:28.000000000","message":"Oh, right. You call prlimit under execute with prlimit. I missed that. Ok.","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"e114869e4294b301f7090d964d81e853a3a7d7d7","unresolved":false,"context_lines":[{"line_number":816,"context_line":""},{"line_number":817,"context_line":"        # trying to set a limit higher than the current hard limit"},{"line_number":818,"context_line":"        # with setrlimit() should fail."},{"line_number":819,"context_line":"        higher_limit \u003d prlimit.address_space + 1024"},{"line_number":820,"context_line":""},{"line_number":821,"context_line":"        args \u003d [sys.executable, \u0027-m\u0027, \u0027oslo_concurrency.prlimit\u0027,"},{"line_number":822,"context_line":"                \u0027--as\u003d%s\u0027 % higher_limit,"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a5de9d1_8b99df70","line":819,"in_reply_to":"7a5de9d1_9fd7e4ec","updated":"2016-01-28 16:48:07.000000000","message":"This test sets RLIMIT_AS twice: first with prlimit.address_space, then with prlimit.address_space + 1024.\n\nSystem prlimit and prlimit.py uses the command line argument as the soft *and* hard limit by default.\n\nYou set the soft and/or hard limits using different syntax: \"soft:\" (only soft), \":hard\" (only hard), \"soft:hard\" (soft+hard, different value) or \"value\" (soft+hard, same value).\n\nCurrently, prlimit.py only supports \"value\" syntax (set soft and hard limits to the same value).","commit_id":"b2e78569c5cabc9582c02aacff1ce2a5e186c3ab"}]}
