{"action":"created","comment":{"url":"https://api.github.com/repos/ansible/ansible/pulls/comments/101578603","pull_request_review_id":22312270,"id":101578603,"diff_hunk":"@@ -0,0 +1,366 @@\n+#!/usr/bin/python\n+# -*- coding: utf-8 -*-\n+# (c) 2015, Adam Hamsik <haaaad@gmail.com>\n+#\n+# This file is part of Ansible\n+#\n+# This module is free software: you can redistribute it and/or modify\n+# it under the terms of the GNU General Public License as published by\n+# the Free Software Foundation, either version 3 of the License, or\n+# (at your option) any later version.\n+#\n+# This software is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU General Public License for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with this software.  If not, see <http://www.gnu.org/licenses/>.\n+\n+ANSIBLE_METADATA = {'status': ['preview'],\n+                    'supported_by': 'community',\n+                    'version': '1.0'}\n+\n+DOCUMENTATION = '''\n+---\n+module: mdadm\n+version_added: 2.3\n+short_description: Initialize and manage linux mdadm array\n+description: Create, Manage linux software raid\n+requirements: [ python json ]\n+options:\n+  state:\n+    description:\n+      - Defines action which can be either RAID creation or removal. This will assemble\n+        existing array if it exist od disks or it will try to create new one if it doesn't.\n+    choices: [ 'present', 'absent', 'examine', 'scan']\n+    default: present\n+  level:\n+    description:\n+      - type of array to create\n+    required: true\n+    default: 1\n+    choices: [0, 1, 5, 6]\n+  md_device:\n+    description:\n+      - Raid device path if this is not provided it will be autogenerated.\n+        When special value auto is used we will use autogenerated md disk name.\n+  raid_devices:\n+    description:\n+      - List of disk devices to add to RAID.\n+    required: true\n+    default: null\n+  spare_devices:\n+    description:\n+      - Number of spare devices in RAID build.\n+    required: true\n+    default: 0\n+  assume_clean:\n+    description:\n+      - Assume created array is clean.\n+    default: no\n+  force:\n+    description:\n+      - Force raid creation.\n+    default: no\n+author: Adam Hamsik <haaaad@gmail.com>\n+'''\n+\n+EXAMPLES = '''\n+mdadm:\n+  state: present\n+  level: 1\n+  md_device: /dev/md0\n+  raid_devices:\n+    - /dev/sda\n+    - /dev/sdb\n+    - /dev/sdc\n+  spare_devices: 1\n+  force: no\n+\n+mdadm:\n+  state: present\n+  level: 5\n+  md_device: auto\n+  raid_devices:\n+    - /dev/sda\n+    - /dev/sdb\n+\n+mdadm:\n+  state: examine\n+  md_device: /dev/md0\n+\n+mdadm:\n+  state: examine\n+  raid_devices:\n+    - /dev/sda\n+    - /dev/sdb\n+\n+mdadm:\n+  state: scan\n+register: list_of_raid_devices_on_system\n+'''\n+\n+RETURN = '''\n+#\n+'''\n+\n+# TODO:\n+#  1) Add support for starting RAID with some missing disks\n+#  3) It seems that mdadm returns different hash if it creates raid\n+#       device and when it's already created.\n+#  4) Use mdstat python library output\n+#\n+\n+RAID_CONF = {\n+    0:{'min_dev': 1, 'redundancy': 0},\n+    1:{'min_dev': 2, 'redundancy': 1},\n+    5:{'min_dev': 3, 'redundancy': 1},\n+    6:{'min_dev': 4, 'redundancy': 2},\n+    10:{'min_dev': 4, 'redundancy': 2}\n+}\n+\n+class MdManager(object):\n+    '''\n+    MDADM raid manager class\n+    '''\n+    def __init__(self, module, md_device, level, raid_devices, spares):\n+        self.module = module\n+        self.level = level\n+        self.md_device = md_device\n+        self.raid_devices = raid_devices\n+        self.spares = spares\n+\n+        self.test_mdadm()\n+\n+    def test_mdadm(self):\n+        ''' Test if mdadm is actuall executable or not '''\n+        test_cmd = \"mdadm --version\"\n+\n+        (md_rc, del_out, del_err) = self.module.run_command(test_cmd, check_rc=True)\n+\n+    def test_raid_level_disks_number(self):\n+        ''' Check if we have proper number of disks for givel RAID level. '''\n+        if not RAID_CONF.get(self.level, None):\n+            self.module.fail_json(msg=\"Unsupported RAID level '%d' used\"% self.level, level=self.level)\n+\n+        min_dev = RAID_CONF[self.level]['min_dev']\n+        disk_red = 0 #TODO: intentionaly set to 0 until missing disk support is done RAID_CONF[level]['redundancy']\n+\n+        # Starting Number of devices in RAID Array can be lower that min_dev - redundancy\n+        if (min_dev - disk_red) > len(self.raid_devices):\n+            self.module.fail_json(msg=\"Not enough RAID disks provided '%d' for level '%d', minimum is '%d'\"\n+                                  % (len(self.raid_devices), self.level, (min_dev - disk_red)),\n+                                  level=self.level, raid_devices=self.raid_devices)\n+\n+        return True\n+\n+    def test_raid_disks(self, level, md_device):\n+        ''' Check if there is a raid superblock already present on given disks '''\n+\n+        for disk in self.raid_devices:\n+            test_cmd = \"mdadm --examine --test %s\" % disk","path":"lib/ansible/modules/system/mdadm.py","position":162,"original_position":162,"commit_id":"47b14525f840734057870ec7e02833fc25d1ff06","original_commit_id":"47b14525f840734057870ec7e02833fc25d1ff06","user":{"login":"bcoca","id":836171,"avatar_url":"https://avatars.githubusercontent.com/u/836171?v=3","gravatar_id":"","url":"https://api.github.com/users/bcoca","html_url":"https://github.com/bcoca","followers_url":"https://api.github.com/users/bcoca/followers","following_url":"https://api.github.com/users/bcoca/following{/other_user}","gists_url":"https://api.github.com/users/bcoca/gists{/gist_id}","starred_url":"https://api.github.com/users/bcoca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bcoca/subscriptions","organizations_url":"https://api.github.com/users/bcoca/orgs","repos_url":"https://api.github.com/users/bcoca/repos","events_url":"https://api.github.com/users/bcoca/events{/privacy}","received_events_url":"https://api.github.com/users/bcoca/received_events","type":"User","site_admin":false},"body":"I would not as .format breaks in older versions and we are trying to still keep this kind of module working on older machines","created_at":"2017-02-16T17:28:40Z","updated_at":"2017-02-16T17:28:40Z","html_url":"https://github.com/ansible/ansible/pull/20275#discussion_r101578603","pull_request_url":"https://api.github.com/repos/ansible/ansible/pulls/20275","_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible/pulls/comments/101578603"},"html":{"href":"https://github.com/ansible/ansible/pull/20275#discussion_r101578603"},"pull_request":{"href":"https://api.github.com/repos/ansible/ansible/pulls/20275"}}},"pull_request":{"url":"https://api.github.com/repos/ansible/ansible/pulls/20275","id":101611770,"html_url":"https://github.com/ansible/ansible/pull/20275","diff_url":"https://github.com/ansible/ansible/pull/20275.diff","patch_url":"https://github.com/ansible/ansible/pull/20275.patch","issue_url":"https://api.github.com/repos/ansible/ansible/issues/20275","number":20275,"state":"open","locked":false,"title":"Add initial version of mdadm module for managing linux raid disks.","user":{"login":"haad","id":67790,"avatar_url":"https://avatars.githubusercontent.com/u/67790?v=3","gravatar_id":"","url":"https://api.github.com/users/haad","html_url":"https://github.com/haad","followers_url":"https://api.github.com/users/haad/followers","following_url":"https://api.github.com/users/haad/following{/other_user}","gists_url":"https://api.github.com/users/haad/gists{/gist_id}","starred_url":"https://api.github.com/users/haad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haad/subscriptions","organizations_url":"https://api.github.com/users/haad/orgs","repos_url":"https://api.github.com/users/haad/repos","events_url":"https://api.github.com/users/haad/events{/privacy}","received_events_url":"https://api.github.com/users/haad/received_events","type":"User","site_admin":false},"body":"ISSUE TYPE\r\n\r\n    Feature Pull Request\r\n\r\nSUMMARY\r\n\r\nAdd module for managing linux software raid disks","created_at":"2017-01-15T22:07:19Z","updated_at":"2017-02-16T17:28:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c7e00d802ebe18be97c576d5ecde5044b9c4a4d5","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/ansible/ansible/pulls/20275/commits","review_comments_url":"https://api.github.com/repos/ansible/ansible/pulls/20275/comments","review_comment_url":"https://api.github.com/repos/ansible/ansible/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ansible/ansible/issues/20275/comments","statuses_url":"https://api.github.com/repos/ansible/ansible/statuses/47b14525f840734057870ec7e02833fc25d1ff06","head":{"label":"haad:mdadm","ref":"mdadm","sha":"47b14525f840734057870ec7e02833fc25d1ff06","user":{"login":"haad","id":67790,"avatar_url":"https://avatars.githubusercontent.com/u/67790?v=3","gravatar_id":"","url":"https://api.github.com/users/haad","html_url":"https://github.com/haad","followers_url":"https://api.github.com/users/haad/followers","following_url":"https://api.github.com/users/haad/following{/other_user}","gists_url":"https://api.github.com/users/haad/gists{/gist_id}","starred_url":"https://api.github.com/users/haad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haad/subscriptions","organizations_url":"https://api.github.com/users/haad/orgs","repos_url":"https://api.github.com/users/haad/repos","events_url":"https://api.github.com/users/haad/events{/privacy}","received_events_url":"https://api.github.com/users/haad/received_events","type":"User","site_admin":false},"repo":{"id":22702536,"name":"ansible","full_name":"haad/ansible","owner":{"login":"haad","id":67790,"avatar_url":"https://avatars.githubusercontent.com/u/67790?v=3","gravatar_id":"","url":"https://api.github.com/users/haad","html_url":"https://github.com/haad","followers_url":"https://api.github.com/users/haad/followers","following_url":"https://api.github.com/users/haad/following{/other_user}","gists_url":"https://api.github.com/users/haad/gists{/gist_id}","starred_url":"https://api.github.com/users/haad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haad/subscriptions","organizations_url":"https://api.github.com/users/haad/orgs","repos_url":"https://api.github.com/users/haad/repos","events_url":"https://api.github.com/users/haad/events{/privacy}","received_events_url":"https://api.github.com/users/haad/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/haad/ansible","description":"Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications— automate in a language that approaches plain English, using SSH, with no agents to install on remote systems.","fork":true,"url":"https://api.github.com/repos/haad/ansible","forks_url":"https://api.github.com/repos/haad/ansible/forks","keys_url":"https://api.github.com/repos/haad/ansible/keys{/key_id}","collaborators_url":"https://api.github.com/repos/haad/ansible/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/haad/ansible/teams","hooks_url":"https://api.github.com/repos/haad/ansible/hooks","issue_events_url":"https://api.github.com/repos/haad/ansible/issues/events{/number}","events_url":"https://api.github.com/repos/haad/ansible/events","assignees_url":"https://api.github.com/repos/haad/ansible/assignees{/user}","branches_url":"https://api.github.com/repos/haad/ansible/branches{/branch}","tags_url":"https://api.github.com/repos/haad/ansible/tags","blobs_url":"https://api.github.com/repos/haad/ansible/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/haad/ansible/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/haad/ansible/git/refs{/sha}","trees_url":"https://api.github.com/repos/haad/ansible/git/trees{/sha}","statuses_url":"https://api.github.com/repos/haad/ansible/statuses/{sha}","languages_url":"https://api.github.com/repos/haad/ansible/languages","stargazers_url":"https://api.github.com/repos/haad/ansible/stargazers","contributors_url":"https://api.github.com/repos/haad/ansible/contributors","subscribers_url":"https://api.github.com/repos/haad/ansible/subscribers","subscription_url":"https://api.github.com/repos/haad/ansible/subscription","commits_url":"https://api.github.com/repos/haad/ansible/commits{/sha}","git_commits_url":"https://api.github.com/repos/haad/ansible/git/commits{/sha}","comments_url":"https://api.github.com/repos/haad/ansible/comments{/number}","issue_comment_url":"https://api.github.com/repos/haad/ansible/issues/comments{/number}","contents_url":"https://api.github.com/repos/haad/ansible/contents/{+path}","compare_url":"https://api.github.com/repos/haad/ansible/compare/{base}...{head}","merges_url":"https://api.github.com/repos/haad/ansible/merges","archive_url":"https://api.github.com/repos/haad/ansible/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/haad/ansible/downloads","issues_url":"https://api.github.com/repos/haad/ansible/issues{/number}","pulls_url":"https://api.github.com/repos/haad/ansible/pulls{/number}","milestones_url":"https://api.github.com/repos/haad/ansible/milestones{/number}","notifications_url":"https://api.github.com/repos/haad/ansible/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/haad/ansible/labels{/name}","releases_url":"https://api.github.com/repos/haad/ansible/releases{/id}","deployments_url":"https://api.github.com/repos/haad/ansible/deployments","created_at":"2014-08-07T00:13:10Z","updated_at":"2016-03-30T09:16:20Z","pushed_at":"2017-02-15T09:28:23Z","git_url":"git://github.com/haad/ansible.git","ssh_url":"git@github.com:haad/ansible.git","clone_url":"https://github.com/haad/ansible.git","svn_url":"https://github.com/haad/ansible","homepage":"http://ansible.com/","size":62575,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"devel"}},"base":{"label":"ansible:devel","ref":"devel","sha":"c5d3aac8229307de09e9411ce0b0eed44cb712cc","user":{"login":"ansible","id":1507452,"avatar_url":"https://avatars.githubusercontent.com/u/1507452?v=3","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"repo":{"id":3638964,"name":"ansible","full_name":"ansible/ansible","owner":{"login":"ansible","id":1507452,"avatar_url":"https://avatars.githubusercontent.com/u/1507452?v=3","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ansible/ansible","description":"Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications— automate in a language that approaches plain English, using SSH, with no agents to install on remote systems.","fork":false,"url":"https://api.github.com/repos/ansible/ansible","forks_url":"https://api.github.com/repos/ansible/ansible/forks","keys_url":"https://api.github.com/repos/ansible/ansible/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ansible/ansible/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ansible/ansible/teams","hooks_url":"https://api.github.com/repos/ansible/ansible/hooks","issue_events_url":"https://api.github.com/repos/ansible/ansible/issues/events{/number}","events_url":"https://api.github.com/repos/ansible/ansible/events","assignees_url":"https://api.github.com/repos/ansible/ansible/assignees{/user}","branches_url":"https://api.github.com/repos/ansible/ansible/branches{/branch}","tags_url":"https://api.github.com/repos/ansible/ansible/tags","blobs_url":"https://api.github.com/repos/ansible/ansible/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ansible/ansible/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ansible/ansible/git/refs{/sha}","trees_url":"https://api.github.com/repos/ansible/ansible/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ansible/ansible/statuses/{sha}","languages_url":"https://api.github.com/repos/ansible/ansible/languages","stargazers_url":"https://api.github.com/repos/ansible/ansible/stargazers","contributors_url":"https://api.github.com/repos/ansible/ansible/contributors","subscribers_url":"https://api.github.com/repos/ansible/ansible/subscribers","subscription_url":"https://api.github.com/repos/ansible/ansible/subscription","commits_url":"https://api.github.com/repos/ansible/ansible/commits{/sha}","git_commits_url":"https://api.github.com/repos/ansible/ansible/git/commits{/sha}","comments_url":"https://api.github.com/repos/ansible/ansible/comments{/number}","issue_comment_url":"https://api.github.com/repos/ansible/ansible/issues/comments{/number}","contents_url":"https://api.github.com/repos/ansible/ansible/contents/{+path}","compare_url":"https://api.github.com/repos/ansible/ansible/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ansible/ansible/merges","archive_url":"https://api.github.com/repos/ansible/ansible/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ansible/ansible/downloads","issues_url":"https://api.github.com/repos/ansible/ansible/issues{/number}","pulls_url":"https://api.github.com/repos/ansible/ansible/pulls{/number}","milestones_url":"https://api.github.com/repos/ansible/ansible/milestones{/number}","notifications_url":"https://api.github.com/repos/ansible/ansible/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ansible/ansible/labels{/name}","releases_url":"https://api.github.com/repos/ansible/ansible/releases{/id}","deployments_url":"https://api.github.com/repos/ansible/ansible/deployments","created_at":"2012-03-06T14:58:02Z","updated_at":"2017-02-16T17:23:06Z","pushed_at":"2017-02-16T17:25:56Z","git_url":"git://github.com/ansible/ansible.git","ssh_url":"git@github.com:ansible/ansible.git","clone_url":"https://github.com/ansible/ansible.git","svn_url":"https://github.com/ansible/ansible","homepage":"http://ansible.com/","size":66450,"stargazers_count":21438,"watchers_count":21438,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6862,"mirror_url":null,"open_issues_count":2402,"forks":6862,"open_issues":2402,"watchers":21438,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible/pulls/20275"},"html":{"href":"https://github.com/ansible/ansible/pull/20275"},"issue":{"href":"https://api.github.com/repos/ansible/ansible/issues/20275"},"comments":{"href":"https://api.github.com/repos/ansible/ansible/issues/20275/comments"},"review_comments":{"href":"https://api.github.com/repos/ansible/ansible/pulls/20275/comments"},"review_comment":{"href":"https://api.github.com/repos/ansible/ansible/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ansible/ansible/pulls/20275/commits"},"statuses":{"href":"https://api.github.com/repos/ansible/ansible/statuses/47b14525f840734057870ec7e02833fc25d1ff06"}}}}
{"actor":{"display_login":"bcoca"}}