{"action":"created","comment":{"url":"https://api.github.com/repos/neo4j/neo4j/pulls/comments/81500661","pull_request_review_id":2476035,"id":81500661,"diff_hunk":"@@ -0,0 +1,184 @@\n+/*\n+ * Copyright (c) 2002-2016 \"Neo Technology,\"\n+ * Network Engine for Objects in Lund AB [http://neotechnology.com]\n+ *\n+ * This file is part of Neo4j.\n+ *\n+ * Neo4j is free software: you can redistribute it and/or modify\n+ * it under the terms of the GNU Affero General Public License as\n+ * published by the Free Software Foundation, either version 3 of the\n+ * License, or (at your option) any later version.\n+ *\n+ * This program 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 Affero General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Affero General Public License\n+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\n+ */\n+package org.neo4j.commandline.dbms;\n+\n+import java.io.IOException;\n+import java.nio.file.Files;\n+import java.nio.file.Path;\n+import java.nio.file.Paths;\n+import java.util.Optional;\n+\n+import org.neo4j.commandline.admin.AdminCommand;\n+import org.neo4j.commandline.admin.CommandFailed;\n+import org.neo4j.commandline.admin.IncorrectUsage;\n+import org.neo4j.commandline.admin.OutsideWorld;\n+import org.neo4j.helpers.Args;\n+import org.neo4j.io.fs.DefaultFileSystemAbstraction;\n+import org.neo4j.io.fs.FileSystemAbstraction;\n+import org.neo4j.io.fs.FileUtils;\n+import org.neo4j.kernel.StoreLockException;\n+import org.neo4j.kernel.internal.StoreLocker;\n+\n+import static java.lang.String.format;\n+import static java.nio.file.Files.exists;\n+import static org.neo4j.coreedge.core.EnterpriseCoreEditionModule.CLUSTER_STATE_DIRECTORY_NAME;\n+\n+public class UnbindFromClusterCommand implements AdminCommand\n+{\n+    public static class Provider extends AdminCommand.Provider\n+    {\n+        public Provider()\n+        {\n+            super( \"unbind\" );\n+        }\n+\n+        @Override\n+        public Optional<String> arguments()\n+        {\n+            return Optional.of( \"[--database=<name>] \" );\n+        }\n+\n+        @Override\n+        public String description()\n+        {\n+            return \"Removes cluster state data from the specified database making it suitable for use non-Core-Edge \" +\n+                    \"databases\";\n+        }\n+\n+        @Override\n+        public AdminCommand create( Path homeDir, Path configDir, OutsideWorld outsideWorld )\n+        {\n+            return new UnbindFromClusterCommand( homeDir, new DefaultFileSystemAbstraction() );\n+        }\n+    }\n+\n+    private Path homeDir;\n+    private FileSystemAbstraction fsa;\n+\n+    UnbindFromClusterCommand( Path homeDir, FileSystemAbstraction fsa )\n+    {\n+        this.homeDir = homeDir;\n+        this.fsa = fsa;\n+    }\n+\n+    @Override\n+    public void execute( String[] args ) throws IncorrectUsage, CommandFailed\n+    {\n+        Args parsedArgs = Args.parse( args );\n+\n+        try\n+        {\n+            Path pathToSpecificDatabase =\n+                    homeDir.resolve( \"data\" ).resolve( \"databases\" ).resolve( databaseNameFrom( parsedArgs ) );\n+            confirmTargetDatabaseDirectoryExists( pathToSpecificDatabase );\n+            confirmClusterStateDirectoryExists( Paths.get( pathToSpecificDatabase.toString(), \"cluster-state\" ) );\n+            confirmTargetDirectoryIsWritable( pathToSpecificDatabase );\n+            deleteClusterStateIn( clusterStateFrom( pathToSpecificDatabase ) );\n+        }\n+        catch ( IllegalArgumentException e )\n+        {\n+            throw new IncorrectUsage( e.getMessage() );\n+        }\n+        catch ( UnbindFailureException e )\n+        {\n+            throw new CommandFailed( \"Unbind failed: \" + e.getMessage(), e );\n+        }\n+    }\n+\n+    private Path clusterStateFrom( Path target )\n+    {\n+        return Paths.get( target.toString(), CLUSTER_STATE_DIRECTORY_NAME );\n+    }\n+\n+    private void confirmTargetDirectoryIsWritable( Path dbDir ) throws CommandFailed\n+    {\n+        Path lockFile = dbDir.resolve( StoreLocker.STORE_LOCK_FILENAME );\n+        if ( exists( lockFile ) )\n+        {\n+            if ( Files.isWritable( lockFile ) )","path":"enterprise/core-edge/src/main/java/org/neo4j/commandline/dbms/UnbindFromClusterCommand.java","position":115,"original_position":115,"commit_id":"1c59e788810abd40775d7f9c6f01275151ed61ec","original_commit_id":"1c59e788810abd40775d7f9c6f01275151ed61ec","user":{"login":"benbc","id":128750,"avatar_url":"https://avatars.githubusercontent.com/u/128750?v=3","gravatar_id":"","url":"https://api.github.com/users/benbc","html_url":"https://github.com/benbc","followers_url":"https://api.github.com/users/benbc/followers","following_url":"https://api.github.com/users/benbc/following{/other_user}","gists_url":"https://api.github.com/users/benbc/gists{/gist_id}","starred_url":"https://api.github.com/users/benbc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benbc/subscriptions","organizations_url":"https://api.github.com/users/benbc/orgs","repos_url":"https://api.github.com/users/benbc/repos","events_url":"https://api.github.com/users/benbc/events{/privacy}","received_events_url":"https://api.github.com/users/benbc/received_events","type":"User","site_admin":false},"body":"You fail silently if the lockfile is unwritable (i.e. if the current user doesn't have the correct permissions to operate on the database). Presumably that's not what you want for this command. This case will happen, for example, with the Debian package if the operator forgets to `sudo -u neo4j`.","created_at":"2016-10-03T07:23:17Z","updated_at":"2016-10-03T07:28:16Z","html_url":"https://github.com/neo4j/neo4j/pull/8066#discussion_r81500661","pull_request_url":"https://api.github.com/repos/neo4j/neo4j/pulls/8066","_links":{"self":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/comments/81500661"},"html":{"href":"https://github.com/neo4j/neo4j/pull/8066#discussion_r81500661"},"pull_request":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/8066"}}},"pull_request":{"url":"https://api.github.com/repos/neo4j/neo4j/pulls/8066","id":87552974,"html_url":"https://github.com/neo4j/neo4j/pull/8066","diff_url":"https://github.com/neo4j/neo4j/pull/8066.diff","patch_url":"https://github.com/neo4j/neo4j/pull/8066.patch","issue_url":"https://api.github.com/repos/neo4j/neo4j/issues/8066","number":8066,"state":"open","locked":false,"title":"Unbind an instance from the cluster.","user":{"login":"jimwebber","id":170553,"avatar_url":"https://avatars.githubusercontent.com/u/170553?v=3","gravatar_id":"","url":"https://api.github.com/users/jimwebber","html_url":"https://github.com/jimwebber","followers_url":"https://api.github.com/users/jimwebber/followers","following_url":"https://api.github.com/users/jimwebber/following{/other_user}","gists_url":"https://api.github.com/users/jimwebber/gists{/gist_id}","starred_url":"https://api.github.com/users/jimwebber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimwebber/subscriptions","organizations_url":"https://api.github.com/users/jimwebber/orgs","repos_url":"https://api.github.com/users/jimwebber/repos","events_url":"https://api.github.com/users/jimwebber/events{/privacy}","received_events_url":"https://api.github.com/users/jimwebber/received_events","type":"User","site_admin":false},"body":"Current implementation merely checks that the database exists,\r\nand that it isn't locked by an active Neo4j instance.\r\n\r\nIf all is good then it deletes the cluster-state directory reverting the\r\nstore to a Neo4j standalone/ha format (which can be used to\r\nseed another core-edge cluster).","created_at":"2016-09-30T19:32:58Z","updated_at":"2016-10-03T07:28:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"99ba6f384cfa8e5c25b592e2b3a2e1b53e31c0ba","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/neo4j/neo4j/pulls/8066/commits","review_comments_url":"https://api.github.com/repos/neo4j/neo4j/pulls/8066/comments","review_comment_url":"https://api.github.com/repos/neo4j/neo4j/pulls/comments{/number}","comments_url":"https://api.github.com/repos/neo4j/neo4j/issues/8066/comments","statuses_url":"https://api.github.com/repos/neo4j/neo4j/statuses/1c59e788810abd40775d7f9c6f01275151ed61ec","head":{"label":"jimwebber:3.1-cluster-admin-unbind","ref":"3.1-cluster-admin-unbind","sha":"1c59e788810abd40775d7f9c6f01275151ed61ec","user":{"login":"jimwebber","id":170553,"avatar_url":"https://avatars.githubusercontent.com/u/170553?v=3","gravatar_id":"","url":"https://api.github.com/users/jimwebber","html_url":"https://github.com/jimwebber","followers_url":"https://api.github.com/users/jimwebber/followers","following_url":"https://api.github.com/users/jimwebber/following{/other_user}","gists_url":"https://api.github.com/users/jimwebber/gists{/gist_id}","starred_url":"https://api.github.com/users/jimwebber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimwebber/subscriptions","organizations_url":"https://api.github.com/users/jimwebber/orgs","repos_url":"https://api.github.com/users/jimwebber/repos","events_url":"https://api.github.com/users/jimwebber/events{/privacy}","received_events_url":"https://api.github.com/users/jimwebber/received_events","type":"User","site_admin":false},"repo":{"id":47407168,"name":"neo4j","full_name":"jimwebber/neo4j","owner":{"login":"jimwebber","id":170553,"avatar_url":"https://avatars.githubusercontent.com/u/170553?v=3","gravatar_id":"","url":"https://api.github.com/users/jimwebber","html_url":"https://github.com/jimwebber","followers_url":"https://api.github.com/users/jimwebber/followers","following_url":"https://api.github.com/users/jimwebber/following{/other_user}","gists_url":"https://api.github.com/users/jimwebber/gists{/gist_id}","starred_url":"https://api.github.com/users/jimwebber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimwebber/subscriptions","organizations_url":"https://api.github.com/users/jimwebber/orgs","repos_url":"https://api.github.com/users/jimwebber/repos","events_url":"https://api.github.com/users/jimwebber/events{/privacy}","received_events_url":"https://api.github.com/users/jimwebber/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jimwebber/neo4j","description":"Graphs for Everyone","fork":true,"url":"https://api.github.com/repos/jimwebber/neo4j","forks_url":"https://api.github.com/repos/jimwebber/neo4j/forks","keys_url":"https://api.github.com/repos/jimwebber/neo4j/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jimwebber/neo4j/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jimwebber/neo4j/teams","hooks_url":"https://api.github.com/repos/jimwebber/neo4j/hooks","issue_events_url":"https://api.github.com/repos/jimwebber/neo4j/issues/events{/number}","events_url":"https://api.github.com/repos/jimwebber/neo4j/events","assignees_url":"https://api.github.com/repos/jimwebber/neo4j/assignees{/user}","branches_url":"https://api.github.com/repos/jimwebber/neo4j/branches{/branch}","tags_url":"https://api.github.com/repos/jimwebber/neo4j/tags","blobs_url":"https://api.github.com/repos/jimwebber/neo4j/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jimwebber/neo4j/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jimwebber/neo4j/git/refs{/sha}","trees_url":"https://api.github.com/repos/jimwebber/neo4j/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jimwebber/neo4j/statuses/{sha}","languages_url":"https://api.github.com/repos/jimwebber/neo4j/languages","stargazers_url":"https://api.github.com/repos/jimwebber/neo4j/stargazers","contributors_url":"https://api.github.com/repos/jimwebber/neo4j/contributors","subscribers_url":"https://api.github.com/repos/jimwebber/neo4j/subscribers","subscription_url":"https://api.github.com/repos/jimwebber/neo4j/subscription","commits_url":"https://api.github.com/repos/jimwebber/neo4j/commits{/sha}","git_commits_url":"https://api.github.com/repos/jimwebber/neo4j/git/commits{/sha}","comments_url":"https://api.github.com/repos/jimwebber/neo4j/comments{/number}","issue_comment_url":"https://api.github.com/repos/jimwebber/neo4j/issues/comments{/number}","contents_url":"https://api.github.com/repos/jimwebber/neo4j/contents/{+path}","compare_url":"https://api.github.com/repos/jimwebber/neo4j/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jimwebber/neo4j/merges","archive_url":"https://api.github.com/repos/jimwebber/neo4j/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jimwebber/neo4j/downloads","issues_url":"https://api.github.com/repos/jimwebber/neo4j/issues{/number}","pulls_url":"https://api.github.com/repos/jimwebber/neo4j/pulls{/number}","milestones_url":"https://api.github.com/repos/jimwebber/neo4j/milestones{/number}","notifications_url":"https://api.github.com/repos/jimwebber/neo4j/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jimwebber/neo4j/labels{/name}","releases_url":"https://api.github.com/repos/jimwebber/neo4j/releases{/id}","deployments_url":"https://api.github.com/repos/jimwebber/neo4j/deployments","created_at":"2015-12-04T13:59:24Z","updated_at":"2016-01-13T11:05:02Z","pushed_at":"2016-09-30T19:32:26Z","git_url":"git://github.com/jimwebber/neo4j.git","ssh_url":"git@github.com:jimwebber/neo4j.git","clone_url":"https://github.com/jimwebber/neo4j.git","svn_url":"https://github.com/jimwebber/neo4j","homepage":"http://neo4j.com","size":357520,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"3.0"}},"base":{"label":"neo4j:3.1","ref":"3.1","sha":"7b890cea4f0be50e697d6ba272edb6b74b84e373","user":{"login":"neo4j","id":201120,"avatar_url":"https://avatars.githubusercontent.com/u/201120?v=3","gravatar_id":"","url":"https://api.github.com/users/neo4j","html_url":"https://github.com/neo4j","followers_url":"https://api.github.com/users/neo4j/followers","following_url":"https://api.github.com/users/neo4j/following{/other_user}","gists_url":"https://api.github.com/users/neo4j/gists{/gist_id}","starred_url":"https://api.github.com/users/neo4j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/neo4j/subscriptions","organizations_url":"https://api.github.com/users/neo4j/orgs","repos_url":"https://api.github.com/users/neo4j/repos","events_url":"https://api.github.com/users/neo4j/events{/privacy}","received_events_url":"https://api.github.com/users/neo4j/received_events","type":"Organization","site_admin":false},"repo":{"id":6650539,"name":"neo4j","full_name":"neo4j/neo4j","owner":{"login":"neo4j","id":201120,"avatar_url":"https://avatars.githubusercontent.com/u/201120?v=3","gravatar_id":"","url":"https://api.github.com/users/neo4j","html_url":"https://github.com/neo4j","followers_url":"https://api.github.com/users/neo4j/followers","following_url":"https://api.github.com/users/neo4j/following{/other_user}","gists_url":"https://api.github.com/users/neo4j/gists{/gist_id}","starred_url":"https://api.github.com/users/neo4j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/neo4j/subscriptions","organizations_url":"https://api.github.com/users/neo4j/orgs","repos_url":"https://api.github.com/users/neo4j/repos","events_url":"https://api.github.com/users/neo4j/events{/privacy}","received_events_url":"https://api.github.com/users/neo4j/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/neo4j/neo4j","description":"Graphs for Everyone","fork":false,"url":"https://api.github.com/repos/neo4j/neo4j","forks_url":"https://api.github.com/repos/neo4j/neo4j/forks","keys_url":"https://api.github.com/repos/neo4j/neo4j/keys{/key_id}","collaborators_url":"https://api.github.com/repos/neo4j/neo4j/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/neo4j/neo4j/teams","hooks_url":"https://api.github.com/repos/neo4j/neo4j/hooks","issue_events_url":"https://api.github.com/repos/neo4j/neo4j/issues/events{/number}","events_url":"https://api.github.com/repos/neo4j/neo4j/events","assignees_url":"https://api.github.com/repos/neo4j/neo4j/assignees{/user}","branches_url":"https://api.github.com/repos/neo4j/neo4j/branches{/branch}","tags_url":"https://api.github.com/repos/neo4j/neo4j/tags","blobs_url":"https://api.github.com/repos/neo4j/neo4j/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/neo4j/neo4j/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/neo4j/neo4j/git/refs{/sha}","trees_url":"https://api.github.com/repos/neo4j/neo4j/git/trees{/sha}","statuses_url":"https://api.github.com/repos/neo4j/neo4j/statuses/{sha}","languages_url":"https://api.github.com/repos/neo4j/neo4j/languages","stargazers_url":"https://api.github.com/repos/neo4j/neo4j/stargazers","contributors_url":"https://api.github.com/repos/neo4j/neo4j/contributors","subscribers_url":"https://api.github.com/repos/neo4j/neo4j/subscribers","subscription_url":"https://api.github.com/repos/neo4j/neo4j/subscription","commits_url":"https://api.github.com/repos/neo4j/neo4j/commits{/sha}","git_commits_url":"https://api.github.com/repos/neo4j/neo4j/git/commits{/sha}","comments_url":"https://api.github.com/repos/neo4j/neo4j/comments{/number}","issue_comment_url":"https://api.github.com/repos/neo4j/neo4j/issues/comments{/number}","contents_url":"https://api.github.com/repos/neo4j/neo4j/contents/{+path}","compare_url":"https://api.github.com/repos/neo4j/neo4j/compare/{base}...{head}","merges_url":"https://api.github.com/repos/neo4j/neo4j/merges","archive_url":"https://api.github.com/repos/neo4j/neo4j/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/neo4j/neo4j/downloads","issues_url":"https://api.github.com/repos/neo4j/neo4j/issues{/number}","pulls_url":"https://api.github.com/repos/neo4j/neo4j/pulls{/number}","milestones_url":"https://api.github.com/repos/neo4j/neo4j/milestones{/number}","notifications_url":"https://api.github.com/repos/neo4j/neo4j/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/neo4j/neo4j/labels{/name}","releases_url":"https://api.github.com/repos/neo4j/neo4j/releases{/id}","deployments_url":"https://api.github.com/repos/neo4j/neo4j/deployments","created_at":"2012-11-12T08:46:15Z","updated_at":"2016-10-03T02:43:39Z","pushed_at":"2016-10-03T07:24:35Z","git_url":"git://github.com/neo4j/neo4j.git","ssh_url":"git@github.com:neo4j/neo4j.git","clone_url":"https://github.com/neo4j/neo4j.git","svn_url":"https://github.com/neo4j/neo4j","homepage":"http://neo4j.com","size":376934,"stargazers_count":3049,"watchers_count":3049,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1002,"mirror_url":null,"open_issues_count":407,"forks":1002,"open_issues":407,"watchers":3049,"default_branch":"3.1"}},"_links":{"self":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/8066"},"html":{"href":"https://github.com/neo4j/neo4j/pull/8066"},"issue":{"href":"https://api.github.com/repos/neo4j/neo4j/issues/8066"},"comments":{"href":"https://api.github.com/repos/neo4j/neo4j/issues/8066/comments"},"review_comments":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/8066/comments"},"review_comment":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/neo4j/neo4j/pulls/8066/commits"},"statuses":{"href":"https://api.github.com/repos/neo4j/neo4j/statuses/1c59e788810abd40775d7f9c6f01275151ed61ec"}}}}
{"actor":{"display_login":"benbc"}}