Browse Source

Merge branch 'mysql'

master
dave 1 year ago
parent
commit
a8787d0ff2
7 changed files with 56 additions and 21 deletions
  1. +1
    -3
      Dockerfile
  2. +21
    -0
      nodepupper/cli.py
  3. +10
    -4
      nodepupper/daemon.py
  4. +10
    -3
      nodepupper/nodeops.py
  5. +11
    -2
      requirements.txt
  6. +2
    -2
      setup.py
  7. +1
    -7
      start

+ 1
- 3
Dockerfile View File

@@ -20,7 +20,7 @@ ADD . /tmp/code/
COPY --from=0 /tmp/code/styles/dist/style.css /tmp/code/styles/dist/style.css

RUN apt-get update && \
apt-get install -y python3-pip sudo
apt-get install -y python3-pip sudo git

RUN pip3 install -U pip && \
cd /tmp/code && \
@@ -28,8 +28,6 @@ RUN pip3 install -U pip && \
python3 setup.py install && \
useradd --uid 1000 app

VOLUME /data/

ADD start /start

ENTRYPOINT ["/start"]

+ 21
- 0
nodepupper/cli.py View File

@@ -8,6 +8,9 @@ import tempfile
import subprocess


import sys


APPNAME = "npcli"
CONFDIR = user_config_dir(APPNAME)
CONFPATH = os.path.join(CONFDIR, "conf.json")
@@ -74,6 +77,9 @@ def main():

spr_dump = spr_action.add_parser("dump", help="dump the database")

spr_import = spr_action.add_parser("import", help="import a database dump")
spr_import.add_argument("fname", help="db dump yaml file to import")

args = parser.parse_args()
r = requests.session()

@@ -131,6 +137,21 @@ def main():

print(yaml.dump(dump, default_flow_style=False))

elif args.action == "import":
with open(args.fname) as f:
dump = yaml.load(f)

for clsname in dump["classes"]:
r.put(args.host.rstrip("/") + "/api/class/" + clsname).raise_for_status()

# just make the nodes first
for nodename, nodebody in dump["nodes"].items():
putnode(nodename, yaml.dump({"body": {}, "classes": {}, "parents": []})).raise_for_status()

# then fill out node bodies to avoid missing parent ordering issues
for nodename, nodebody in dump["nodes"].items():
putnode(nodename, yaml.dump(nodebody)).raise_for_status()


if __name__ == "__main__":
main()

+ 10
- 4
nodepupper/daemon.py View File

@@ -3,10 +3,10 @@ import cherrypy
import logging
from nodepupper.nodeops import NodeOps, NObject, NClass, NClassAttachment
from jinja2 import Environment, FileSystemLoader, select_autoescape
from nodepupper.common import pwhash
import math
from urllib.parse import urlparse
import math
import yaml
import sys


APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
@@ -206,7 +206,8 @@ class ClassesApi(object):

def PUT(self, cls):
with self.nodes.db.transaction() as c:
c.root.classes[cls] = NClass(cls)
if cls not in c.root.classes:
c.root.classes[cls] = NClass(cls)

def DELETE(self, cls):
with self.nodes.db.transaction() as c:
@@ -278,7 +279,8 @@ def main():
parser.add_argument('-p', '--port', default=8080, type=int, help="tcp port to listen on")
# parser.add_argument('-l', '--library', default="./library", help="library path")
# parser.add_argument('-c', '--cache', default="./cache", help="cache path")
parser.add_argument('-s', '--database', default="./pupper.db", help="path to persistent sqlite database")
parser.add_argument('-s', '--database', default=os.environ.get('DATABASE_URI', None),
help="mysql:// connection uri")
parser.add_argument('--debug', action="store_true", help="enable development options")

args = parser.parse_args()
@@ -286,6 +288,10 @@ def main():
logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING,
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")

if not args.database:
print("--database or $DATABASE_URI is required")
sys.exit(2)

library = NodeOps(args.database)

tpl_dir = os.path.join(APPROOT, "templates") if not args.debug else "templates"


+ 10
- 3
nodepupper/nodeops.py View File

@@ -1,5 +1,8 @@
from urllib.parse import urlparse
import ZODB
import ZODB.FileStorage
from relstorage.storage import RelStorage
from relstorage.options import Options
from relstorage.adapters.mysql import MySQLAdapter
import persistent
import persistent.list
import persistent.mapping
@@ -40,8 +43,12 @@ class NClassAttachment(persistent.Persistent):


class NodeOps(object):
def __init__(self, db_path):
self.storage = ZODB.FileStorage.FileStorage(db_path)
def __init__(self, db_uri):
uri = urlparse(db_uri)

self.mysql = MySQLAdapter(host=uri.hostname, user=uri.username, passwd=uri.password, db=uri.path[1:],
options=Options(keep_history=False))
self.storage = RelStorage(adapter=self.mysql)
self.db = ZODB.DB(self.storage)

with self.db.transaction() as c:


+ 11
- 2
requirements.txt View File

@@ -1,26 +1,35 @@
appdirs==1.4.3
asn1crypto==0.24.0
backports.functools-lru-cache==1.5
BTrees==4.5.1
certifi==2018.11.29
cffi==1.12.2
chardet==3.0.4
cheroot==6.5.2
CherryPy==18.0.1
cryptography==2.6.1
idna==2.8
jaraco.functools==1.20
Jinja2==2.10
MarkupSafe==1.0
more-itertools==4.3.0
perfmetrics==2.0
persistent==4.4.2
portend==2.3
pycparser==2.19
PyMySQL==0.9.3
pytz==2018.5
PyYAML==3.13
-e git+https://git.davepedu.com/dave/relstorage.git@5ae138b71a0eeb740208e61cfd1662c49738ee45#egg=RelStorage
requests==2.21.0
six==1.11.0
tempora==1.13
transaction==2.2.1
transaction==2.4.0
urllib3==1.24.1
zc.lockfile==1.3.0
ZConfig==3.3.0
ZODB==5.4.0
zdaemon==4.3
ZEO==5.2.1
ZODB==5.5.1
zodbpickle==1.0.2
zope.interface==4.5.0

+ 2
- 2
setup.py View File

@@ -4,9 +4,9 @@ from setuptools import setup
import os


__version__ = "0.0.1"
__version__ = "0.0.2"
with open(os.path.join(os.path.dirname(__file__), "requirements.txt")) as f:
__requirements__ = [line.strip() for line in f.readlines()]
__requirements__ = [line.strip() for line in f.readlines() if not line.startswith("-")]


setup(name='nodepupper',


+ 1
- 7
start View File

@@ -1,9 +1,3 @@
#!/bin/sh


mkdir /data/db

chown -R app:app /data/db


exec sudo -Hu app nodepupperd --database /data/db/pup.db $@
exec sudo --preserve-env -Hu app nodepupperd $@

Loading…
Cancel
Save