{"action":"created","comment":{"url":"https://api.github.com/repos/Yelp/paasta/pulls/comments/104992901","pull_request_review_id":25852185,"id":104992901,"diff_hunk":"@@ -84,31 +89,128 @@ def generate_hostname(fqdn, mesos_task_id):\n     return hostname\n \n \n-def add_hostname(args, hostname):\n-    # Add --hostname argument immediately after 'run' command if it exists\n+def add_argument(args, argument):\n+    # Add an argument immediately after 'run' command if it exists\n     args = list(args)\n-\n     try:\n         run_index = args.index('run')\n     except ValueError:\n         pass\n     else:\n-        args.insert(run_index + 1, '--hostname=' + hostname)\n-\n+        args.insert(run_index + 1, argument)\n     return args\n \n \n+def get_cpumap():\n+    # Return a dict containing the core numbers per physical CPU\n+    core = 0\n+    cpumap = {}\n+    try:\n+        with open('/proc/cpuinfo', 'r') as f:\n+            for line in f:\n+                m = re.match('physical\\sid.*(\\d)', line)\n+                if m:\n+                    cpuid = int(m.group(1))\n+                    if cpuid not in cpumap:\n+                        cpumap[cpuid] = []\n+                    cpumap[cpuid].append(core)\n+                    core += 1\n+    except IOError:\n+        pass\n+    return cpumap\n+\n+\n+def get_numa_memsize(nb_nodes):\n+    # Return memory size in mB per NUMA node assuming memory is split evenly\n+    # TODO: calculate and return real memory map\n+    try:\n+        with open('/proc/meminfo', 'r') as f:\n+            for line in f:\n+                m = re.match('MemTotal:\\s*(\\d)kb', line)\n+                if m:\n+                    return int(m) / 1024 / int(nb_nodes)\n+    except IOError:\n+        pass\n+    return 0\n+\n+\n+def arg_collision(new_args, current_args):\n+    # Returns True if one of the new arguments is already in the\n+    # current argument list.\n+    cur_arg_keys = []\n+    for c in current_args:\n+        cur_arg_keys.append(c.split('=')[0])\n+    return bool(set(new_args).intersection(set(cur_arg_keys)))\n+\n+\n+def extract_float(f):\n+    # Ensure we return a float. If input is invalid we return 0.0\n+    try:\n+        return float(f)\n+    except (ValueError, TypeError):\n+        logging.warning('Could not read %s as a float' % str(f))\n+        return 0.0\n+\n+\n+def is_numa_enabled():\n+    if os.path.exists('/proc/1/numa_maps'):\n+        return True\n+    else:\n+        logging.warning('The system does not support NUMA')\n+        return False\n+\n+\n+def append_cpuset_args(argv, env_args):\n+    # Enable log messages to stderr\n+    logging.basicConfig(stream=sys.stderr, level=logging.INFO)\n+    try:\n+        pinned_numa_node = int(env_args.get('PIN_TO_NUMA_NODE'))\n+    except (ValueError, TypeError):\n+        logging.warning('Could not read PIN_TO_NUMA_NODE value as an int.' +\n+                        str(env_args.get('PIN_TO_NUMA_NODE')))\n+        pinned_numa_node = None\n+\n+    cpumap = get_cpumap()\n+\n+    # We do nothing if any of these conditions are not met\n+    if (\n+        # PIN_TO_NUMA_NODE has a correct value\n+        pinned_numa_node and\n+        # cpuset is not already manually set\n+        not arg_collision(['--cpuset-cpus', '--cpuset-mems'], argv) and","path":"paasta_tools/docker_wrapper.py","position":120,"original_position":120,"commit_id":"b9e2c17ddddab0c6f8ed5c44f76365f15de33602","original_commit_id":"b9e2c17ddddab0c6f8ed5c44f76365f15de33602","user":{"login":"solarkennedy","id":370205,"avatar_url":"https://avatars3.githubusercontent.com/u/370205?v=3","gravatar_id":"","url":"https://api.github.com/users/solarkennedy","html_url":"https://github.com/solarkennedy","followers_url":"https://api.github.com/users/solarkennedy/followers","following_url":"https://api.github.com/users/solarkennedy/following{/other_user}","gists_url":"https://api.github.com/users/solarkennedy/gists{/gist_id}","starred_url":"https://api.github.com/users/solarkennedy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solarkennedy/subscriptions","organizations_url":"https://api.github.com/users/solarkennedy/orgs","repos_url":"https://api.github.com/users/solarkennedy/repos","events_url":"https://api.github.com/users/solarkennedy/events{/privacy}","received_events_url":"https://api.github.com/users/solarkennedy/received_events","type":"User","site_admin":false},"body":"This if is way too complex and the comments don't add a lot of value.\r\n\r\nMake it \"self documenting\" by testing each condition and outputting each thing and returning the right result.\r\n\r\n```\r\nif arg_collision():\r\n    log.error('args already have the things')\r\n    return argv\r\nif not is_numa_enabled():\r\n    log.warning('numa optimization requested, but not on a numa system. Doing nothing.')\r\n    return argv\r\nif ....\r\n```","created_at":"2017-03-08T18:52:45Z","updated_at":"2017-03-08T18:52:45Z","html_url":"https://github.com/Yelp/paasta/pull/1044#discussion_r104992901","pull_request_url":"https://api.github.com/repos/Yelp/paasta/pulls/1044","_links":{"self":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/comments/104992901"},"html":{"href":"https://github.com/Yelp/paasta/pull/1044#discussion_r104992901"},"pull_request":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/1044"}}},"pull_request":{"url":"https://api.github.com/repos/Yelp/paasta/pulls/1044","id":108213177,"html_url":"https://github.com/Yelp/paasta/pull/1044","diff_url":"https://github.com/Yelp/paasta/pull/1044.diff","patch_url":"https://github.com/Yelp/paasta/pull/1044.patch","issue_url":"https://api.github.com/repos/Yelp/paasta/issues/1044","number":1044,"state":"open","locked":false,"title":"Add basic support for NUMA cpu affinity settings. This enable the use…","user":{"login":"matfra","id":4550821,"avatar_url":"https://avatars1.githubusercontent.com/u/4550821?v=3","gravatar_id":"","url":"https://api.github.com/users/matfra","html_url":"https://github.com/matfra","followers_url":"https://api.github.com/users/matfra/followers","following_url":"https://api.github.com/users/matfra/following{/other_user}","gists_url":"https://api.github.com/users/matfra/gists{/gist_id}","starred_url":"https://api.github.com/users/matfra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matfra/subscriptions","organizations_url":"https://api.github.com/users/matfra/orgs","repos_url":"https://api.github.com/users/matfra/repos","events_url":"https://api.github.com/users/matfra/events{/privacy}","received_events_url":"https://api.github.com/users/matfra/received_events","type":"User","site_admin":false},"body":"Control which physical CPU and memory node docker will be running on using\r\ndocker options \"--cpuset-cpus\" and \"--cpuset-mems\". To enable it, simply\r\npass as a docker environment variable PIN_TO_NUMA_NODE=n where n is the\r\nid of a physical CPU (usually 0 or 1 on a dual CPU machine)","created_at":"2017-02-27T22:12:47Z","updated_at":"2017-03-08T18:52:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7c87023c8d918c8083e0df2997a3fb4497208f14","assignee":{"login":"matfra","id":4550821,"avatar_url":"https://avatars1.githubusercontent.com/u/4550821?v=3","gravatar_id":"","url":"https://api.github.com/users/matfra","html_url":"https://github.com/matfra","followers_url":"https://api.github.com/users/matfra/followers","following_url":"https://api.github.com/users/matfra/following{/other_user}","gists_url":"https://api.github.com/users/matfra/gists{/gist_id}","starred_url":"https://api.github.com/users/matfra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matfra/subscriptions","organizations_url":"https://api.github.com/users/matfra/orgs","repos_url":"https://api.github.com/users/matfra/repos","events_url":"https://api.github.com/users/matfra/events{/privacy}","received_events_url":"https://api.github.com/users/matfra/received_events","type":"User","site_admin":false},"assignees":[{"login":"matfra","id":4550821,"avatar_url":"https://avatars1.githubusercontent.com/u/4550821?v=3","gravatar_id":"","url":"https://api.github.com/users/matfra","html_url":"https://github.com/matfra","followers_url":"https://api.github.com/users/matfra/followers","following_url":"https://api.github.com/users/matfra/following{/other_user}","gists_url":"https://api.github.com/users/matfra/gists{/gist_id}","starred_url":"https://api.github.com/users/matfra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matfra/subscriptions","organizations_url":"https://api.github.com/users/matfra/orgs","repos_url":"https://api.github.com/users/matfra/repos","events_url":"https://api.github.com/users/matfra/events{/privacy}","received_events_url":"https://api.github.com/users/matfra/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/Yelp/paasta/pulls/1044/commits","review_comments_url":"https://api.github.com/repos/Yelp/paasta/pulls/1044/comments","review_comment_url":"https://api.github.com/repos/Yelp/paasta/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Yelp/paasta/issues/1044/comments","statuses_url":"https://api.github.com/repos/Yelp/paasta/statuses/b9e2c17ddddab0c6f8ed5c44f76365f15de33602","head":{"label":"Yelp:numa_isolation_docker_wrapper","ref":"numa_isolation_docker_wrapper","sha":"b9e2c17ddddab0c6f8ed5c44f76365f15de33602","user":{"login":"Yelp","id":49071,"avatar_url":"https://avatars2.githubusercontent.com/u/49071?v=3","gravatar_id":"","url":"https://api.github.com/users/Yelp","html_url":"https://github.com/Yelp","followers_url":"https://api.github.com/users/Yelp/followers","following_url":"https://api.github.com/users/Yelp/following{/other_user}","gists_url":"https://api.github.com/users/Yelp/gists{/gist_id}","starred_url":"https://api.github.com/users/Yelp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yelp/subscriptions","organizations_url":"https://api.github.com/users/Yelp/orgs","repos_url":"https://api.github.com/users/Yelp/repos","events_url":"https://api.github.com/users/Yelp/events{/privacy}","received_events_url":"https://api.github.com/users/Yelp/received_events","type":"Organization","site_admin":false},"repo":{"id":44998824,"name":"paasta","full_name":"Yelp/paasta","owner":{"login":"Yelp","id":49071,"avatar_url":"https://avatars2.githubusercontent.com/u/49071?v=3","gravatar_id":"","url":"https://api.github.com/users/Yelp","html_url":"https://github.com/Yelp","followers_url":"https://api.github.com/users/Yelp/followers","following_url":"https://api.github.com/users/Yelp/following{/other_user}","gists_url":"https://api.github.com/users/Yelp/gists{/gist_id}","starred_url":"https://api.github.com/users/Yelp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yelp/subscriptions","organizations_url":"https://api.github.com/users/Yelp/orgs","repos_url":"https://api.github.com/users/Yelp/repos","events_url":"https://api.github.com/users/Yelp/events{/privacy}","received_events_url":"https://api.github.com/users/Yelp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Yelp/paasta","description":"An open, distributed platform as a service","fork":false,"url":"https://api.github.com/repos/Yelp/paasta","forks_url":"https://api.github.com/repos/Yelp/paasta/forks","keys_url":"https://api.github.com/repos/Yelp/paasta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Yelp/paasta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Yelp/paasta/teams","hooks_url":"https://api.github.com/repos/Yelp/paasta/hooks","issue_events_url":"https://api.github.com/repos/Yelp/paasta/issues/events{/number}","events_url":"https://api.github.com/repos/Yelp/paasta/events","assignees_url":"https://api.github.com/repos/Yelp/paasta/assignees{/user}","branches_url":"https://api.github.com/repos/Yelp/paasta/branches{/branch}","tags_url":"https://api.github.com/repos/Yelp/paasta/tags","blobs_url":"https://api.github.com/repos/Yelp/paasta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Yelp/paasta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Yelp/paasta/git/refs{/sha}","trees_url":"https://api.github.com/repos/Yelp/paasta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Yelp/paasta/statuses/{sha}","languages_url":"https://api.github.com/repos/Yelp/paasta/languages","stargazers_url":"https://api.github.com/repos/Yelp/paasta/stargazers","contributors_url":"https://api.github.com/repos/Yelp/paasta/contributors","subscribers_url":"https://api.github.com/repos/Yelp/paasta/subscribers","subscription_url":"https://api.github.com/repos/Yelp/paasta/subscription","commits_url":"https://api.github.com/repos/Yelp/paasta/commits{/sha}","git_commits_url":"https://api.github.com/repos/Yelp/paasta/git/commits{/sha}","comments_url":"https://api.github.com/repos/Yelp/paasta/comments{/number}","issue_comment_url":"https://api.github.com/repos/Yelp/paasta/issues/comments{/number}","contents_url":"https://api.github.com/repos/Yelp/paasta/contents/{+path}","compare_url":"https://api.github.com/repos/Yelp/paasta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Yelp/paasta/merges","archive_url":"https://api.github.com/repos/Yelp/paasta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Yelp/paasta/downloads","issues_url":"https://api.github.com/repos/Yelp/paasta/issues{/number}","pulls_url":"https://api.github.com/repos/Yelp/paasta/pulls{/number}","milestones_url":"https://api.github.com/repos/Yelp/paasta/milestones{/number}","notifications_url":"https://api.github.com/repos/Yelp/paasta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Yelp/paasta/labels{/name}","releases_url":"https://api.github.com/repos/Yelp/paasta/releases{/id}","deployments_url":"https://api.github.com/repos/Yelp/paasta/deployments","created_at":"2015-10-26T21:35:53Z","updated_at":"2017-03-08T07:38:19Z","pushed_at":"2017-03-08T18:27:14Z","git_url":"git://github.com/Yelp/paasta.git","ssh_url":"git@github.com:Yelp/paasta.git","clone_url":"https://github.com/Yelp/paasta.git","svn_url":"https://github.com/Yelp/paasta","homepage":"","size":13816,"stargazers_count":995,"watchers_count":995,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":110,"mirror_url":null,"open_issues_count":79,"forks":110,"open_issues":79,"watchers":995,"default_branch":"master"}},"base":{"label":"Yelp:master","ref":"master","sha":"5d55c65482a007bcf1ef921d29d3255733e3cd49","user":{"login":"Yelp","id":49071,"avatar_url":"https://avatars2.githubusercontent.com/u/49071?v=3","gravatar_id":"","url":"https://api.github.com/users/Yelp","html_url":"https://github.com/Yelp","followers_url":"https://api.github.com/users/Yelp/followers","following_url":"https://api.github.com/users/Yelp/following{/other_user}","gists_url":"https://api.github.com/users/Yelp/gists{/gist_id}","starred_url":"https://api.github.com/users/Yelp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yelp/subscriptions","organizations_url":"https://api.github.com/users/Yelp/orgs","repos_url":"https://api.github.com/users/Yelp/repos","events_url":"https://api.github.com/users/Yelp/events{/privacy}","received_events_url":"https://api.github.com/users/Yelp/received_events","type":"Organization","site_admin":false},"repo":{"id":44998824,"name":"paasta","full_name":"Yelp/paasta","owner":{"login":"Yelp","id":49071,"avatar_url":"https://avatars2.githubusercontent.com/u/49071?v=3","gravatar_id":"","url":"https://api.github.com/users/Yelp","html_url":"https://github.com/Yelp","followers_url":"https://api.github.com/users/Yelp/followers","following_url":"https://api.github.com/users/Yelp/following{/other_user}","gists_url":"https://api.github.com/users/Yelp/gists{/gist_id}","starred_url":"https://api.github.com/users/Yelp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yelp/subscriptions","organizations_url":"https://api.github.com/users/Yelp/orgs","repos_url":"https://api.github.com/users/Yelp/repos","events_url":"https://api.github.com/users/Yelp/events{/privacy}","received_events_url":"https://api.github.com/users/Yelp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Yelp/paasta","description":"An open, distributed platform as a service","fork":false,"url":"https://api.github.com/repos/Yelp/paasta","forks_url":"https://api.github.com/repos/Yelp/paasta/forks","keys_url":"https://api.github.com/repos/Yelp/paasta/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Yelp/paasta/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Yelp/paasta/teams","hooks_url":"https://api.github.com/repos/Yelp/paasta/hooks","issue_events_url":"https://api.github.com/repos/Yelp/paasta/issues/events{/number}","events_url":"https://api.github.com/repos/Yelp/paasta/events","assignees_url":"https://api.github.com/repos/Yelp/paasta/assignees{/user}","branches_url":"https://api.github.com/repos/Yelp/paasta/branches{/branch}","tags_url":"https://api.github.com/repos/Yelp/paasta/tags","blobs_url":"https://api.github.com/repos/Yelp/paasta/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Yelp/paasta/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Yelp/paasta/git/refs{/sha}","trees_url":"https://api.github.com/repos/Yelp/paasta/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Yelp/paasta/statuses/{sha}","languages_url":"https://api.github.com/repos/Yelp/paasta/languages","stargazers_url":"https://api.github.com/repos/Yelp/paasta/stargazers","contributors_url":"https://api.github.com/repos/Yelp/paasta/contributors","subscribers_url":"https://api.github.com/repos/Yelp/paasta/subscribers","subscription_url":"https://api.github.com/repos/Yelp/paasta/subscription","commits_url":"https://api.github.com/repos/Yelp/paasta/commits{/sha}","git_commits_url":"https://api.github.com/repos/Yelp/paasta/git/commits{/sha}","comments_url":"https://api.github.com/repos/Yelp/paasta/comments{/number}","issue_comment_url":"https://api.github.com/repos/Yelp/paasta/issues/comments{/number}","contents_url":"https://api.github.com/repos/Yelp/paasta/contents/{+path}","compare_url":"https://api.github.com/repos/Yelp/paasta/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Yelp/paasta/merges","archive_url":"https://api.github.com/repos/Yelp/paasta/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Yelp/paasta/downloads","issues_url":"https://api.github.com/repos/Yelp/paasta/issues{/number}","pulls_url":"https://api.github.com/repos/Yelp/paasta/pulls{/number}","milestones_url":"https://api.github.com/repos/Yelp/paasta/milestones{/number}","notifications_url":"https://api.github.com/repos/Yelp/paasta/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Yelp/paasta/labels{/name}","releases_url":"https://api.github.com/repos/Yelp/paasta/releases{/id}","deployments_url":"https://api.github.com/repos/Yelp/paasta/deployments","created_at":"2015-10-26T21:35:53Z","updated_at":"2017-03-08T07:38:19Z","pushed_at":"2017-03-08T18:27:14Z","git_url":"git://github.com/Yelp/paasta.git","ssh_url":"git@github.com:Yelp/paasta.git","clone_url":"https://github.com/Yelp/paasta.git","svn_url":"https://github.com/Yelp/paasta","homepage":"","size":13816,"stargazers_count":995,"watchers_count":995,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":110,"mirror_url":null,"open_issues_count":79,"forks":110,"open_issues":79,"watchers":995,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/1044"},"html":{"href":"https://github.com/Yelp/paasta/pull/1044"},"issue":{"href":"https://api.github.com/repos/Yelp/paasta/issues/1044"},"comments":{"href":"https://api.github.com/repos/Yelp/paasta/issues/1044/comments"},"review_comments":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/1044/comments"},"review_comment":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Yelp/paasta/pulls/1044/commits"},"statuses":{"href":"https://api.github.com/repos/Yelp/paasta/statuses/b9e2c17ddddab0c6f8ed5c44f76365f15de33602"}}}}
{"actor":{"display_login":"solarkennedy"}}