{"action":"created","comment":{"url":"https://api.github.com/repos/openvcloud/0-templates/pulls/comments/170451288","pull_request_review_id":99141238,"id":170451288,"diff_hunk":"@@ -0,0 +1,277 @@\n+from js9 import j\n+from zerorobot.template.base import TemplateBase\n+from zerorobot.template.state import StateCheckError\n+\n+class Node(TemplateBase):\n+\n+    version = '0.0.1'\n+    template_name = \"node\"\n+\n+    VDC_TEMPLATE = 'github.com/openvcloud/0-templates/vdc/0.0.1'\n+    SSH_TEMPLATE = 'github.com/openvcloud/0-templates/sshkey/0.0.1'\n+    DISK_TEMPLATE = 'github.com/openvcloud/0-templates/disk/0.0.1'\n+\n+    def __init__(self, name, guid=None, data=None):\n+        super().__init__(name=name, guid=guid, data=data)\n+\n+        self._ovc = None\n+        self._vdc = None\n+        self._machine = None\n+\n+    def validate(self):\n+        if not self.data['vdc']:\n+            raise RuntimeError('vdc name should be given')\n+        # ensure uploaded key\n+        self.sshkey\n+\n+    def update_data(self, data):\n+        # merge the new data\n+        self.data.update(data)\n+        self.save()\n+\n+    @property\n+    def ovc(self):\n+        \"\"\"\n+        An ovc connection instance\n+        \"\"\"\n+        if self._ovc is not None:\n+            return self._ovc\n+        \n+        vdc = self.vdc\n+        instance = vdc.ovc.instance\n+        self._ovc = j.clients.openvcloud.get(instance=instance)\n+\n+        return self._ovc\n+\n+    @property\n+    def vdc(self):\n+        if self._vdc:\n+            return self._vdc\n+\n+        # Get object for an VDC service, make sure exactly one is running\n+        vdc = self.api.services.find(template_uid=self.VDC_TEMPLATE, name=self.data['vdc'])\n+        if len(vdc) != 1:\n+            raise RuntimeError('found %s vdc, requires exactly 1' % len(vdc))\n+        \n+        self._vdc = vdc[0]\n+\n+        return self._vdc\n+\n+    @property\n+    def space(self):\n+        return self.ovc.space_get(\n+            accountName=None,\n+            spaceName=self.data['vdc']\n+            )\n+\n+    @property\n+    def sshkey(self):\n+        \"\"\" Get a path and keyname of the sshkey service \"\"\"\n+\n+        sshkeys = self.api.services.find(template_uid=self.SSH_TEMPLATE)\n+        if len(sshkeys) == 0:\n+            raise RuntimeError('no %s ssh services found' % len(sshkeys))\n+\n+        # Get key name and path\n+        path = sshkeys[0].data['path']\n+        key = path.split('/')[-1]\n+\n+        return key         \n+\n+    @property\n+    def machine(self):\n+        if self._machine:\n+            return self._machine\n+        return self.space.machines.get(self.name)\n+\n+    def install(self):\n+        try:\n+            self.state.check('actions', 'install', 'ok')\n+            return\n+        except StateCheckError:\n+            pass        \n+\n+        machine = self.machine\n+        if not machine:\n+            machine = self._machine_create()\n+\n+        # Get data from the vm\n+        ip_private, vm_info = machine.machineip_get()\n+        self.data['sshLogin'] = vm_info['accounts'][0]['login']\n+        self.data['sshPassword']= vm_info['accounts'][0]['password']\n+        self.data['ipPrivate'] = ip_private\n+        self.data['ipPublic'] = machine.space.model['publicipaddress']\n+        self.data['machineId'] = machine.id\n+\n+        self.portforward_create(self.data['ports'])\n+        self._configure_disks()\n+        self.save()\n+\n+        self.state.set('actions', 'install', 'ok')\n+\n+    def _machine_create(self):\n+        \"\"\" Create a new machine \"\"\"\n+        data = self.data\n+        space = self.space\n+        self._machine = space.machine_create(\n+            name=self.name,\n+            sshkeyname= self.sshkey,\n+            image=data['osImage'],\n+            disksize=data['bootDiskSize'],\n+            datadisks=[data['dataDiskSize']],\n+            sizeId=data['sizeId'],\n+            )\n+\n+        return self._machine\n+\n+    def _configure_disks(self):\n+        \"\"\"\n+        Configure one boot disk and one data disk when installing a machine.\n+        \"\"\"\n+        machine = self.machine\n+        space_name = machine.space.model['name']\n+        if machine:\n+            machine.start()\n+        else:\n+            raise RuntimeError('machine %s in not found' % self.name)        \n+\n+        for disk in machine.disks:\n+            # create a disk service\n+            service = self.api.services.create(\n+                template_uid=self.DISK_TEMPLATE, \n+                service_name= 'Disk%s' % str(disk['id']),\n+                data={'vdc' : space_name},\n+            )\n+            # update data in the disk service\n+            task = service.schedule_action('update_data', {'data':disk})\n+            task.wait()\n+            # limmit disk with default limits\n+            task = service.schedule_action('limit_io')\n+            task.wait()                   \n+\n+\n+    def uninstall(self):\n+        \"\"\" Uninstall machine \"\"\"\n+        if not self.machine:\n+            raise RuntimeError('machine %s in not found' % self.name)\n+        self.machine.delete()\n+\n+    def portforward_create(self, ports):\n+        \"\"\" Add portforwards \"\"\"\n+        if not self.machine:\n+            raise RuntimeError('machine %s in not found' % self.name)\n+\n+        # get vdc service\n+        task = self.vdc.schedule_action('portforward_create', \n+                                        {'machineId':self.machine.id, 'port_forwards':ports, 'protocol':'tcp'})\n+        task.wait()","path":"templates/node/node.py","position":167,"original_position":167,"commit_id":"b02df9099a254dba449220cf3fb25e21b96cec57","original_commit_id":"b02df9099a254dba449220cf3fb25e21b96cec57","user":{"login":"muhamadazmy","id":10920323,"avatar_url":"https://avatars1.githubusercontent.com/u/10920323?v=4","gravatar_id":"","url":"https://api.github.com/users/muhamadazmy","html_url":"https://github.com/muhamadazmy","followers_url":"https://api.github.com/users/muhamadazmy/followers","following_url":"https://api.github.com/users/muhamadazmy/following{/other_user}","gists_url":"https://api.github.com/users/muhamadazmy/gists{/gist_id}","starred_url":"https://api.github.com/users/muhamadazmy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/muhamadazmy/subscriptions","organizations_url":"https://api.github.com/users/muhamadazmy/orgs","repos_url":"https://api.github.com/users/muhamadazmy/repos","events_url":"https://api.github.com/users/muhamadazmy/events{/privacy}","received_events_url":"https://api.github.com/users/muhamadazmy/received_events","type":"User","site_admin":false},"body":"Do we need to wait? i guess u only need to wait if u gonna use the results of this action. Hence waiting will just cause an over head (pulling for the action result).\r\n\r\nSame for the portforward_delete","created_at":"2018-02-25T12:23:26Z","updated_at":"2018-02-25T12:23:51Z","html_url":"https://github.com/openvcloud/0-templates/pull/19#discussion_r170451288","pull_request_url":"https://api.github.com/repos/openvcloud/0-templates/pulls/19","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/comments/170451288"},"html":{"href":"https://github.com/openvcloud/0-templates/pull/19#discussion_r170451288"},"pull_request":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/19"}}},"pull_request":{"url":"https://api.github.com/repos/openvcloud/0-templates/pulls/19","id":170020847,"html_url":"https://github.com/openvcloud/0-templates/pull/19","diff_url":"https://github.com/openvcloud/0-templates/pull/19.diff","patch_url":"https://github.com/openvcloud/0-templates/pull/19.patch","issue_url":"https://api.github.com/repos/openvcloud/0-templates/issues/19","number":19,"state":"open","locked":false,"title":"Nodeovc","user":{"login":"katia-e","id":32639869,"avatar_url":"https://avatars3.githubusercontent.com/u/32639869?v=4","gravatar_id":"","url":"https://api.github.com/users/katia-e","html_url":"https://github.com/katia-e","followers_url":"https://api.github.com/users/katia-e/followers","following_url":"https://api.github.com/users/katia-e/following{/other_user}","gists_url":"https://api.github.com/users/katia-e/gists{/gist_id}","starred_url":"https://api.github.com/users/katia-e/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/katia-e/subscriptions","organizations_url":"https://api.github.com/users/katia-e/orgs","repos_url":"https://api.github.com/users/katia-e/repos","events_url":"https://api.github.com/users/katia-e/events{/privacy}","received_events_url":"https://api.github.com/users/katia-e/received_events","type":"User","site_admin":false},"body":"This PR covers most of actions on a VM(#8), except actions with disk.","created_at":"2018-02-19T17:43:53Z","updated_at":"2018-02-25T12:23:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ad0abc46d85de269dd9edab146de2e4fc6877485","assignee":null,"assignees":[],"requested_reviewers":[{"login":"FastGeert","id":15246294,"avatar_url":"https://avatars2.githubusercontent.com/u/15246294?v=4","gravatar_id":"","url":"https://api.github.com/users/FastGeert","html_url":"https://github.com/FastGeert","followers_url":"https://api.github.com/users/FastGeert/followers","following_url":"https://api.github.com/users/FastGeert/following{/other_user}","gists_url":"https://api.github.com/users/FastGeert/gists{/gist_id}","starred_url":"https://api.github.com/users/FastGeert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FastGeert/subscriptions","organizations_url":"https://api.github.com/users/FastGeert/orgs","repos_url":"https://api.github.com/users/FastGeert/repos","events_url":"https://api.github.com/users/FastGeert/events{/privacy}","received_events_url":"https://api.github.com/users/FastGeert/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":828469079,"url":"https://api.github.com/repos/openvcloud/0-templates/labels/state_inprogress","name":"state_inprogress","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/openvcloud/0-templates/pulls/19/commits","review_comments_url":"https://api.github.com/repos/openvcloud/0-templates/pulls/19/comments","review_comment_url":"https://api.github.com/repos/openvcloud/0-templates/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openvcloud/0-templates/issues/19/comments","statuses_url":"https://api.github.com/repos/openvcloud/0-templates/statuses/b02df9099a254dba449220cf3fb25e21b96cec57","head":{"label":"openvcloud:nodeovc","ref":"nodeovc","sha":"b02df9099a254dba449220cf3fb25e21b96cec57","user":{"login":"openvcloud","id":31403827,"avatar_url":"https://avatars1.githubusercontent.com/u/31403827?v=4","gravatar_id":"","url":"https://api.github.com/users/openvcloud","html_url":"https://github.com/openvcloud","followers_url":"https://api.github.com/users/openvcloud/followers","following_url":"https://api.github.com/users/openvcloud/following{/other_user}","gists_url":"https://api.github.com/users/openvcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/openvcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openvcloud/subscriptions","organizations_url":"https://api.github.com/users/openvcloud/orgs","repos_url":"https://api.github.com/users/openvcloud/repos","events_url":"https://api.github.com/users/openvcloud/events{/privacy}","received_events_url":"https://api.github.com/users/openvcloud/received_events","type":"Organization","site_admin":false},"repo":{"id":119681678,"name":"0-templates","full_name":"openvcloud/0-templates","owner":{"login":"openvcloud","id":31403827,"avatar_url":"https://avatars1.githubusercontent.com/u/31403827?v=4","gravatar_id":"","url":"https://api.github.com/users/openvcloud","html_url":"https://github.com/openvcloud","followers_url":"https://api.github.com/users/openvcloud/followers","following_url":"https://api.github.com/users/openvcloud/following{/other_user}","gists_url":"https://api.github.com/users/openvcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/openvcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openvcloud/subscriptions","organizations_url":"https://api.github.com/users/openvcloud/orgs","repos_url":"https://api.github.com/users/openvcloud/repos","events_url":"https://api.github.com/users/openvcloud/events{/privacy}","received_events_url":"https://api.github.com/users/openvcloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openvcloud/0-templates","description":null,"fork":false,"url":"https://api.github.com/repos/openvcloud/0-templates","forks_url":"https://api.github.com/repos/openvcloud/0-templates/forks","keys_url":"https://api.github.com/repos/openvcloud/0-templates/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openvcloud/0-templates/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openvcloud/0-templates/teams","hooks_url":"https://api.github.com/repos/openvcloud/0-templates/hooks","issue_events_url":"https://api.github.com/repos/openvcloud/0-templates/issues/events{/number}","events_url":"https://api.github.com/repos/openvcloud/0-templates/events","assignees_url":"https://api.github.com/repos/openvcloud/0-templates/assignees{/user}","branches_url":"https://api.github.com/repos/openvcloud/0-templates/branches{/branch}","tags_url":"https://api.github.com/repos/openvcloud/0-templates/tags","blobs_url":"https://api.github.com/repos/openvcloud/0-templates/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openvcloud/0-templates/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openvcloud/0-templates/git/refs{/sha}","trees_url":"https://api.github.com/repos/openvcloud/0-templates/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openvcloud/0-templates/statuses/{sha}","languages_url":"https://api.github.com/repos/openvcloud/0-templates/languages","stargazers_url":"https://api.github.com/repos/openvcloud/0-templates/stargazers","contributors_url":"https://api.github.com/repos/openvcloud/0-templates/contributors","subscribers_url":"https://api.github.com/repos/openvcloud/0-templates/subscribers","subscription_url":"https://api.github.com/repos/openvcloud/0-templates/subscription","commits_url":"https://api.github.com/repos/openvcloud/0-templates/commits{/sha}","git_commits_url":"https://api.github.com/repos/openvcloud/0-templates/git/commits{/sha}","comments_url":"https://api.github.com/repos/openvcloud/0-templates/comments{/number}","issue_comment_url":"https://api.github.com/repos/openvcloud/0-templates/issues/comments{/number}","contents_url":"https://api.github.com/repos/openvcloud/0-templates/contents/{+path}","compare_url":"https://api.github.com/repos/openvcloud/0-templates/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openvcloud/0-templates/merges","archive_url":"https://api.github.com/repos/openvcloud/0-templates/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openvcloud/0-templates/downloads","issues_url":"https://api.github.com/repos/openvcloud/0-templates/issues{/number}","pulls_url":"https://api.github.com/repos/openvcloud/0-templates/pulls{/number}","milestones_url":"https://api.github.com/repos/openvcloud/0-templates/milestones{/number}","notifications_url":"https://api.github.com/repos/openvcloud/0-templates/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openvcloud/0-templates/labels{/name}","releases_url":"https://api.github.com/repos/openvcloud/0-templates/releases{/id}","deployments_url":"https://api.github.com/repos/openvcloud/0-templates/deployments","created_at":"2018-01-31T12:02:17Z","updated_at":"2018-02-20T09:16:03Z","pushed_at":"2018-02-25T11:58:13Z","git_url":"git://github.com/openvcloud/0-templates.git","ssh_url":"git@github.com:openvcloud/0-templates.git","clone_url":"https://github.com/openvcloud/0-templates.git","svn_url":"https://github.com/openvcloud/0-templates","homepage":null,"size":71,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":7,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":7,"watchers":0,"default_branch":"master"}},"base":{"label":"openvcloud:master","ref":"master","sha":"61a536de65e10ad5d67da54c7d7e1d3044623842","user":{"login":"openvcloud","id":31403827,"avatar_url":"https://avatars1.githubusercontent.com/u/31403827?v=4","gravatar_id":"","url":"https://api.github.com/users/openvcloud","html_url":"https://github.com/openvcloud","followers_url":"https://api.github.com/users/openvcloud/followers","following_url":"https://api.github.com/users/openvcloud/following{/other_user}","gists_url":"https://api.github.com/users/openvcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/openvcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openvcloud/subscriptions","organizations_url":"https://api.github.com/users/openvcloud/orgs","repos_url":"https://api.github.com/users/openvcloud/repos","events_url":"https://api.github.com/users/openvcloud/events{/privacy}","received_events_url":"https://api.github.com/users/openvcloud/received_events","type":"Organization","site_admin":false},"repo":{"id":119681678,"name":"0-templates","full_name":"openvcloud/0-templates","owner":{"login":"openvcloud","id":31403827,"avatar_url":"https://avatars1.githubusercontent.com/u/31403827?v=4","gravatar_id":"","url":"https://api.github.com/users/openvcloud","html_url":"https://github.com/openvcloud","followers_url":"https://api.github.com/users/openvcloud/followers","following_url":"https://api.github.com/users/openvcloud/following{/other_user}","gists_url":"https://api.github.com/users/openvcloud/gists{/gist_id}","starred_url":"https://api.github.com/users/openvcloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openvcloud/subscriptions","organizations_url":"https://api.github.com/users/openvcloud/orgs","repos_url":"https://api.github.com/users/openvcloud/repos","events_url":"https://api.github.com/users/openvcloud/events{/privacy}","received_events_url":"https://api.github.com/users/openvcloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openvcloud/0-templates","description":null,"fork":false,"url":"https://api.github.com/repos/openvcloud/0-templates","forks_url":"https://api.github.com/repos/openvcloud/0-templates/forks","keys_url":"https://api.github.com/repos/openvcloud/0-templates/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openvcloud/0-templates/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openvcloud/0-templates/teams","hooks_url":"https://api.github.com/repos/openvcloud/0-templates/hooks","issue_events_url":"https://api.github.com/repos/openvcloud/0-templates/issues/events{/number}","events_url":"https://api.github.com/repos/openvcloud/0-templates/events","assignees_url":"https://api.github.com/repos/openvcloud/0-templates/assignees{/user}","branches_url":"https://api.github.com/repos/openvcloud/0-templates/branches{/branch}","tags_url":"https://api.github.com/repos/openvcloud/0-templates/tags","blobs_url":"https://api.github.com/repos/openvcloud/0-templates/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openvcloud/0-templates/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openvcloud/0-templates/git/refs{/sha}","trees_url":"https://api.github.com/repos/openvcloud/0-templates/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openvcloud/0-templates/statuses/{sha}","languages_url":"https://api.github.com/repos/openvcloud/0-templates/languages","stargazers_url":"https://api.github.com/repos/openvcloud/0-templates/stargazers","contributors_url":"https://api.github.com/repos/openvcloud/0-templates/contributors","subscribers_url":"https://api.github.com/repos/openvcloud/0-templates/subscribers","subscription_url":"https://api.github.com/repos/openvcloud/0-templates/subscription","commits_url":"https://api.github.com/repos/openvcloud/0-templates/commits{/sha}","git_commits_url":"https://api.github.com/repos/openvcloud/0-templates/git/commits{/sha}","comments_url":"https://api.github.com/repos/openvcloud/0-templates/comments{/number}","issue_comment_url":"https://api.github.com/repos/openvcloud/0-templates/issues/comments{/number}","contents_url":"https://api.github.com/repos/openvcloud/0-templates/contents/{+path}","compare_url":"https://api.github.com/repos/openvcloud/0-templates/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openvcloud/0-templates/merges","archive_url":"https://api.github.com/repos/openvcloud/0-templates/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openvcloud/0-templates/downloads","issues_url":"https://api.github.com/repos/openvcloud/0-templates/issues{/number}","pulls_url":"https://api.github.com/repos/openvcloud/0-templates/pulls{/number}","milestones_url":"https://api.github.com/repos/openvcloud/0-templates/milestones{/number}","notifications_url":"https://api.github.com/repos/openvcloud/0-templates/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openvcloud/0-templates/labels{/name}","releases_url":"https://api.github.com/repos/openvcloud/0-templates/releases{/id}","deployments_url":"https://api.github.com/repos/openvcloud/0-templates/deployments","created_at":"2018-01-31T12:02:17Z","updated_at":"2018-02-20T09:16:03Z","pushed_at":"2018-02-25T11:58:13Z","git_url":"git://github.com/openvcloud/0-templates.git","ssh_url":"git@github.com:openvcloud/0-templates.git","clone_url":"https://github.com/openvcloud/0-templates.git","svn_url":"https://github.com/openvcloud/0-templates","homepage":null,"size":71,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":7,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":7,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/19"},"html":{"href":"https://github.com/openvcloud/0-templates/pull/19"},"issue":{"href":"https://api.github.com/repos/openvcloud/0-templates/issues/19"},"comments":{"href":"https://api.github.com/repos/openvcloud/0-templates/issues/19/comments"},"review_comments":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/19/comments"},"review_comment":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openvcloud/0-templates/pulls/19/commits"},"statuses":{"href":"https://api.github.com/repos/openvcloud/0-templates/statuses/b02df9099a254dba449220cf3fb25e21b96cec57"}},"author_association":"NONE"}}
{"actor":{"display_login":"muhamadazmy"}}