cubething_psync 0.1.0.dev5__tar.gz → 0.1.0.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/PKG-INFO +2 -1
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/README.md +1 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/pyproject.toml +1 -1
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/client/args.py +18 -6
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/client/main.py +23 -12
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/PKG-INFO +2 -1
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/server/main.py +8 -9
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/LICENSE +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/setup.cfg +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/client/__init__.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/client/__main__.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/common/__init__.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/common/data.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/common/log.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/SOURCES.txt +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/dependency_links.txt +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/entry_points.txt +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/requires.txt +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/top_level.txt +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/server/__init__.py +0 -0
- {cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/server/__main__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cubething_psync
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev7
|
|
4
4
|
Summary: Simple project synchronization tool.
|
|
5
5
|
Author-email: ada mandala <ada@cubething.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Dynamic: license-file
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
[](https://psync.readthedocs.io/en/latest)
|
|
23
|
+
[](https://pypi.org/project/cubething_psync)
|
|
23
24
|
|
|
24
25
|
**psync** is a simple tool to sync your project over SSH. It consists of a
|
|
25
26
|
client and server.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
</div>
|
|
4
4
|
|
|
5
5
|
[](https://psync.readthedocs.io/en/latest)
|
|
6
|
+
[](https://pypi.org/project/cubething_psync)
|
|
6
7
|
|
|
7
8
|
**psync** is a simple tool to sync your project over SSH. It consists of a
|
|
8
9
|
client and server.
|
|
@@ -10,14 +10,28 @@ from common.data import deserialize_env
|
|
|
10
10
|
@dataclass
|
|
11
11
|
class Args:
|
|
12
12
|
target_path: str
|
|
13
|
-
dest_path: str
|
|
14
13
|
extra: list[str]
|
|
15
14
|
env: dict[str, str]
|
|
16
15
|
args: list[str]
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
parser = argparse.ArgumentParser(
|
|
20
|
-
prog="psync-client",
|
|
19
|
+
prog="psync-client",
|
|
20
|
+
usage="""\
|
|
21
|
+
Client for the psync server.
|
|
22
|
+
|
|
23
|
+
In addition to the options below, the client is configurable through environment
|
|
24
|
+
variables.
|
|
25
|
+
|
|
26
|
+
Variable | Default
|
|
27
|
+
------------------+-------------------------------
|
|
28
|
+
PSYNC_SERVER_IP | 127.0.0.1
|
|
29
|
+
PSYNC_SERVER_PORT | 5000
|
|
30
|
+
PSYNC_SSH_PORT | 5022
|
|
31
|
+
PSYNC_SERVER_DEST | /app/rsync/
|
|
32
|
+
PSYNC_SSH_USER | <unset>
|
|
33
|
+
PSYNC_CERT_PATH | ~/.local/share/psync/cert.pem
|
|
34
|
+
""",
|
|
21
35
|
)
|
|
22
36
|
_action = parser.add_argument(
|
|
23
37
|
"--path",
|
|
@@ -42,6 +56,8 @@ _action = parser.add_argument(
|
|
|
42
56
|
|
|
43
57
|
SERVER_IP: str = os.environ.get("PSYNC_SERVER_IP", "127.0.0.1")
|
|
44
58
|
SERVER_PORT: int = int(os.environ.get("PSYNC_SERVER_PORT", "5000"))
|
|
59
|
+
SERVER_SSH_PORT: int = int(os.environ.get("PSYNC_SSH_PORT", "5022"))
|
|
60
|
+
SERVER_DEST: str = os.environ.get("PSYNC_SERVER_DEST", "/app/rsync")
|
|
45
61
|
USER: str = os.environ.get("PSYNC_SSH_USER", "")
|
|
46
62
|
SSL_CERT_PATH: str = os.environ.get("PSYNC_CERT_PATH", "~/.local/share/psync/cert.pem")
|
|
47
63
|
|
|
@@ -55,9 +71,6 @@ def parse_args() -> Args:
|
|
|
55
71
|
logging.error(f"Could not file at {target_path}")
|
|
56
72
|
exit(1)
|
|
57
73
|
|
|
58
|
-
val_hash = hash(os.getcwd())
|
|
59
|
-
dest_path = f"~/.local/share/psync/{val_hash}/"
|
|
60
|
-
|
|
61
74
|
extra: list[str] = []
|
|
62
75
|
extra_raw = args.get("extra")
|
|
63
76
|
if extra_raw is not None:
|
|
@@ -75,7 +88,6 @@ def parse_args() -> Args:
|
|
|
75
88
|
|
|
76
89
|
return Args(
|
|
77
90
|
target_path=str(target_path),
|
|
78
|
-
dest_path=dest_path,
|
|
79
91
|
extra=extra or [],
|
|
80
92
|
env=env,
|
|
81
93
|
args=client_args,
|
|
@@ -3,6 +3,7 @@ psync client
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import hashlib
|
|
6
7
|
import os
|
|
7
8
|
import pathlib
|
|
8
9
|
import signal
|
|
@@ -21,7 +22,16 @@ from common.data import (
|
|
|
21
22
|
)
|
|
22
23
|
import logging
|
|
23
24
|
from common.log import InterceptHandler
|
|
24
|
-
from client.args import
|
|
25
|
+
from client.args import (
|
|
26
|
+
SERVER_IP,
|
|
27
|
+
SERVER_PORT,
|
|
28
|
+
SERVER_SSH_PORT,
|
|
29
|
+
USER,
|
|
30
|
+
SSL_CERT_PATH,
|
|
31
|
+
SERVER_DEST,
|
|
32
|
+
Args,
|
|
33
|
+
parse_args,
|
|
34
|
+
)
|
|
25
35
|
|
|
26
36
|
|
|
27
37
|
class PsyncClient:
|
|
@@ -49,7 +59,9 @@ class PsyncClient:
|
|
|
49
59
|
Default: 127.0.0.1
|
|
50
60
|
PSYNC_SERVER_PORT: The port of the server instance.
|
|
51
61
|
Default: 5000
|
|
52
|
-
|
|
62
|
+
PSYNC_SSH_PORT: The server instance's SSH port.
|
|
63
|
+
Default: 5001
|
|
64
|
+
PSYNC_SSH_USER: The server instance's SSH user.
|
|
53
65
|
Default: Unset. Will use the default ssh user.
|
|
54
66
|
PSYNC_CERT_PATH: Path to the SSL certificate. Used to trust self-signed certs. Should
|
|
55
67
|
match the server's certificate.
|
|
@@ -87,7 +99,6 @@ class PsyncClient:
|
|
|
87
99
|
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
|
88
100
|
ssl_ctx.load_verify_locations(pathlib.Path(SSL_CERT_PATH).expanduser())
|
|
89
101
|
ssl_ctx.check_hostname = False # not ideal
|
|
90
|
-
print(ssl_ctx.get_ca_certs())
|
|
91
102
|
async with websockets.connect(
|
|
92
103
|
f"wss://{SERVER_IP}:{SERVER_PORT}", ssl=ssl_ctx
|
|
93
104
|
) as ws:
|
|
@@ -129,13 +140,10 @@ class PsyncClient:
|
|
|
129
140
|
logging.warning(f"Got unknown request {resp}")
|
|
130
141
|
|
|
131
142
|
|
|
132
|
-
def __rsync(args: Args):
|
|
143
|
+
def __rsync(project_hash: str, args: Args):
|
|
133
144
|
"""Runs rsync."""
|
|
134
|
-
if USER != ""
|
|
135
|
-
|
|
136
|
-
else:
|
|
137
|
-
user = ""
|
|
138
|
-
url = f"{user}{SERVER_IP}:{args.dest_path}"
|
|
145
|
+
user = f"{USER}@" if USER != "" else ""
|
|
146
|
+
url = f"ssh://{user}{SERVER_IP}:{SERVER_SSH_PORT}/{SERVER_DEST}/{project_hash}/"
|
|
139
147
|
rsync_args = [
|
|
140
148
|
"rsync",
|
|
141
149
|
"-avzr",
|
|
@@ -160,11 +168,14 @@ def main():
|
|
|
160
168
|
log_level = os.environ.get("PSYNC_LOG", "INFO").upper()
|
|
161
169
|
logging.basicConfig(handlers=[InterceptHandler()], level=log_level, force=True)
|
|
162
170
|
|
|
171
|
+
project_hash = hashlib.blake2s(os.getcwd().encode(), digest_size=8).hexdigest()
|
|
163
172
|
args = parse_args()
|
|
164
|
-
__rsync(args)
|
|
173
|
+
__rsync(project_hash, args)
|
|
165
174
|
|
|
166
|
-
|
|
167
|
-
|
|
175
|
+
dest_path = pathlib.Path(
|
|
176
|
+
f"{SERVER_DEST}/{project_hash}/{os.path.basename(args.target_path)}"
|
|
177
|
+
)
|
|
178
|
+
client = PsyncClient(args=args.args, env=args.env, path=dest_path)
|
|
168
179
|
asyncio.run(client.run())
|
|
169
180
|
|
|
170
181
|
|
{cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cubething_psync
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev7
|
|
4
4
|
Summary: Simple project synchronization tool.
|
|
5
5
|
Author-email: ada mandala <ada@cubething.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Dynamic: license-file
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
[](https://psync.readthedocs.io/en/latest)
|
|
23
|
+
[](https://pypi.org/project/cubething_psync)
|
|
23
24
|
|
|
24
25
|
**psync** is a simple tool to sync your project over SSH. It consists of a
|
|
25
26
|
client and server.
|
|
@@ -34,12 +34,6 @@ import logging
|
|
|
34
34
|
from common.log import InterceptHandler
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def __get_host(ws: ServerConnection) -> str:
|
|
38
|
-
addrs: tuple[str, str] = ws.remote_address # pyright: ignore[reportAny]
|
|
39
|
-
(host, _port) = addrs
|
|
40
|
-
return host
|
|
41
|
-
|
|
42
|
-
|
|
43
37
|
SSL_CERT_PATH: str = environ.get("SSL_CERT_PATH", "./cert.pem")
|
|
44
38
|
SSL_KEY_PATH: str = environ.get("SSL_KEY_PATH", "./key.pem")
|
|
45
39
|
PSYNC_HOST: str = environ.get("PSYNC_SERVER_IP", "0.0.0.0")
|
|
@@ -88,6 +82,11 @@ class PsyncServer:
|
|
|
88
82
|
__coroutine: Task[None] | None = None
|
|
89
83
|
"""The main coroutine for this server."""
|
|
90
84
|
|
|
85
|
+
def __get_host(self, ws: ServerConnection) -> str:
|
|
86
|
+
addrs: tuple[str, str] = ws.remote_address # pyright: ignore[reportAny]
|
|
87
|
+
(host, _port) = addrs
|
|
88
|
+
return host
|
|
89
|
+
|
|
91
90
|
async def serve(self) -> None:
|
|
92
91
|
"""
|
|
93
92
|
The main interface for the server. Will serve forever, or until exited with SIGINT/Ctrl-C.
|
|
@@ -124,7 +123,7 @@ class PsyncServer:
|
|
|
124
123
|
return inner
|
|
125
124
|
|
|
126
125
|
async def __end_session(self, ws: ServerConnection):
|
|
127
|
-
host = __get_host(ws)
|
|
126
|
+
host = self.__get_host(ws)
|
|
128
127
|
try:
|
|
129
128
|
_ = self.__sessions.pop(host)
|
|
130
129
|
except Exception:
|
|
@@ -179,7 +178,7 @@ class PsyncServer:
|
|
|
179
178
|
return inner
|
|
180
179
|
|
|
181
180
|
async def __open(self, req: OpenReq, ws: ServerConnection):
|
|
182
|
-
host = __get_host(ws)
|
|
181
|
+
host = self.__get_host(ws)
|
|
183
182
|
if self.__sessions.get(host) is not None:
|
|
184
183
|
self.__sessions[host]
|
|
185
184
|
resp = ErrorResp(msg="Process already open for this client.")
|
|
@@ -228,7 +227,7 @@ class PsyncServer:
|
|
|
228
227
|
pass
|
|
229
228
|
|
|
230
229
|
async def __kill(self, _req: KillReq, ws: ServerConnection):
|
|
231
|
-
host = __get_host(ws)
|
|
230
|
+
host = self.__get_host(ws)
|
|
232
231
|
p = self.__sessions.get(host)
|
|
233
232
|
task = self.__tasks.get(host)
|
|
234
233
|
if p is not None and task is not None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/requires.txt
RENAMED
|
File without changes
|
{cubething_psync-0.1.0.dev5 → cubething_psync-0.1.0.dev7}/src/cubething_psync.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|