1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | """
|
22 | Usage: neorun.py <cmd=arg>
|
23 | --start=path/to/neo4j/home <cmd> [arg]
|
24 | : start the neo4j server in the folder specified by the path
|
25 | -v version : download the version provided if no neo4j detected
|
26 | -n neo4j-version: download this specific neo4j enterprise nightly version from teamcity with basic access auth
|
27 | -l download-url : download the neo4j provided by this url if no neo4j found
|
28 | -p new-password : change the default password to this new password
|
29 | --stop=path/to/neo4j/home : stop a neo4j server
|
30 | -h : show this help message
|
31 |
|
32 | Example: neorun.py -h
|
33 | neorun.py --start=path/to/neo4j/home -v 3.0.1 -p TOUFU
|
34 | neorun.py --start=path/to/neo4j/home -n 3.0 -p TOUFU
|
35 | neorun.py --start=path/to/neo4j/home -n 3.1
|
36 | neorun.py --stop=path/to/neo4j/home
|
37 | """
|
38 | import getopt
|
39 | from sys import argv, stdout, exit
|
40 | from neoget import neo4j_default_archive, neo4j_archive, download
|
41 | from neoctl import neo4j_start, neo4j_stop, neo4j_update_default_password
|
42 | from os import path, rename, getenv
|
43 | import socket
|
44 | from time import time, sleep, strftime
|
45 |
|
46 | KNOWN_HOST = path.join(path.expanduser("~"), ".neo4j", "known_hosts")
|
47 | NEORUN_START_ARGS_NAME = "NEORUN_START_ARGS"
|
48 |
|
49 | class Enum(set):
|
50 | def __getattr__(self, name):
|
51 | if name in self:
|
52 | return name
|
53 | raise AttributeError
|
54 |
|
55 | ServerStatus = Enum(["STARTED", "STOPPED" ])
|
56 |
|
57 | def main():
|
58 |
|
59 | if len(argv) <= 1:
|
60 | print_help()
|
61 | exit(2)
|
62 | try:
|
63 | opts, args = getopt.getopt(argv[1:], "hv:n:l:p:", ["start=", "stop="])
|
64 | except getopt.GetoptError as err:
|
65 | print(str(err))
|
66 | print_help()
|
67 | exit(2)
|
68 | else:
|
69 | exit_code = 0
|
70 | for opt, arg in opts:
|
71 | if opt == '-h':
|
72 | print_help()
|
73 | exit(2)
|
74 |
|
75 | if opt == "--start":
|
76 | neo4j_home = path.abspath(arg)
|
77 | if neo4j_status() == ServerStatus.STARTED:
|
78 | stdout.write("Failed to start neo4j as a neo4j server is already running on this machine.\n")
|
79 | exit(2)
|
80 |
|
81 |
|
82 | env = getenv(NEORUN_START_ARGS_NAME)
|
83 | if env:
|
84 | stdout.write("WARNING: using env var `NEORUN_START_ARGS=%s`\n" % env)
|
85 | try:
|
86 | start_opts, start_args = getopt.getopt(env.split(), "v:n:l:p:")
|
87 | except getopt.GetoptError as err:
|
88 | print(str(err))
|
89 | print_help()
|
90 | exit(2)
|
91 | else:
|
92 | start_opts = opts
|
93 |
|
94 |
|
95 | archive_url, archive_name, require_basic_auth = neo4j_default_archive()
|
96 | password = ''
|
97 | for start_opt, start_arg in start_opts:
|
98 | if start_opt == "-p":
|
99 | password = start_arg
|
100 | elif start_opt in ['-v', '-n', '-l']:
|
101 | archive_url, archive_name, require_basic_auth = neo4j_archive(start_opt, start_arg)
|
102 |
|
103 | exit_code = handle_start(archive_url, archive_name, neo4j_home, require_basic_auth)
|
104 | if exit_code == 0 and password:
|
105 | exit_code = neo4j_update_default_password("localhost", 7474, new_password=password) or 0
|
106 |
|
107 | elif opt == "--stop":
|
108 | if neo4j_status() == ServerStatus.STOPPED:
|
109 | stdout.write("Failed to stop server as no neo4j server is running on this machine.\n")
|
110 | exit(2)
|
111 | exit_code = neo4j_stop(neo4j_home=arg) or test_neo4j_status(ServerStatus.STOPPED) or 0
|
112 |
|
113 | if exit_code != 0:
|
114 | break
|
115 | exit(exit_code)
|
116 |
|
117 |
|
118 | def handle_start(archive_url, archive_name, neo4j_home, require_basic_auth):
|
119 | if not path.exists(neo4j_home):
|
120 | folder_name=download(archive_url, archive_name, path.dirname(neo4j_home), require_basic_auth)
|
121 | if not path.exists(neo4j_home):
|
122 |
|
123 | rename(path.join(path.dirname(neo4j_home), folder_name), neo4j_home)
|
124 | if path.exists(KNOWN_HOST):
|
125 | known_host_backup_name = KNOWN_HOST + strftime("%Y%m%d-%H%M%S") + ".backup"
|
126 | stdout.write("Found an existing known_host file, renaming it to %s.\n" % (known_host_backup_name))
|
127 | rename(KNOWN_HOST, known_host_backup_name)
|
128 |
|
129 | exit_code = neo4j_start(neo4j_home) or 0
|
130 | if exit_code == 0:
|
131 | exit_code = test_neo4j_status()
|
132 | return exit_code
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | def test_neo4j_status(status = ServerStatus.STARTED):
|
139 | success = False
|
140 | start_time = time()
|
141 | timeout = 60 * 4
|
142 | count = 0
|
143 | while not success:
|
144 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
145 | actual_status = s.connect_ex(("localhost", 7474))
|
146 | if status == ServerStatus.STARTED:
|
147 | success = True if actual_status == 0 else False
|
148 | else:
|
149 | success = True if actual_status != 0 else False
|
150 | s.close()
|
151 |
|
152 | current_time = time()
|
153 | if current_time - start_time > timeout:
|
154 |
|
155 | stdout.write("Failed to start server in 4 mins\n")
|
156 | return 1
|
157 |
|
158 | count += 1
|
159 | if count % 10 == 0:
|
160 | stdout.write(".")
|
161 |
|
162 | sleep(0.1)
|
163 |
|
164 | stdout.write("\n")
|
165 | return 0
|
166 |
|
167 |
|
168 | def neo4j_status():
|
169 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
170 | server_status = ServerStatus.STARTED if s.connect_ex(("localhost", 7474)) == 0 else ServerStatus.STOPPED
|
171 | s.close()
|
172 | return server_status
|
173 |
|
174 |
|
175 | def print_help():
|
176 | print(__doc__)
|
177 |
|
178 |
|
179 | if __name__ == "__main__":
|
180 | main()
|