{"action":"created","comment":{"url":"https://api.github.com/repos/StackStorm/st2/pulls/comments/45937049","id":45937049,"diff_hunk":"@@ -58,101 +56,110 @@ def do_register_cli_opts(opts, ignore_errors=False):\n                 raise\n \n \n-def _purge_action_models(execution_db):\n-    liveaction_id = execution_db.liveaction['id']\n+def _register_cli_opts():\n+    cli_opts = [\n+        cfg.StrOpt('timestamp', default=None,\n+                   help='Will delete execution and liveaction models older than ' +\n+                   'this UTC timestamp. ' +\n+                   'Example value: 2015-03-13T19:01:27.255542Z.'),\n+        cfg.StrOpt('action-ref', default='',\n+                   help='action-ref to delete executions for.'),\n+        cfg.BoolOpt('purge-incomplete', default=False,\n+                    help='Purge all models irrespective of their ``status``.' +\n+                    'By default, only executions in completed states such as \"succeeeded\" ' +\n+                    ', \"failed\", \"canceled\" and \"timed_out\" are deleted.'),\n+    ]\n+    _do_register_cli_opts(cli_opts)\n+\n+\n+def _purge_models(execution_db):\n+    liveaction_id = execution_db.liveaction.get('id', None)\n \n     if not liveaction_id:\n-        print('Invalid LiveAction id. Skipping delete: %s', execution_db)\n+        LOG.error('Invalid LiveAction id. Skipping delete: %s', execution_db)\n \n     liveaction_db = None\n     try:\n         liveaction_db = LiveAction.get_by_id(liveaction_id)\n     except:\n-        print('LiveAction with id: %s not found. Skipping delete.', liveaction_id)\n+        LOG.exception('LiveAction with id: %s not found. Skipping delete.', liveaction_id)\n     else:\n         global DELETED_COUNT\n         DELETED_COUNT += 1\n \n     try:\n         ActionExecution.delete(execution_db)\n-    except Exception as e:\n-        print('Exception deleting Execution model: %s, exception: %s',\n-              execution_db, str(e))\n+    except:\n+        LOG.exception('Exception deleting Execution model: %s',\n+                      execution_db)\n     else:\n-        try:\n-            LiveAction.delete(liveaction_db)\n-        except Exception as e:\n-            print('Zombie LiveAction left in db: %s. Exception: %s',\n-                  liveaction_db, str(e))\n+        if liveaction_db:\n+            try:\n+                LiveAction.delete(liveaction_db)\n+            except:\n+                LOG.exception('Zombie LiveAction left in db: %s.', liveaction_db)\n+\n \n+def _should_delete(execution_db, action_ref, timestamp, purge_incomplete=False):\n+    if not purge_incomplete and execution_db.status in IN_PROGRESS_STATES:\n+        return False\n \n-def _purge_executions(timestamp=None, action_ref=None):\n+    if action_ref != '':\n+        return (execution_db.liveaction['action'] == action_ref and\n+                execution_db.start_timestamp < timestamp)\n+    else:\n+        return execution_db.start_timestamp < timestamp\n+\n+\n+def purge_executions(timestamp=None, action_ref=None, purge_incomplete=False):\n     if not timestamp:\n-        print('Specify a valid timestamp to purge.')\n+        LOG.error('Specify a valid timestamp to purge.')\n         return\n \n     if not action_ref:\n         action_ref = ''\n \n-    print('Purging executions older than timestamp: %s' %\n-          timestamp.strftime('%Y-%m-%dT%H:%M:%S.%fZ'))\n-\n-    def should_delete(execution_db):\n-        if action_ref != '':\n-            return (execution_db.liveaction['action'] == action_ref and\n-                    execution_db.start_timestamp < timestamp)\n-        else:\n-            return execution_db.start_timestamp < timestamp\n+    LOG.info('Purging executions older than timestamp: %s' %\n+             timestamp.strftime('%Y-%m-%dT%H:%M:%S.%fZ'))\n \n     # XXX: Think about paginating this call.\n-    filters = {'start_timestamp__lt': isotime.parse(timestamp)}\n+    filters = {'end_timestamp__lt': isotime.parse(timestamp)}\n     executions = ActionExecution.query(**filters)","path":"tools/purge_executions.py","position":144,"original_position":144,"commit_id":"4ae86f62af11acb6f5d83ff057391d6e8a6f8c14","original_commit_id":"4ae86f62af11acb6f5d83ff057391d6e8a6f8c14","user":{"login":"lakshmi-kannan","id":1839421,"avatar_url":"https://avatars.githubusercontent.com/u/1839421?v=3","gravatar_id":"","url":"https://api.github.com/users/lakshmi-kannan","html_url":"https://github.com/lakshmi-kannan","followers_url":"https://api.github.com/users/lakshmi-kannan/followers","following_url":"https://api.github.com/users/lakshmi-kannan/following{/other_user}","gists_url":"https://api.github.com/users/lakshmi-kannan/gists{/gist_id}","starred_url":"https://api.github.com/users/lakshmi-kannan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lakshmi-kannan/subscriptions","organizations_url":"https://api.github.com/users/lakshmi-kannan/orgs","repos_url":"https://api.github.com/users/lakshmi-kannan/repos","events_url":"https://api.github.com/users/lakshmi-kannan/events{/privacy}","received_events_url":"https://api.github.com/users/lakshmi-kannan/received_events","type":"User","site_admin":false},"body":"Good point. I'll make this change. ","created_at":"2015-11-26T01:31:29Z","updated_at":"2015-11-26T01:31:29Z","html_url":"https://github.com/StackStorm/st2/pull/2236#discussion_r45937049","pull_request_url":"https://api.github.com/repos/StackStorm/st2/pulls/2236","_links":{"self":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/comments/45937049"},"html":{"href":"https://github.com/StackStorm/st2/pull/2236#discussion_r45937049"},"pull_request":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/2236"}}},"pull_request":{"url":"https://api.github.com/repos/StackStorm/st2/pulls/2236","id":51738940,"html_url":"https://github.com/StackStorm/st2/pull/2236","diff_url":"https://github.com/StackStorm/st2/pull/2236.diff","patch_url":"https://github.com/StackStorm/st2/pull/2236.patch","issue_url":"https://api.github.com/repos/StackStorm/st2/issues/2236","number":2236,"state":"open","locked":false,"title":"RFR: Purge models ","user":{"login":"lakshmi-kannan","id":1839421,"avatar_url":"https://avatars.githubusercontent.com/u/1839421?v=3","gravatar_id":"","url":"https://api.github.com/users/lakshmi-kannan","html_url":"https://github.com/lakshmi-kannan","followers_url":"https://api.github.com/users/lakshmi-kannan/followers","following_url":"https://api.github.com/users/lakshmi-kannan/following{/other_user}","gists_url":"https://api.github.com/users/lakshmi-kannan/gists{/gist_id}","starred_url":"https://api.github.com/users/lakshmi-kannan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lakshmi-kannan/subscriptions","organizations_url":"https://api.github.com/users/lakshmi-kannan/orgs","repos_url":"https://api.github.com/users/lakshmi-kannan/repos","events_url":"https://api.github.com/users/lakshmi-kannan/events{/privacy}","received_events_url":"https://api.github.com/users/lakshmi-kannan/received_events","type":"User","site_admin":false},"body":"TODO:\r\n\r\n* - [X] Tests for purge executions\r\n* - [X] Purge trigger instances\r\n* - [X] Docs\r\n* - [X] Changelog\r\n\r\nEXAMPLES:\r\n\r\nhttps://gist.github.com/lakshmi-kannan/c7181d4bf6f5ab910bc3\r\nhttps://gist.github.com/lakshmi-kannan/af62e7872fbc61be4b1f","created_at":"2015-11-25T00:48:07Z","updated_at":"2015-11-26T01:31:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5efa9e77838dacde0ff0108610469f404fc31b14","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/StackStorm/st2/pulls/2236/commits","review_comments_url":"https://api.github.com/repos/StackStorm/st2/pulls/2236/comments","review_comment_url":"https://api.github.com/repos/StackStorm/st2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/StackStorm/st2/issues/2236/comments","statuses_url":"https://api.github.com/repos/StackStorm/st2/statuses/4ae86f62af11acb6f5d83ff057391d6e8a6f8c14","head":{"label":"lakshmi-kannan:purge_models","ref":"purge_models","sha":"4ae86f62af11acb6f5d83ff057391d6e8a6f8c14","user":{"login":"lakshmi-kannan","id":1839421,"avatar_url":"https://avatars.githubusercontent.com/u/1839421?v=3","gravatar_id":"","url":"https://api.github.com/users/lakshmi-kannan","html_url":"https://github.com/lakshmi-kannan","followers_url":"https://api.github.com/users/lakshmi-kannan/followers","following_url":"https://api.github.com/users/lakshmi-kannan/following{/other_user}","gists_url":"https://api.github.com/users/lakshmi-kannan/gists{/gist_id}","starred_url":"https://api.github.com/users/lakshmi-kannan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lakshmi-kannan/subscriptions","organizations_url":"https://api.github.com/users/lakshmi-kannan/orgs","repos_url":"https://api.github.com/users/lakshmi-kannan/repos","events_url":"https://api.github.com/users/lakshmi-kannan/events{/privacy}","received_events_url":"https://api.github.com/users/lakshmi-kannan/received_events","type":"User","site_admin":false},"repo":{"id":26183288,"name":"st2","full_name":"lakshmi-kannan/st2","owner":{"login":"lakshmi-kannan","id":1839421,"avatar_url":"https://avatars.githubusercontent.com/u/1839421?v=3","gravatar_id":"","url":"https://api.github.com/users/lakshmi-kannan","html_url":"https://github.com/lakshmi-kannan","followers_url":"https://api.github.com/users/lakshmi-kannan/followers","following_url":"https://api.github.com/users/lakshmi-kannan/following{/other_user}","gists_url":"https://api.github.com/users/lakshmi-kannan/gists{/gist_id}","starred_url":"https://api.github.com/users/lakshmi-kannan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lakshmi-kannan/subscriptions","organizations_url":"https://api.github.com/users/lakshmi-kannan/orgs","repos_url":"https://api.github.com/users/lakshmi-kannan/repos","events_url":"https://api.github.com/users/lakshmi-kannan/events{/privacy}","received_events_url":"https://api.github.com/users/lakshmi-kannan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lakshmi-kannan/st2","description":"Home of the StackStorm automation platform.","fork":true,"url":"https://api.github.com/repos/lakshmi-kannan/st2","forks_url":"https://api.github.com/repos/lakshmi-kannan/st2/forks","keys_url":"https://api.github.com/repos/lakshmi-kannan/st2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lakshmi-kannan/st2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lakshmi-kannan/st2/teams","hooks_url":"https://api.github.com/repos/lakshmi-kannan/st2/hooks","issue_events_url":"https://api.github.com/repos/lakshmi-kannan/st2/issues/events{/number}","events_url":"https://api.github.com/repos/lakshmi-kannan/st2/events","assignees_url":"https://api.github.com/repos/lakshmi-kannan/st2/assignees{/user}","branches_url":"https://api.github.com/repos/lakshmi-kannan/st2/branches{/branch}","tags_url":"https://api.github.com/repos/lakshmi-kannan/st2/tags","blobs_url":"https://api.github.com/repos/lakshmi-kannan/st2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lakshmi-kannan/st2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lakshmi-kannan/st2/git/refs{/sha}","trees_url":"https://api.github.com/repos/lakshmi-kannan/st2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lakshmi-kannan/st2/statuses/{sha}","languages_url":"https://api.github.com/repos/lakshmi-kannan/st2/languages","stargazers_url":"https://api.github.com/repos/lakshmi-kannan/st2/stargazers","contributors_url":"https://api.github.com/repos/lakshmi-kannan/st2/contributors","subscribers_url":"https://api.github.com/repos/lakshmi-kannan/st2/subscribers","subscription_url":"https://api.github.com/repos/lakshmi-kannan/st2/subscription","commits_url":"https://api.github.com/repos/lakshmi-kannan/st2/commits{/sha}","git_commits_url":"https://api.github.com/repos/lakshmi-kannan/st2/git/commits{/sha}","comments_url":"https://api.github.com/repos/lakshmi-kannan/st2/comments{/number}","issue_comment_url":"https://api.github.com/repos/lakshmi-kannan/st2/issues/comments{/number}","contents_url":"https://api.github.com/repos/lakshmi-kannan/st2/contents/{+path}","compare_url":"https://api.github.com/repos/lakshmi-kannan/st2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lakshmi-kannan/st2/merges","archive_url":"https://api.github.com/repos/lakshmi-kannan/st2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lakshmi-kannan/st2/downloads","issues_url":"https://api.github.com/repos/lakshmi-kannan/st2/issues{/number}","pulls_url":"https://api.github.com/repos/lakshmi-kannan/st2/pulls{/number}","milestones_url":"https://api.github.com/repos/lakshmi-kannan/st2/milestones{/number}","notifications_url":"https://api.github.com/repos/lakshmi-kannan/st2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lakshmi-kannan/st2/labels{/name}","releases_url":"https://api.github.com/repos/lakshmi-kannan/st2/releases{/id}","created_at":"2014-11-04T18:49:03Z","updated_at":"2015-02-13T05:59:12Z","pushed_at":"2015-11-26T00:56:32Z","git_url":"git://github.com/lakshmi-kannan/st2.git","ssh_url":"git@github.com:lakshmi-kannan/st2.git","clone_url":"https://github.com/lakshmi-kannan/st2.git","svn_url":"https://github.com/lakshmi-kannan/st2","homepage":"http://www.stackstorm.com/","size":12439,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"StackStorm:master","ref":"master","sha":"9c26f2e03c364ff28a50d165870dbc78a39d3831","user":{"login":"StackStorm","id":4969009,"avatar_url":"https://avatars.githubusercontent.com/u/4969009?v=3","gravatar_id":"","url":"https://api.github.com/users/StackStorm","html_url":"https://github.com/StackStorm","followers_url":"https://api.github.com/users/StackStorm/followers","following_url":"https://api.github.com/users/StackStorm/following{/other_user}","gists_url":"https://api.github.com/users/StackStorm/gists{/gist_id}","starred_url":"https://api.github.com/users/StackStorm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/StackStorm/subscriptions","organizations_url":"https://api.github.com/users/StackStorm/orgs","repos_url":"https://api.github.com/users/StackStorm/repos","events_url":"https://api.github.com/users/StackStorm/events{/privacy}","received_events_url":"https://api.github.com/users/StackStorm/received_events","type":"Organization","site_admin":false},"repo":{"id":19051806,"name":"st2","full_name":"StackStorm/st2","owner":{"login":"StackStorm","id":4969009,"avatar_url":"https://avatars.githubusercontent.com/u/4969009?v=3","gravatar_id":"","url":"https://api.github.com/users/StackStorm","html_url":"https://github.com/StackStorm","followers_url":"https://api.github.com/users/StackStorm/followers","following_url":"https://api.github.com/users/StackStorm/following{/other_user}","gists_url":"https://api.github.com/users/StackStorm/gists{/gist_id}","starred_url":"https://api.github.com/users/StackStorm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/StackStorm/subscriptions","organizations_url":"https://api.github.com/users/StackStorm/orgs","repos_url":"https://api.github.com/users/StackStorm/repos","events_url":"https://api.github.com/users/StackStorm/events{/privacy}","received_events_url":"https://api.github.com/users/StackStorm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/StackStorm/st2","description":"StackStorm (aka \"IFTTT for Ops\") is event-driven automation commonly used for auto-remediation, security responses, facilitated troubleshooting, complex deployments, and more. Includes rules engine, workflow, 1500+ integrations, native ChatOps and so forth.  Zingy installer available at http://docs.stackstorm.com/install/index.html. Ping us on slack - https://stackstorm-community.slack.com/. ","fork":false,"url":"https://api.github.com/repos/StackStorm/st2","forks_url":"https://api.github.com/repos/StackStorm/st2/forks","keys_url":"https://api.github.com/repos/StackStorm/st2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/StackStorm/st2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/StackStorm/st2/teams","hooks_url":"https://api.github.com/repos/StackStorm/st2/hooks","issue_events_url":"https://api.github.com/repos/StackStorm/st2/issues/events{/number}","events_url":"https://api.github.com/repos/StackStorm/st2/events","assignees_url":"https://api.github.com/repos/StackStorm/st2/assignees{/user}","branches_url":"https://api.github.com/repos/StackStorm/st2/branches{/branch}","tags_url":"https://api.github.com/repos/StackStorm/st2/tags","blobs_url":"https://api.github.com/repos/StackStorm/st2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/StackStorm/st2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/StackStorm/st2/git/refs{/sha}","trees_url":"https://api.github.com/repos/StackStorm/st2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/StackStorm/st2/statuses/{sha}","languages_url":"https://api.github.com/repos/StackStorm/st2/languages","stargazers_url":"https://api.github.com/repos/StackStorm/st2/stargazers","contributors_url":"https://api.github.com/repos/StackStorm/st2/contributors","subscribers_url":"https://api.github.com/repos/StackStorm/st2/subscribers","subscription_url":"https://api.github.com/repos/StackStorm/st2/subscription","commits_url":"https://api.github.com/repos/StackStorm/st2/commits{/sha}","git_commits_url":"https://api.github.com/repos/StackStorm/st2/git/commits{/sha}","comments_url":"https://api.github.com/repos/StackStorm/st2/comments{/number}","issue_comment_url":"https://api.github.com/repos/StackStorm/st2/issues/comments{/number}","contents_url":"https://api.github.com/repos/StackStorm/st2/contents/{+path}","compare_url":"https://api.github.com/repos/StackStorm/st2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/StackStorm/st2/merges","archive_url":"https://api.github.com/repos/StackStorm/st2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/StackStorm/st2/downloads","issues_url":"https://api.github.com/repos/StackStorm/st2/issues{/number}","pulls_url":"https://api.github.com/repos/StackStorm/st2/pulls{/number}","milestones_url":"https://api.github.com/repos/StackStorm/st2/milestones{/number}","notifications_url":"https://api.github.com/repos/StackStorm/st2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/StackStorm/st2/labels{/name}","releases_url":"https://api.github.com/repos/StackStorm/st2/releases{/id}","created_at":"2014-04-23T00:51:34Z","updated_at":"2015-11-25T17:46:02Z","pushed_at":"2015-11-26T01:26:42Z","git_url":"git://github.com/StackStorm/st2.git","ssh_url":"git@github.com:StackStorm/st2.git","clone_url":"https://github.com/StackStorm/st2.git","svn_url":"https://github.com/StackStorm/st2","homepage":"http://www.stackstorm.com/","size":14781,"stargazers_count":1069,"watchers_count":1069,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":90,"mirror_url":null,"open_issues_count":82,"forks":90,"open_issues":82,"watchers":1069,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/2236"},"html":{"href":"https://github.com/StackStorm/st2/pull/2236"},"issue":{"href":"https://api.github.com/repos/StackStorm/st2/issues/2236"},"comments":{"href":"https://api.github.com/repos/StackStorm/st2/issues/2236/comments"},"review_comments":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/2236/comments"},"review_comment":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/StackStorm/st2/pulls/2236/commits"},"statuses":{"href":"https://api.github.com/repos/StackStorm/st2/statuses/4ae86f62af11acb6f5d83ff057391d6e8a6f8c14"}}}}