def on_load(app): if app.id != "syncthing": return if not users.get_system("syncthing"): u = users.SystemUser('syncthing') u.add() u = users.get_system('syncthing') if not os.path.exists("/home/syncthing"): os.makedirs("/home/syncthing") os.chown("/home/syncthing", u.uid, 100) s = services.get("syncthing@syncthing") if not s.state == "running": s.start() count = 0 while count < 5: if not os.path.exists("/home/syncthing/.config/syncthing/config.xml"): time.sleep(5) count += 1 else: break if not os.path.exists("/home/syncthing/.config/syncthing/config.xml"): raise Exception("Syncthing taking too long to generate config, try again later") global api_key api_key = get_api_key() global my_id my_id = get_myid()
def create_acme_dummy(domain): """ Create a dummy directory to use for serving ACME challenge data. This function is used when no website yet exists for the desired domain. :param str domain: Domain name to use :returns: Path to directory for challenge data """ site_dir = os.path.join(config.get("websites", "site_dir"), "acme-" + domain) challenge_dir = os.path.join(site_dir, ".well-known/acme-challenge") conf = nginx.Conf( nginx.Server( nginx.Key("listen", "80"), nginx.Key("listen", "[::]:80"), nginx.Key("server_name", domain), nginx.Key("root", site_dir), nginx.Location("/.well-known/acme-challenge/", nginx.Key("root", site_dir)))) origin = os.path.join("/etc/nginx/sites-available", "acme-" + domain) target = os.path.join("/etc/nginx/sites-enabled", "acme-" + domain) uid = users.get_system("http").uid nginx.dumpf(conf, origin) if not os.path.exists(target): os.symlink(origin, target) if not os.path.exists(challenge_dir): os.makedirs(challenge_dir) os.chown(site_dir, uid, -1) os.chown(os.path.join(site_dir, ".well-known"), uid, -1) os.chown(challenge_dir, uid, -1) tracked_services.register("acme", domain, domain + "(ACME Validation)", "globe", [('tcp', 80)], 2) nginx_reload() return challenge_dir
def post_restore(self, site, dbpasswd): nodejs.install_from_package(site.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'}) users.SystemUser("ghost").add() uid = users.get_system("ghost").uid for r, d, f in os.walk(site.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) s = services.get(site.id) if s: s.remove() cfg = { 'directory': site.path, 'user': '******', 'command': 'node %s'%os.path.join(site.path, 'index.js'), 'autostart': 'true', 'autorestart': 'true', 'environment': 'NODE_ENV="production"', 'stdout_logfile': '/var/log/ghost.log', 'stderr_logfile': '/var/log/ghost.log' } s = services.Service(site.id, "supervisor", cfg=cfg) s.add()
def post_install(self, extra_vars, dbpasswd=""): # Make sure the webapps config points to # the _site directory and generate it. c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id)) for x in c.servers: if x.filter('Key', 'root'): x.filter('Key', 'root')[0].value = \ os.path.join(self.path, '_site') nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id)) s = shell('jekyll build --source {0} --destination {1}'.format( self.path, os.path.join(self.path, '_site'))) if s["code"] != 0: raise errors.OperationFailedError( 'Jekyll failed to build: {0}'.format(str(s["stderr"]))) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0o755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0o644) os.chown(os.path.join(r, x), uid, gid) # Return an explicatory message. return 'Jekyll has been setup, with a sample site at {0}. '\ 'Modify these files as you like. To learn how to use Jekyll, '\ 'visit http://jekyllrb.com/docs/usage. After making changes, '\ 'click the site icon to edit, then "Regenerate Site" '\ 'to bring your changes live.'.format(self.path)
def post_install(self, extra_vars, dbpasswd=""): # Write a basic index file showing that we are here if extra_vars.get('php'): php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini") index_ext = 'php' if extra_vars.get('php') else 'html' index_path = os.path.join(self.path, 'index.{0}'.format(index_ext)) addr = self.domain + (":" + str(self.port) if self.port != 80 else "") with open(index_path, 'w') as f: f.write( '<html>\n' '<body>\n' '<div style="text-align:center;margin-top:20%;font-family:sans-serif;">\n' '<img style="width: 300px;" src="https://cdn.citizenweb.io/static/img/arkos-2-01.png" />\n' '<h1>Custom Website</h1>\n' '<p>Your site is online at http://{0}, and stored at {0}</p>\n' '<p>Feel free to paste your site files there!</p>\n' '</div>\n' '</body>\n' '</html>\n'.format(addr, self.path)) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): # Create Lychee automatic configuration file with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f: f.write( '<?php\n' ' if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n' ' $dbHost = \'localhost\';\n' ' $dbUser = \'' + self.db.id + '\';\n' ' $dbPassword = \'' + dbpasswd + '\';\n' ' $dbName = \'' + self.db.id + '\';\n' ' $dbTablePrefix = \'\';\n' '?>\n') # Make sure that the correct PHP settings are enabled php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json', 'mbstring') # Rename lychee index.html to index.php to make it work with our default nginx config os.rename(os.path.join(self.path, "index.html"), os.path.join(self.path, "index.php")) # Finally, make sure that permissions are set so that Lychee # can make adjustments and save plugins when need be. uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def add_repo(name, dir, ro, perms, vers, rsc, nids=[]): config = pull_config() folder = {"id": name, "path": dir, "readOnly": ro, "ignorePerms": perms, "order": "random", "hashers": 0, "lenientMTimes": False, "copiers": 1, "autoNormalize": False, "rescanIntervalS": rsc or 60, "devices": [], "versioning": {"params": {}, "type": ""}} for x in nids: folder["devices"].append({"deviceID": x}) if vers: folder["versioning"]["type"] = "simple" folder["versioning"]["params"] = {"key": "keep", "val": vers} config["folders"].append(folder) if dir.startswith('~'): dir = os.path.join(os.path.expanduser("~syncthing"), dir.lstrip("~/")) if not os.path.exists(dir): os.makedirs(dir) uid = users.get_system('syncthing').uid for r, d, f in os.walk(dir): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) save_config(config) return folder
def post_install(self, vars, dbpasswd=""): # Create Lychee automatic configuration file with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f: f.write( '<?php\n' ' if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n' ' $dbHost = \'localhost\';\n' ' $dbUser = \'' + self.db.id + '\';\n' ' $dbPassword = \'' + dbpasswd + '\';\n' ' $dbName = \'' + self.db.id + '\';\n' ' $dbTablePrefix = \'\';\n' '?>\n' ) # Make sure that the correct PHP settings are enabled php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json', 'mbstring') # Rename lychee index.html to index.php to make it work with our default nginx config os.rename(os.path.join(self.path, "index.html"), os.path.join(self.path, "index.php")) # Finally, make sure that permissions are set so that Lychee # can make adjustments and save plugins when need be. uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, extra_vars, dbpasswd=""): secret_key = random_string() dbengine = 'mysql' \ if self.app.selected_dbengine == 'db-mariadb' \ else 'sqlite' # Write a standard Wallabag config file config_file = os.path.join(self.path, 'app/config/parameters.yml') with open(config_file + ".dist", 'r') as f: ic = f.readlines() with open(config_file, 'w') as f: for l in ic: if "database_driver: " in l: pdo = "pdo_mysql" if dbengine == "mysql" else "pdo_sqlite" l = " database_driver: {0}\n".format(pdo) elif "database_path: " in l and dbengine == 'sqlite': l = " database_path: {0}\n".format(self.db.path) elif "database_name: " in l and dbengine == 'mysql': l = " database_name: {0}\n".format(self.db.id) elif "database_user: "******" database_user: {0}\n".format(self.db.id) elif "database_password: "******"{0}"\n'.format(dbpasswd) elif "secret: " in l: l = " secret: {0}\n".format(secret_key) f.write(l) # Make sure that the correct PHP settings are enabled php.enable_mod('sqlite3', 'bcmath', 'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite', 'zip', 'tidy') php.open_basedir('add', '/usr/bin/php') uid, gid = users.get_system("http").uid, groups.get_system("http").gid # Set up the database then delete the install folder if dbengine == 'sqlite3': php.open_basedir('add', '/var/lib/sqlite3') cwd = os.getcwd() os.chdir(self.path) s = shell("php bin/console wallabag:install --env=prod -n") if s["code"] != 0: logger.error("Websites", s["stderr"].decode()) raise errors.OperationFailedError( "Failed to populate database. See logs for more info") os.chdir(cwd) if dbengine == 'sqlite3': os.chown("/var/lib/sqlite3/{0}.db".format(self.db.id), -1, gid) os.chmod("/var/lib/sqlite3/{0}.db".format(self.db.id), 0o660) # Finally, make sure that permissions are set so that Wallabag # can make adjustments and save plugins when need be. for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, extra_vars, dbpasswd=""): secret_key = random_string() # Use the WordPress key generators as first option # If connection fails, use the secret_key as fallback try: keysection = requests.get( 'https://api.wordpress.org/secret-key/1.1/salt/').text except: keysection = '' if 'define(\'AUTH_KEY' not in keysection: keysection = ( 'define(\'AUTH_KEY\', \'{0}\');\n' 'define(\'SECURE_AUTH_KEY\', \'{0}\');\n' 'define(\'LOGGED_IN_KEY\', \'{0}\');\n' 'define(\'NONCE_KEY\', \'{0}\');\n'.format(secret_key) ) # Write a standard WordPress config file with open(os.path.join(self.path, 'wp-config.php'), 'w') as f: f.write('<?php\n' 'define(\'DB_NAME\', \'{0}\');\n' 'define(\'DB_USER\', \'{0}\');\n' 'define(\'DB_PASSWORD\', \'{1}\');\n' 'define(\'DB_HOST\', \'localhost\');\n' 'define(\'DB_CHARSET\', \'utf8\');\n' 'define(\'SECRET_KEY\', \'{2}\');\n' '\n' 'define(\'WP_CACHE\', true);\n' 'define(\'FORCE_SSL_ADMIN\', false);\n' '\n' '{3}' '\n' '$table_prefix = \'wp_\';\n' '\n' '/** Absolute path to the WordPress directory. */\n' 'if ( !defined(\'ABSPATH\') )\n' ' define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n' '\n' '/** Sets up WordPress vars and included files. */\n' 'require_once(ABSPATH . \'wp-settings.php\');\n' .format(self.db.id, dbpasswd, secret_key, keysection) ) # Make sure that the correct PHP settings are enabled php.enable_mod('mysqli', 'opcache') php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini") # Finally, make sure that permissions are set so that Wordpress # can make adjustments and save plugins when need be. uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_restore(self, site, dbpasswd): nodejs.install_from_package(site.path) users.SystemUser("haste").add() uid = users.get_system("haste").uid for r, d, f in os.walk(site.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) services.get(site.id).enable()
def add(id, user, type): uid, gid = users.get_system("radicale").uid, groups.get_system("radicale").gid try: os.makedirs('/home/radicale/.config/radicale/collections/%s' % user) os.chown('/home/radicale/.config/radicale/collections', uid, gid) except os.error: pass with open(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), 'w') as f: f.write("") os.chown(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), uid, gid)
def post_install(self, extra_vars, dbpasswd=""): # Get around top-level zip restriction (FIXME 0.7.2) if "paperwork-master" in os.listdir(self.path): tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp")) os.rename(os.path.join(self.path, "paperwork-master/frontend"), tmp_path) os.rename(os.path.join(self.path, ".arkos"), os.path.join(tmp_path, ".arkos")) shutil.rmtree(self.path) os.rename(tmp_path, self.path) # Make sure that the correct PHP settings are enabled php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt') php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini") dbstr = "mysql, localhost, 3389, {0}, {1}, {0}"\ .format(self.id, dbpasswd) with open(os.path.join(self.path, 'app/storage/db_settings'), 'w') as f: f.write(dbstr) php.composer_install(self.path) nodejs.install("gulp", as_global=True) nodejs.install_from_package(self.path, stat=None) cwd = os.getcwd() os.chdir(self.path) s = shell("bower install --allow-root", stdin='y\n') if s["code"] != 0: raise Exception("Failed to run bower: {0}".format(s["stderr"])) s = shell("gulp") if s["code"] != 0: raise Exception("Failed to run gulp: {0}".format(s["stderr"])) s = shell("php artisan migrate --force") if s["code"] != 0: raise Exception("Failed to run artisan: {0}".format(s["stderr"])) os.chdir(cwd) # Make sure the webapps config points to the public directory. c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id)) for x in c.servers: if x.filter('Key', 'root'): x.filter('Key', 'root')[0].value = \ os.path.join(self.path, 'public') nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id)) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(os.path.join(self.path, 'app')): for x in d: os.chmod(os.path.join(r, x), 0o755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0o644) os.chown(os.path.join(r, x), uid, gid) if os.path.exists(os.path.join(self.path, 'app/storage/setup')): os.unlink(os.path.join(self.path, 'app/storage/setup'))
def put(self, path): data = json.loads(request.data)["file"] if not os.path.exists(data["path"]): abort(404) if data["operation"] == "copy": if os.path.exists(os.path.join(data["newdir"], data["name"])): data["name"] = data["name"]+"-copy" if os.path.isdir(data["path"]): shutil.copytree(data["path"], os.path.join(data["newdir"], data["name"])) else: shutil.copy2(data["path"], os.path.join(data["newdir"], data["name"])) return jsonify(file=as_dict(os.path.join(data["newdir"], data["name"]))) elif data["operation"] == "rename": shutil.move(data["path"], os.path.join(os.path.split(join(data["path"]))[0], data["name"])) elif data["operation"] == "edit": with open(data["path"], "w") as f: f.write(data["data"]) return jsonify(file=as_dict(data["path"])) elif data["operation"] == "props": orig = as_dict(data["path"]) if data["user"] != orig["user"] or data["group"] != orig["group"]: uid, gid = None, None u, g = users.get_system(data["user"]), groups.get_system(data["group"]) if data["user"] == "root": uid = 0 if data["group"] == "root": gid = 0 if u and g: uid, gid = u.uid, g.gid if uid == None or gid == None: resp = jsonify(message="Invalid user/group specification") resp.status_code = 422 return resp if data["folder"]: os.chown(data["path"], uid, gid) for r, d, f in os.walk(data["path"]): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid) else: os.chown(data["path"], u.uid, g.gid) if data["perms"]["oct"] != orig["perms"]["oct"]: if data["folder"]: os.chmod(data["path"], int(data["perms"]["oct"][1:], 8)) for r, d, f in os.walk(data["path"]): for x in d: os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8)) for x in f: os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8)) else: os.chmod(data["path"], int(data["perms"]["oct"][1:], 8)) return jsonify(file=as_dict(data["path"])) else: abort(422)
def update(self, pkg, ver): # General update procedure shell('unzip -o -d %s %s' % (self.path, pkg)) uid = users.get_system("ghost").uid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) nodejs.install_from_package(self.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'}) services.get(self.id).restart()
def post_install(self, vars, dbpasswd=""): secret_key = random_string() # Use the WordPress key generators as first option # If connection fails, use the secret_key as fallback try: keysection = urllib.urlopen('https://api.wordpress.org/secret-key/1.1/salt/').read() except: keysection = '' if not 'define(\'AUTH_KEY' in keysection: keysection = ( 'define(\'AUTH_KEY\', \''+secret_key+'\');\n' 'define(\'SECURE_AUTH_KEY\', \''+secret_key+'\');\n' 'define(\'LOGGED_IN_KEY\', \''+secret_key+'\');\n' 'define(\'NONCE_KEY\', \''+secret_key+'\');\n' ) # Write a standard WordPress config file with open(os.path.join(self.path, 'wp-config.php'), 'w') as f: f.write('<?php\n' 'define(\'DB_NAME\', \''+self.db.id+'\');\n' 'define(\'DB_USER\', \''+self.db.id+'\');\n' 'define(\'DB_PASSWORD\', \''+dbpasswd+'\');\n' 'define(\'DB_HOST\', \'localhost\');\n' 'define(\'DB_CHARSET\', \'utf8\');\n' 'define(\'SECRET_KEY\', \''+secret_key+'\');\n' '\n' 'define(\'WP_CACHE\', true);\n' 'define(\'FORCE_SSL_ADMIN\', false);\n' '\n' +keysection+ '\n' '$table_prefix = \'wp_\';\n' '\n' '/** Absolute path to the WordPress directory. */\n' 'if ( !defined(\'ABSPATH\') )\n' ' define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n' '\n' '/** Sets up WordPress vars and included files. */\n' 'require_once(ABSPATH . \'wp-settings.php\');\n' ) # Make sure that the correct PHP settings are enabled php.enable_mod('mysqli', 'opcache') php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini") # Finally, make sure that permissions are set so that Wordpress # can make adjustments and save plugins when need be. uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): # Get around top-level zip restriction (FIXME 0.7.2) if "paperwork-master" in os.listdir(self.path): tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp")) os.rename(os.path.join(self.path, "paperwork-master/frontend"), tmp_path) os.rename(os.path.join(self.path, ".arkos"), os.path.join(tmp_path, ".arkos")) shutil.rmtree(self.path) os.rename(tmp_path, self.path) # Make sure that the correct PHP settings are enabled php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt') php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini") dbstr = "mysql, localhost, 3389, {0}, {1}, {0}".format(self.id, dbpasswd) with open(os.path.join(self.path, 'app/storage/db_settings'), 'w') as f: f.write(dbstr) php.composer_install(self.path) nodejs.install("gulp", as_global=True) nodejs.install_from_package(self.path, stat=None) cwd = os.getcwd() os.chdir(self.path) s = shell("bower install --allow-root", stdin='y\n') if s["code"] != 0: raise Exception("Failed to run bower: %s" % s["stderr"]) s = shell("gulp") if s["code"] != 0: raise Exception("Failed to run gulp: %s" % s["stderr"]) s = shell("php artisan migrate --force") if s["code"] != 0: raise Exception("Failed to run artisan: %s" % s["stderr"]) os.chdir(cwd) # Make sure the webapps config points to the public directory. c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id)) for x in c.servers: if x.filter('Key', 'root'): x.filter('Key', 'root')[0].value = os.path.join(self.path, 'public') nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id)) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(os.path.join(self.path, 'app')): for x in d: os.chmod(os.path.join(r, x), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0644) os.chown(os.path.join(r, x), uid, gid) if os.path.exists(os.path.join(self.path, 'app/storage/setup')): os.unlink(os.path.join(self.path, 'app/storage/setup'))
def update(self, pkg, ver): # General update procedure shell('unzip -o -d {0} {1}'.format(self.path, pkg)) uid = users.get_system("ghost").uid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) nodejs.install_from_package(self.path, 'production', { 'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2' }) services.get(self.id).restart()
def add(id, user, type): uid, gid = users.get_system("radicale").uid, groups.get_system( "radicale").gid try: os.makedirs('/home/radicale/.config/radicale/collections/%s' % user) os.chown('/home/radicale/.config/radicale/collections', uid, gid) except os.error: pass with open( os.path.join('/home/radicale/.config/radicale/collections', user, id + type), 'w') as f: f.write("") os.chown( os.path.join('/home/radicale/.config/radicale/collections', user, id + type), uid, gid)
def regenerate(self): path = self.path if not path.endswith("_site"): path = os.path.join(self.path, "_site") s = shell('jekyll build --source '+self.path.split('/_site')[0]+' --destination '+path) if s["code"] != 0: raise Exception('Jekyll failed to build: %s'%str(s["stderr"])) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0644) os.chown(os.path.join(r, x), uid, gid)
def on_load(app): if app.id != "syncthing": return if not users.get_system("syncthing"): u = users.SystemUser('syncthing') u.add() u = users.get_system('syncthing') if not os.path.exists("/home/syncthing"): os.makedirs("/home/syncthing") os.chown("/home/syncthing", u.uid, 0o100) config_path = "/home/syncthing/.config/syncthing/config.xml" s = services.get("syncthing@syncthing") if not os.path.exists(config_path) and s.state != "running": s.restart() count = 0 while count < 5: if not os.path.exists(config_path): time.sleep(5) count += 1 else: break if not os.path.exists(config_path): raise Exception("Syncthing taking too long to generate config," " try again later")
def regenerate(self): path = self.path if not path.endswith("_site"): path = os.path.join(self.path, "_site") s = shell('jekyll build --source {0} --destination {1}'.format( self.path.split('/_site')[0], path)) if s["code"] != 0: raise errors.OperationFailedError( 'Jekyll failed to build: {0}'.format(str(s["stderr"]))) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0o755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0o644) os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): with open(os.path.join(self.path, 'config.js'), 'r') as f: d = json.loads(f.read()) d["port"] = self.backend_port if d["storage"]["type"] == "redis": d["storage"]["type"] = "file" d["storage"]["path"] = "./data" if d["storage"].has_key("host"): del d["storage"]["host"] if d["storage"].has_key("port"): del d["storage"]["port"] if d["storage"].has_key("db"): del d["storage"]["db"] if d["storage"].has_key("expire"): del d["storage"]["expire"] with open(os.path.join(self.path, 'config.js'), 'w') as f: f.write( json.dumps(d, sort_keys=True, indent=4, separators=(',', ': '))) nodejs.install_from_package(self.path) users.SystemUser("haste").add() # Finally, make sure that permissions are set so that Haste # can save its files properly. uid = users.get_system("haste").uid if not os.path.exists(os.path.join(self.path, 'data')): os.mkdir(os.path.join(self.path, 'data')) for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) cfg = { 'directory': self.path, 'user': '******', 'command': 'node %s' % os.path.join(self.path, 'server.js'), 'autostart': 'true', 'autorestart': 'true', 'environment': 'NODE_ENV="production"', 'stdout_logfile': '/var/log/haste.log', 'stderr_logfile': '/var/log/haste.log' } s = services.Service(self.id, "supervisor", cfg=cfg) s.add()
def post_install(self, vars, dbpasswd=""): with open(os.path.join(self.path, 'config.js'), 'r') as f: d = json.loads(f.read()) d["port"] = self.backend_port if d["storage"]["type"] == "redis": d["storage"]["type"] = "file" d["storage"]["path"] = "./data" if d["storage"].has_key("host"): del d["storage"]["host"] if d["storage"].has_key("port"): del d["storage"]["port"] if d["storage"].has_key("db"): del d["storage"]["db"] if d["storage"].has_key("expire"): del d["storage"]["expire"] with open(os.path.join(self.path, 'config.js'), 'w') as f: f.write(json.dumps(d, sort_keys=True, indent=4, separators=(',', ': '))) nodejs.install_from_package(self.path) users.SystemUser("haste").add() # Finally, make sure that permissions are set so that Haste # can save its files properly. uid = users.get_system("haste").uid if not os.path.exists(os.path.join(self.path, 'data')): os.mkdir(os.path.join(self.path, 'data')) for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) cfg = { 'directory': self.path, 'user': '******', 'command': 'node %s'%os.path.join(self.path, 'server.js'), 'autostart': 'true', 'autorestart': 'true', 'environment': 'NODE_ENV="production"', 'stdout_logfile': '/var/log/haste.log', 'stderr_logfile': '/var/log/haste.log' } s = services.Service(self.id, "supervisor", cfg=cfg) s.add()
def post_install(self, vars, dbpasswd=""): # Write a standard Wikitten config file shutil.copy(os.path.join(self.path, 'config.php.example'), os.path.join(self.path, 'config.php')) with open(os.path.join(self.path, 'config.php'), 'r') as f: d = f.read() d = d.replace("'My Wiki'", "'%s'" % self.id) with open(os.path.join(self.path, 'config.php'), 'w') as f: f.write(d) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): # Write a standard CMS.js config file with open(os.path.join(self.path, 'js/config.js'), 'r') as f: d = f.read() d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'") d = d.replace("siteTagline: 'Your site tagline'", "siteTagline: 'Configure js/config.js to your liking'") d = d.replace("mode: 'Github'", "mode: 'Server'") with open(os.path.join(self.path, 'js/config.js'), 'w') as f: f.write(d) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, extra_vars, dbpasswd=""): # Write a standard CMS.js config file with open(os.path.join(self.path, 'js/config.js'), 'r') as f: d = f.read() d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'") d = d.replace("siteTagline: 'Your site tagline'", "siteTagline: 'Configure js/config.js to your liking'") d = d.replace("mode: 'Github'", "mode: 'Server'") with open(os.path.join(self.path, 'js/config.js'), 'w') as f: f.write(d) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def add_acme_challenge(self): challenge_path = os.path.join(self.path, ".well-known/acme-challenge/") confpath = os.path.join("/etc/nginx/sites-available/", self.id) uid = users.get_system("http").uid block = nginx.loadf(confpath) server = block.server locations = server.filter("Location", "/.well-known/acme-challenge/") if locations: server.remove(*locations) server.add( nginx.Location("/.well-known/acme-challenge/", nginx.Key("root", self.path))) nginx.dumpf(block, confpath) if not os.path.exists(challenge_path): os.makedirs(challenge_path) os.chown(self.path, uid, -1) os.chown(os.path.join(self.path, ".well-known"), uid, -1) os.chown(challenge_path, uid, -1) nginx_reload() return challenge_path
def post_install(self, extra_vars, dbpasswd=""): # Write a standard Wikitten config file shutil.copy(os.path.join( self.path, 'config.php.example'), os.path.join(self.path, 'config.php')) with open(os.path.join(self.path, 'config.php'), 'r') as f: d = f.read() d = d.replace("'My Wiki'", "'{0}'".format(self.id)) with open(os.path.join(self.path, 'config.php'), 'w') as f: f.write(d) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): secret_key = random_string() php.open_basedir('add', '/dev') # If there is a custom path for the data directory, add to open_basedir uid, gid = users.get_system("http").uid, groups.get_system("http").gid os.makedirs(os.path.join(self.path, "data")) os.chown(os.path.join(self.path, "data"), uid, gid) if self.data_path == self.path: self.data_path = os.path.join(self.path, "data") else: try: os.makedirs(os.path.join(self.data_path)) except OSError, e: if e[0] == 17: pass else: raise os.chown(os.path.join(self.data_path), uid, gid) php.open_basedir('add', self.data_path)
def post_install(self, vars, dbpasswd=""): # Make sure the webapps config points to the _site directory and generate it. c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id)) for x in c.servers: if x.filter('Key', 'root'): x.filter('Key', 'root')[0].value = os.path.join(self.path, '_site') nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id)) s = shell('jekyll build --source '+self.path+' --destination '+os.path.join(self.path, '_site')) if s["code"] != 0: raise Exception('Jekyll failed to build: %s'%str(s["stderr"])) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0644) os.chown(os.path.join(r, x), uid, gid) # Return an explicatory message. return 'Jekyll has been setup, with a sample site at '+self.path+'. Modify these files as you like. To learn how to use Jekyll, visit http://jekyllrb.com/docs/usage. After making changes, click the Edit button for the site, then "Regenerate Site" to bring your changes live.'
def add_repo(name, dirname, ro, perms, vers, rsc, nids=[]): config = pull_config() folder = { "id": name, "path": dir, "readOnly": ro, "ignorePerms": perms, "order": "random", "hashers": 0, "lenientMTimes": False, "copiers": 1, "autoNormalize": False, "rescanIntervalS": rsc or 60, "devices": [], "versioning": { "params": {}, "type": "" } } for x in nids: folder["devices"].append({"deviceID": x}) if vers: folder["versioning"]["type"] = "simple" folder["versioning"]["params"] = {"key": "keep", "val": vers} config["folders"].append(folder) if dirname.startswith('~'): dirname = os.path.join(os.path.expanduser("~syncthing"), dirname.lstrip("~/")) if not os.path.exists(dir): os.makedirs(dir) uid = users.get_system('syncthing').uid for r, d, f in os.walk(dir): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) save_config(config) folder["is_ready"] = True return folder
def post_install(self, vars, dbpasswd=""): # Write a basic index file showing that we are here if vars.get('php'): php.enable_mod('xcache') with open(os.path.join(self.path, 'index.'+('php' if vars.get('php') else 'html')), 'w') as f: f.write( '<html>\n' '<body>\n' '<h1>Genesis - Custom Site</h1>\n' '<p>Your site is online and available at '+self.path+'</p>\n' '<p>Feel free to paste your site files here</p>\n' '</body>\n' '</html>\n' ) # Give access to httpd uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def update(self, pkg, ver): # General update procedure if semver.Version.coerce(ver) > semver.Version('2.0.0'): raise Exception( "Cannot automatically update from 1.x to 2.x. Please see " "Wallabag documentation for more information.") os.rename(os.path.join(self.path, 'app/config/parameters.yml'), '/tmp/_wb_parameters.yml') shell('tar xzf {0} -C {1} --strip 1'.format(pkg, self.path)) os.rename('/tmp/_wb_parameters.yml', os.path.join(self.path, 'app/config/parameters.yml')) cachepath = os.path.join(self.path, 'var/cache') for x in os.listdir(cachepath): fpath = os.path.join(cachepath, x) if os.path.isdir(fpath): shutil.rmtree(fpath) else: os.unlink(fpath) uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): secret_key = random_string() # If there is a custom path for the data directory, add to open_basedir uid, gid = users.get_system("http").uid, groups.get_system("http").gid if not self.data_path.startswith(self.path): os.makedirs(os.path.join(self.path, "data")) os.chown(os.path.join(self.path, "data"), uid, gid) php.open_basedir('add', self.data_path) # Create ownCloud automatic configuration file with open(os.path.join(self.path, 'config', 'autoconfig.php'), 'w') as f: f.write( '<?php\n' ' $AUTOCONFIG = array(\n' ' "adminlogin" => "admin",\n' ' "adminpass" => "'+dbpasswd+'",\n' ' "dbtype" => "mysql",\n' ' "dbname" => "'+self.db.id+'",\n' ' "dbuser" => "'+self.db.id+'",\n' ' "dbpass" => "'+dbpasswd+'",\n' ' "dbhost" => "localhost",\n' ' "dbtableprefix" => "",\n' ' "directory" => "'+self.data_path+'",\n' ' );\n' '?>\n' ) os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid) # Make sure that the correct PHP settings are enabled php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv', 'openssl', 'xcache', 'posix') # Make sure xcache has the correct settings, otherwise ownCloud breaks with open('/etc/php/conf.d/xcache.ini', 'w') as f: f.writelines(['extension=xcache.so\n', 'xcache.size=64M\n', 'xcache.var_size=64M\n', 'xcache.admin.enable_auth = Off\n', 'xcache.admin.user = "******"\n', 'xcache.admin.pass = "******"\n']) php.change_setting("always_populate_raw_post_data", "-1") mydir = os.getcwd() os.chdir(self.path) s = shell("sudo -u http php index.php") if s["code"] != 0: raise Exception("ownCloud database population failed") s = shell("sudo -u http php occ app:enable user_ldap") if s["code"] != 0: raise Exception("ownCloud LDAP configuration failed") os.chdir(mydir) ldap_sql = ("REPLACE INTO appconfig (appid, configkey, configvalue) VALUES" "('user_ldap', 'ldap_uuid_attribute', 'auto')," "('user_ldap', 'ldap_host', 'localhost')," "('user_ldap', 'ldap_port', '389')," "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_tls', '0')," "('user_ldap', 'ldap_display_name', 'cn')," "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount')," "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup')," "('user_ldap', 'ldap_group_display_name', 'cn')," "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember')," "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))')," "('user_ldap', 'ldap_quota_attr', 'mailQuota')," "('user_ldap', 'ldap_quota_def', '')," "('user_ldap', 'ldap_email_attr', 'mail')," "('user_ldap', 'ldap_cache_ttl', '600')," "('user_ldap', 'ldap_configuration_active', '1')," "('user_ldap', 'home_folder_naming_rule', '')," "('user_ldap', 'ldap_backup_host', '')," "('user_ldap', 'ldap_dn', '')," "('user_ldap', 'ldap_agent_password', '')," "('user_ldap', 'ldap_backup_port', '')," "('user_ldap', 'ldap_nocase', '')," "('user_ldap', 'ldap_turn_off_cert_check', '')," "('user_ldap', 'ldap_override_main_server', '')," "('user_ldap', 'ldap_attributes_for_user_search', '')," "('user_ldap', 'ldap_attributes_for_group_search', '')," "('user_ldap', 'ldap_expert_username_attr', 'uid')," "('user_ldap', 'ldap_expert_uuid_attr', '');" ) self.db.execute(ldap_sql, commit=True) # TODO set authed user name self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');", commit=True)
def post_install(self, extra_vars, dbpasswd=""): php.open_basedir('add', '/dev') # If there is a custom path for the data directory, add to open_basedir uid, gid = users.get_system("http").uid, groups.get_system("http").gid os.makedirs(os.path.join(self.path, "data")) os.chown(os.path.join(self.path, "data"), uid, gid) if self.data_path == self.path: self.data_path = os.path.join(self.path, "data") else: try: os.makedirs(os.path.join(self.data_path)) except OSError as e: if e[0] == 17: pass else: raise os.chown(os.path.join(self.data_path), uid, gid) php.open_basedir('add', self.data_path) # Make sure that the correct PHP settings are enabled php.enable_mod('opcache', 'mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv', 'openssl', 'posix') php.enable_mod('apcu', 'apc', config_file="/etc/php/conf.d/apcu.ini") php.change_setting('apc.enable_cli', '1', config_file="/etc/php/conf.d/apcu.ini") # Make sure php-fpm has the correct settings, # otherwise Nextcloud breaks with open("/etc/php/php-fpm.conf", "r") as f: lines = f.readlines() with open("/etc/php/php-fpm.conf", "w") as f: for line in lines: if ";clear_env = " in line: line = "clear_env = no\n" f.write(line) php.change_setting("always_populate_raw_post_data", "-1") mydir = os.getcwd() os.chdir(self.path) s = shell(('php occ maintenance:install ' '--database "mysql" --database-name "{}" ' '--database-user "{}" --database-pass "{}" ' '--admin-pass "{}" --data-dir "{}"').format( self.db.id, self.db.id, dbpasswd, dbpasswd, self.data_path)) if s["code"] != 0: logger.critical("Nextcloud", s["stderr"]) raise Exception("Nextcloud database population failed") s = shell("php occ app:enable user_ldap") if s["code"] != 0: logger.critical("Nextcloud", s["stderr"]) raise Exception("Nextcloud LDAP configuration failed") os.chdir(mydir) os.chown(os.path.join(self.path, "config/config.php"), uid, gid) ldap_sql = ("REPLACE INTO oc_appconfig " "(appid, configkey, configvalue) VALUES" "('core', 'backgroundjobs_mode', 'cron')," "('user_ldap', 'ldap_uuid_attribute', 'auto')," "('user_ldap', 'ldap_host', 'localhost')," "('user_ldap', 'ldap_port', '389')," "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_users', " "'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_groups', " "'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_tls', '0')," "('user_ldap', 'ldap_display_name', 'cn')," "('user_ldap', 'ldap_userlist_filter', " "'objectClass=mailAccount')," "('user_ldap', 'ldap_group_filter', " "'objectClass=posixGroup')," "('user_ldap', 'ldap_group_display_name', 'cn')," "('user_ldap', 'ldap_group_member_assoc_attribute', " "'uniqueMember')," "('user_ldap', 'ldap_login_filter', " "'(&(|(objectclass=posixAccount))(|(uid=%uid)))')," "('user_ldap', 'ldap_quota_attr', 'mailQuota')," "('user_ldap', 'ldap_quota_def', '')," "('user_ldap', 'ldap_email_attr', 'mail')," "('user_ldap', 'ldap_cache_ttl', '600')," "('user_ldap', 'ldap_configuration_active', '1')," "('user_ldap', 'home_folder_naming_rule', '')," "('user_ldap', 'ldap_backup_host', '')," "('user_ldap', 'ldap_dn', '')," "('user_ldap', 'ldap_agent_password', '')," "('user_ldap', 'ldap_backup_port', '')," "('user_ldap', 'ldap_nocase', '')," "('user_ldap', 'ldap_turn_off_cert_check', '')," "('user_ldap', 'ldap_override_main_server', '')," "('user_ldap', 'ldap_attributes_for_user_search', '')," "('user_ldap', 'ldap_attributes_for_group_search', '')," "('user_ldap', 'ldap_expert_username_attr', 'uid')," "('user_ldap', 'ldap_expert_uuid_attr', '');") self.db.execute(ldap_sql, commit=True) self.db.execute("DELETE FROM oc_group_user;", commit=True) self.db.execute( "INSERT INTO oc_group_user VALUES ('admin','{0}');".format( extra_vars.get("nc-admin", "admin")), commit=True) if not os.path.exists("/etc/cron.d"): os.mkdir("/etc/cron.d") with open("/etc/cron.d/nc-{0}".format(self.id), "w") as f: f.write("*/15 * * * * http php -f {0} > /dev/null 2>&1".format( os.path.join(self.path, "cron.php"))) with open(os.path.join(self.path, "config", "config.php"), "r") as f: data = f.read() while re.search("\n(\s*('|\")memcache.local.*?\n)", data, re.DOTALL): data = data.replace( re.search("\n(\s*('|\")memcache.local.*?\n)", data, re.DOTALL).group(1), "") data = data.split("\n") with open(os.path.join(self.path, "config", "config.php"), "w") as f: for x in data: if not x.endswith("\n"): x += "\n" if x.startswith(");"): f.write(" 'memcache.local' => '\OC\Memcache\APCu',\n") f.write(x) rootcerts = os.path.join(self.data_path, 'data/files_external/rootcerts.crt') if os.path.exists(rootcerts): os.chown(os.path.join(rootcerts), uid, gid) self.site_edited()
def put(self, path): data = request.get_json()["file"] if not os.path.exists(data["path"]): abort(404) orig = as_dict(data["path"]) if data["operation"] == "copy": if os.path.exists(os.path.join(data["newdir"], data["name"])): data["name"] = data["name"] + "-copy" if os.path.isdir(data["path"]): shutil.copytree(data["path"], os.path.join(data["newdir"], data["name"])) else: shutil.copy2(data["path"], os.path.join(data["newdir"], data["name"])) return jsonify( file=as_dict(os.path.join(data["newdir"], data["name"]))) elif data["operation"] == "rename": shutil.move( data["path"], os.path.join( os.path.split(join(data["path"]))[0], data["name"])) elif data["operation"] == "edit": with open(data["path"], "w") as f: f.write(data["data"]) return jsonify(file=as_dict(data["path"])) elif data["operation"] == "extract": if not orig["type"] == "archive": return jsonify(errors={"msg": "Not an archive"}), 422 extract(data["path"], os.path.dirname(data["path"])) return jsonify(file=as_dict(data["path"])) elif data["operation"] == "props": if data["user"] != orig["user"] or data["group"] != orig["group"]: uid, gid = None, None u, g = users.get_system(data["user"]), groups.get_system( data["group"]) if data["user"] == "root": uid = 0 if data["group"] == "root": gid = 0 if u and g: uid = u.uid if u.uid is not None else -1 gid = g.gid if g.gid is not None else -1 if data["folder"]: os.chown(data["path"], uid, gid) for r, d, f in os.walk(data["path"]): for x in d: os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid) else: os.chown(data["path"], uid, gid) if data["perms"]["oct"] != orig["perms"]["oct"]: if data["folder"]: os.chmod(data["path"], int(data["perms"]["oct"], 8)) for r, d, f in os.walk(data["path"]): for x in d: os.chmod(os.path.join(r, x), int(data["perms"]["oct"], 8)) for x in f: os.chmod(os.path.join(r, x), int(data["perms"]["oct"], 8)) else: os.chmod(data["path"], int(data["perms"]["oct"], 8)) return jsonify(file=as_dict(data["path"])) else: abort(422)
def _request_acme_certificate(domain, webroot, nthread): nthread.title = "Requesting ACME certificate" signals.emit("certificates", "pre_add", id) domains = [domain] uid = users.get_system("http").uid gid = groups.get_system("ssl-cert").gid if webroot: webroot = os.path.join(webroot, ".well-known", "acme-challenge") acme_dir = config.get("certificates", "acme_dir") cert_dir = os.path.join(acme_dir, "certs", domain) cert_path = os.path.join(cert_dir, "cert.pem") key_path = os.path.join(cert_dir, "privkey.pem") if not os.path.exists(cert_dir): os.makedirs(cert_dir) if not webroot: sites = websites.get() for x in sites: if x.port in [80, 443] and x.domain == domain: webroot = x.add_acme_challenge() break else: webroot = websites.create_acme_dummy(domain) smsg = "Requesting certificate from Let's Encrypt CA..." nthread.update(Notification("info", "Certificates", smsg)) agree_to_tos = None has_written_files = False while True: try: leclient.issue_certificate( domains, acme_dir, acme_server=config.get("certificates", "acme_server"), certificate_file=cert_path, private_key_file=key_path, agree_to_tos_url=agree_to_tos) break except leclient.NeedToAgreeToTOS as e: agree_to_tos = e.url continue except leclient.NeedToTakeAction as e: if not has_written_files: if not os.path.exists(webroot): os.makedirs(webroot) os.chown(webroot, uid, gid) for x in e.actions: fn = os.path.join(webroot, x.file_name) with open(fn, 'w') as f: f.write(x.contents) os.chown(fn, uid, gid) has_written_files = True continue else: raise errors.InvalidConfigError( "Requesting a certificate failed - it doesn't appear your " "requested domain's DNS is pointing to your server, or " "there was a port problem. Please check these things and " "try again.") except leclient.WaitABit as e: while e.until_when > datetime.datetime.now(): until = e.until_when - datetime.datetime.now() until_secs = int(round(until.total_seconds())) + 1 if until_secs > 300: raise errors.InvalidConfigError( "Requesting a certificate failed - LE rate limiting " "detected, for a period of more than five minutes. " "Please try again later." ) nthread.update( Notification( "warning", "Certificates", "LE rate limiting detected." " Will reattempt in {0} seconds".format(until_secs)) ) time.sleep(until_secs) continue except leclient.InvalidDomainName: raise errors.InvalidConfigError( "Requesting a certificate failed - invalid domain name" ) except leclient.RateLimited: raise errors.InvalidConfigError( "Requesting a certificate failed - LE is refusing to issue " "more certificates to you for this domain. Please choose " "another domain or try again another time." ) os.chown(cert_path, -1, gid) os.chown(key_path, -1, gid) os.chmod(cert_path, 0o750) os.chmod(key_path, 0o750) with open(cert_path, "rb") as f: cert = x509.load_pem_x509_certificate(f.read(), default_backend()) with open(key_path, "rb") as f: key = serialization.load_pem_private_key( f.read(), password=None, backend=default_backend() ) sha1 = binascii.hexlify(cert.fingerprint(hashes.SHA1())).decode() md5 = binascii.hexlify(cert.fingerprint(hashes.MD5())).decode() sha1 = ":".join([sha1[i:i+2].upper() for i in range(0, len(sha1), 2)]) md5 = ":".join([md5[i:i+2].upper() for i in range(0, len(md5), 2)]) if isinstance(key.public_key(), rsa.RSAPublicKey): ktype = "RSA" elif isinstance(key.public_key(), dsa.DSAPublicKey): ktype = "DSA" elif isinstance(key.public_key(), ec.EllipticCurvePublicKey): ktype = "EC" else: ktype = "Unknown" ksize = key.key_size c = Certificate(domain, domain, cert_path, key_path, ktype, ksize, [], cert.not_valid_after, sha1, md5, is_acme=True) storage.certificates[c.id] = c with open("/etc/cron.d/arkos-acme-renew", "a") as f: f.write("0 4 * * * systemctl reload nginx\n") fln = ("30 3 * * * free_tls_certificate {0} {1} {2} {3} {4} " ">> /var/log/acme-renew.log\n") f.write(fln.format( " ".join(domains), key_path, cert_path, webroot.split("/.well-known/acme-challenge")[0], acme_dir )) signals.emit("certificates", "post_add", c) msg = "Certificate issued successfully" nthread.complete(Notification("success", "Certificates", msg)) return c
def post_install(self, vars, dbpasswd=""): secret_key = random_string() dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite' username = vars.get("wb-username") passwd = vars.get("wb-passwd") + username + secret_key passwd = hashlib.sha1(passwd).hexdigest() # Write a standard Wallabag config file shutil.copy(os.path.join(self.path, 'inc/poche/config.inc.default.php'), os.path.join(self.path, 'inc/poche/config.inc.php')) with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'r') as f: ic = f.readlines() oc = [] for l in ic: if 'define (\'SALT\'' in l: l = '@define (\'SALT\', \''+secret_key+'\');\n' oc.append(l) elif 'define (\'STORAGE\'' in l: l = '@define (\'STORAGE\', \''+dbengine+'\');\n' oc.append(l) elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite': l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/'+self.db.id+'.db\');\n' oc.append(l) elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_DB\', \''+self.db.id+'\');\n' oc.append(l) elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_USER\', \''+self.db.id+'\');\n' oc.append(l) elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_PASSWORD\', \''+dbpasswd+'\');\n' oc.append(l) else: oc.append(l) with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'w') as f: f.writelines(oc) # Make sure that the correct PHP settings are enabled php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3', 'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite', 'zip', 'tidy', 'xcache', 'openssl') # Set up Composer and install the proper modules php.composer_install(self.path) uid, gid = users.get_system("http").uid, groups.get_system("http").gid # Set up the database then delete the install folder if dbengine == 'mysql': with open(os.path.join(self.path, 'install/mysql.sql')) as f: self.db.execute(f.read()) self.db.execute( "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username), commit=True) lid = int(self.db.manager.connection.insert_id()) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');" % lid, commit=True) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');" % lid, commit=True) else: shutil.copy(os.path.join(self.path, 'install/poche.sqlite'), '/var/lib/sqlite3/%s.db' % self.db.id) php.open_basedir('add', '/var/lib/sqlite3') os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid) os.chmod("/var/lib/sqlite3/%s.db", 0664) self.db.execute( "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username)) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');") self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');") shutil.rmtree(os.path.join(self.path, 'install')) # Finally, make sure that permissions are set so that Wallabag # can make adjustments and save plugins when need be. for r, d, f in os.walk(self.path): for x in d: if d in ["assets", "cache", "db"]: os.chmod(os.path.join(r, d), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
# Format extraction command according to type message.update("info", "Extracting source...", head="Installing website") if ending in [".tar.gz", ".tgz", ".tar.bz2"]: extract_cmd = "tar " extract_cmd += "xzf" if ending in [".tar.gz", ".tgz"] else "xjf" extract_cmd += " /tmp/%s -C %s --strip 1" % (self.id+ending, self.path) else: extract_cmd = "unzip -d %s /tmp/%s" % (self.path, self.id+ending) status = shell(extract_cmd) if status["code"] >= 1: raise Exception(status["stderr"]) os.remove(pkg_path) # Set proper starting permissions on source directory uid, gid = users.get_system("http").uid, groups.get_system("http").gid for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0644) os.chown(os.path.join(r, x), uid, gid) # If there is a custom path for the data directory, set it up if hasattr(self.meta, "website_datapaths") and self.meta.website_datapaths \ and extra_vars.get("datadir"): self.data_path = extra_vars["datadir"] if not os.path.exists(self.data_path): os.makedirs(self.data_path) os.chmod(self.data_path, 0755)
def _install(self, extra_vars, enable, nthread): nthread.title = "Installing website" msg = Notification("info", "Webs", "Preparing to install...") nthread.update(msg) # Make sure the chosen port is indeed open if not tracked_services.is_open_port(self.port, self.domain): cname = "({0})".format(self.app.id) raise errors.InvalidConfigError(cname, nthread)\ from tracked_services.PortConflictError(self.port, self.domain) # Set some metadata values specialmsg, dbpasswd = "", "" site_dir = config.get("websites", "site_dir") path = (self.path or os.path.join(site_dir, self.id)) self.path = path self.php = extra_vars.get("php") or self.php \ or self.app.uses_php or False self.version = self.app.version.rsplit("-", 1)[0] \ if self.app.website_updates else None # Classify the source package type if not self.app.download_url: ending = "" elif self.app.download_url.endswith(".tar.gz"): ending = ".tar.gz" elif self.app.download_url.endswith(".tgz"): ending = ".tgz" elif self.app.download_url.endswith(".tar.bz2"): ending = ".tar.bz2" elif self.app.download_url.endswith(".zip"): ending = ".zip" elif self.app.download_url.endswith(".git"): ending = ".git" else: raise errors.InvalidConfigError( "Invalid source archive format in {0}".format(self.app.id)) msg = "Running pre-installation..." uid, gid = users.get_system("http").uid, groups.get_system("http").gid nthread.update(Notification("info", "Webs", msg)) # Call website type's pre-install hook self.pre_install(extra_vars) # If needs DB and user didn't select an engine, choose one for them if len(self.app.database_engines) > 1 \ and extra_vars.get("dbengine", None): self.app.selected_dbengine = extra_vars.get("dbengine") if not getattr(self.app, "selected_dbengine", None)\ and self.app.database_engines: self.app.selected_dbengine = self.app.database_engines[0] # Create DB and/or DB user as necessary if getattr(self.app, "selected_dbengine", None): msg = "Creating database..." nthread.update(Notification("info", "Webs", msg)) mgr = databases.get_managers(self.app.selected_dbengine) if not mgr: estr = "No manager found for {0}" raise errors.InvalidConfigError( estr.format(self.app.selected_dbengine)) # Make sure DB daemon is running if it has one if not mgr.state: svc = services.get(mgr.meta.database_service) svc.restart() self.db = mgr.add_db(self.id) if hasattr(self.db, "path"): os.chmod(self.db.path, 0o660) os.chown(self.db.path, -1, gid) # If multiuser DB type, create user if mgr.meta.database_multiuser: dbpasswd = random_string(16) db_user = mgr.add_user(self.id, dbpasswd) db_user.chperm("grant", self.db) # Make sure the target directory exists, but is empty pkg_path = os.path.join("/tmp", self.id + ending) if os.path.isdir(self.path): shutil.rmtree(self.path) os.makedirs(self.path) # Download and extract the source repo / package msg = "Downloading website source..." nthread.update(Notification("info", "Webs", msg)) if self.app.download_url and ending == ".git": g = git.Repo.clone_from(self.app.download_url, self.path) if hasattr(self.app, "download_at_tag"): g = git.Git(self.path) g.checkout(self.app.download_git_tag) elif self.app.download_url: download(self.app.download_url, file=pkg_path, crit=True) # Format extraction command according to type msg = "Extracting source..." nthread.update(Notification("info", "Webs", msg)) if ending in [".tar.gz", ".tgz", ".tar.bz2"]: arch = tarfile.open(pkg_path, "r:gz") r = (x for x in arch.getnames() if re.match("^[^/]*$", x)) toplvl = next(r, None) if not toplvl: raise errors.OperationFailedError( "Malformed source archive") arch.extractall(site_dir) os.rename(os.path.join(site_dir, toplvl), self.path) else: arch = zipfile.ZipFile(pkg_path) r = (x for x in arch.namelist() if re.match("^[^/]*/$", x)) toplvl = next(r, None) if not toplvl: raise errors.OperationFailedError( "Malformed source archive") arch.extractall(site_dir) os.rename(os.path.join(site_dir, toplvl.rstrip("/")), self.path) os.remove(pkg_path) # Set proper starting permissions on source directory os.chmod(self.path, 0o755) os.chown(self.path, uid, gid) for r, d, f in os.walk(self.path): for x in d: os.chmod(os.path.join(r, x), 0o755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chmod(os.path.join(r, x), 0o644) os.chown(os.path.join(r, x), uid, gid) # If there is a custom path for the data directory, set it up if getattr(self.app, "website_datapaths", None) \ and extra_vars.get("datadir"): self.data_path = extra_vars["datadir"] if not os.path.exists(self.data_path): os.makedirs(self.data_path) os.chmod(self.data_path, 0o755) os.chown(self.data_path, uid, gid) elif hasattr(self, "website_default_data_subdir"): self.data_path = os.path.join(self.path, self.website_default_data_subdir) else: self.data_path = self.path # Create the nginx serverblock addtoblock = self.addtoblock or [] if extra_vars.get("addtoblock"): addtoblock += nginx.loads(extra_vars.get("addtoblock"), False) default_index = "index." + ("php" if self.php else "html") if hasattr(self.app, "website_root"): webroot = os.path.join(self.path, self.app.website_root) else: webroot = self.path block = nginx.Conf() server = nginx.Server( nginx.Key("listen", str(self.port)), nginx.Key("listen", "[::]:" + str(self.port)), nginx.Key("server_name", self.domain), nginx.Key("root", webroot), nginx.Key( "index", getattr(self.app, "website_index", None) or default_index), nginx.Location("/.well-known/acme-challenge/", nginx.Key("root", self.path))) if addtoblock: server.add(*[x for x in addtoblock]) block.add(server) nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id)) challenge_dir = os.path.join(self.path, ".well-known/acme-challenge/") if not os.path.exists(challenge_dir): os.makedirs(challenge_dir) # Create arkOS metadata file meta = configparser.SafeConfigParser() meta.add_section("website") meta.set("website", "id", self.id) meta.set("website", "app", self.app.id) meta.set("website", "ssl", self.cert.id if getattr(self, "cert", None) else "None") meta.set("website", "version", self.version or "None") if getattr(self.app, "website_datapaths", None) \ and self.data_path: meta.set("website", "data_path", self.data_path) meta.set("website", "dbengine", "") meta.set("website", "dbengine", getattr(self.app, "selected_dbengine", "")) with open(os.path.join(self.path, ".arkos"), "w") as f: meta.write(f) # Call site type's post-installation hook msg = "Running post-installation. This may take a few minutes..." nthread.update(Notification("info", "Webs", msg)) specialmsg = self.post_install(extra_vars, dbpasswd) # Cleanup and reload daemons msg = "Finishing..." nthread.update(Notification("info", "Webs", msg)) self.installed = True storage.websites[self.id] = self if self.port == 80: cleanup_acme_dummy(self.domain) signals.emit("websites", "site_installed", self) if enable: self.nginx_enable() if enable and self.php: php.open_basedir("add", "/srv/http/") php_reload() msg = "{0} site installed successfully".format(self.app.name) nthread.complete(Notification("success", "Webs", msg)) if specialmsg: return specialmsg
def post_install(self, vars, dbpasswd=""): secret_key = random_string() dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite' username = vars.get("wb-username") passwd = vars.get("wb-passwd") + username + secret_key passwd = hashlib.sha1(passwd).hexdigest() # Write a standard Wallabag config file shutil.copy( os.path.join(self.path, 'inc/poche/config.inc.default.php'), os.path.join(self.path, 'inc/poche/config.inc.php')) with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'r') as f: ic = f.readlines() oc = [] for l in ic: if 'define (\'SALT\'' in l: l = '@define (\'SALT\', \'' + secret_key + '\');\n' oc.append(l) elif 'define (\'STORAGE\'' in l: l = '@define (\'STORAGE\', \'' + dbengine + '\');\n' oc.append(l) elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite': l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/' + self.db.id + '.db\');\n' oc.append(l) elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_DB\', \'' + self.db.id + '\');\n' oc.append(l) elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_USER\', \'' + self.db.id + '\');\n' oc.append(l) elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql': l = '@define (\'STORAGE_PASSWORD\', \'' + dbpasswd + '\');\n' oc.append(l) else: oc.append(l) with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'w') as f: f.writelines(oc) # Make sure that the correct PHP settings are enabled php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3', 'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite', 'zip', 'tidy', 'xcache', 'openssl') # Set up Composer and install the proper modules php.composer_install(self.path) uid, gid = users.get_system("http").uid, groups.get_system("http").gid # Set up the database then delete the install folder if dbengine == 'mysql': with open(os.path.join(self.path, 'install/mysql.sql')) as f: self.db.execute(f.read()) self.db.execute( "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username), commit=True) lid = int(self.db.manager.connection.insert_id()) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');" % lid, commit=True) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');" % lid, commit=True) else: shutil.copy(os.path.join(self.path, 'install/poche.sqlite'), '/var/lib/sqlite3/%s.db' % self.db.id) php.open_basedir('add', '/var/lib/sqlite3') os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid) os.chmod("/var/lib/sqlite3/%s.db", 0664) self.db.execute( "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username)) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');" ) self.db.execute( "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');" ) shutil.rmtree(os.path.join(self.path, 'install')) # Finally, make sure that permissions are set so that Wallabag # can make adjustments and save plugins when need be. for r, d, f in os.walk(self.path): for x in d: if d in ["assets", "cache", "db"]: os.chmod(os.path.join(r, d), 0755) os.chown(os.path.join(r, x), uid, gid) for x in f: os.chown(os.path.join(r, x), uid, gid)
def post_install(self, vars, dbpasswd=""): secret_key = random_string() # If there is a custom path for the data directory, add to open_basedir uid, gid = users.get_system("http").uid, groups.get_system("http").gid if not self.data_path.startswith(self.path): os.makedirs(os.path.join(self.path, "data")) os.chown(os.path.join(self.path, "data"), uid, gid) php.open_basedir('add', self.data_path) # Create ownCloud automatic configuration file with open(os.path.join(self.path, 'config', 'autoconfig.php'), 'w') as f: f.write('<?php\n' ' $AUTOCONFIG = array(\n' ' "adminlogin" => "admin",\n' ' "adminpass" => "' + dbpasswd + '",\n' ' "dbtype" => "mysql",\n' ' "dbname" => "' + self.db.id + '",\n' ' "dbuser" => "' + self.db.id + '",\n' ' "dbpass" => "' + dbpasswd + '",\n' ' "dbhost" => "localhost",\n' ' "dbtableprefix" => "",\n' ' "directory" => "' + self.data_path + '",\n' ' );\n' '?>\n') os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid) # Make sure that the correct PHP settings are enabled php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv', 'openssl', 'xcache', 'posix') # Make sure xcache has the correct settings, otherwise ownCloud breaks with open('/etc/php/conf.d/xcache.ini', 'w') as f: f.writelines([ 'extension=xcache.so\n', 'xcache.size=64M\n', 'xcache.var_size=64M\n', 'xcache.admin.enable_auth = Off\n', 'xcache.admin.user = "******"\n', 'xcache.admin.pass = "******"\n' ]) php.change_setting("always_populate_raw_post_data", "-1") mydir = os.getcwd() os.chdir(self.path) s = shell("sudo -u http php index.php") if s["code"] != 0: raise Exception("ownCloud database population failed") s = shell("sudo -u http php occ app:enable user_ldap") if s["code"] != 0: raise Exception("ownCloud LDAP configuration failed") os.chdir(mydir) ldap_sql = ( "REPLACE INTO appconfig (appid, configkey, configvalue) VALUES" "('user_ldap', 'ldap_uuid_attribute', 'auto')," "('user_ldap', 'ldap_host', 'localhost')," "('user_ldap', 'ldap_port', '389')," "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org')," "('user_ldap', 'ldap_tls', '0')," "('user_ldap', 'ldap_display_name', 'cn')," "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount')," "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup')," "('user_ldap', 'ldap_group_display_name', 'cn')," "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember')," "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))')," "('user_ldap', 'ldap_quota_attr', 'mailQuota')," "('user_ldap', 'ldap_quota_def', '')," "('user_ldap', 'ldap_email_attr', 'mail')," "('user_ldap', 'ldap_cache_ttl', '600')," "('user_ldap', 'ldap_configuration_active', '1')," "('user_ldap', 'home_folder_naming_rule', '')," "('user_ldap', 'ldap_backup_host', '')," "('user_ldap', 'ldap_dn', '')," "('user_ldap', 'ldap_agent_password', '')," "('user_ldap', 'ldap_backup_port', '')," "('user_ldap', 'ldap_nocase', '')," "('user_ldap', 'ldap_turn_off_cert_check', '')," "('user_ldap', 'ldap_override_main_server', '')," "('user_ldap', 'ldap_attributes_for_user_search', '')," "('user_ldap', 'ldap_attributes_for_group_search', '')," "('user_ldap', 'ldap_expert_username_attr', 'uid')," "('user_ldap', 'ldap_expert_uuid_attr', '');") self.db.execute(ldap_sql, commit=True) # TODO set authed user name self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');", commit=True)
def post_install(self, vars, dbpasswd=""): with open(os.path.join(self.path, 'package.json'), 'r') as f: d = json.loads(f.read()) del d['dependencies']['bcryptjs'] d['dependencies']['bcrypt'] = '0.8.1' with open(os.path.join(self.path, 'package.json'), 'w') as f: f.write(json.dumps(d)) with open(os.path.join(self.path, 'core/server/models/user.js'), 'r') as f: d = f.read() d = d.replace('bcryptjs', 'bcrypt') with open(os.path.join(self.path, 'core/server/models/user.js'), 'w') as f: f.write(d) if os.path.exists(os.path.join(self.path, 'npm-shrinkwrap.json')): os.unlink(os.path.join(self.path, 'npm-shrinkwrap.json')) nodejs.install_from_package(self.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'}) users.SystemUser("ghost").add() # Get Mail settings mail_settings = { 'transport' : vars.get('ghost-transport') or "", 'service' : vars.get('ghost-service') or "", 'mail_user' : vars.get('ghost-mail-user') or "", 'mail_pass' : vars.get('ghost-mail-pass') or "", 'from_address' : vars.get('ghost-from-address') or "" } # Create/Edit the Ghost config file with open(os.path.join(self.path, 'config.example.js'), 'r') as f: data = f.read() data = data.replace("port: '2368'", "port: '%s'" % self.backend_port) data = data.replace('http://my-ghost-blog.com', 'http://'+self.addr+(':'+str(self.port) if str(self.port) != '80' else'')) if len(set(mail_settings.values())) != 1 and\ mail_settings['transport'] != '': # If the mail settings exist, add them data = data.replace( "mail: {},",\ 'mail: {\n' "\tfromaddress: '" + mail_settings['from_address'] + "',\n" "\ttransport: '" + mail_settings['transport'] + "',\n" "\t\toptions: {\n" "\t\t\tservice: '" + mail_settings['service'] + "',\n" "\t\t\tauth: {\n" "\t\t\t\tuser: '******'mail_user'] + "',\n" "\t\t\t\tpass: '******'mail_pass'] + "'\n" "\t\t\t}\n" "\t\t}\n" "},\n" ) with open(os.path.join(self.path, 'config.js'), 'w') as f: f.write(data) # Finally, make sure that permissions are set so that Ghost # can make adjustments and save plugins when need be. uid = users.get_system("ghost").uid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) cfg = { 'directory': self.path, 'user': '******', 'command': 'node %s'%os.path.join(self.path, 'index.js'), 'autostart': 'true', 'autorestart': 'true', 'environment': 'NODE_ENV="production"', 'stdout_logfile': '/var/log/ghost.log', 'stderr_logfile': '/var/log/ghost.log' } s = services.Service(self.id, "supervisor", cfg=cfg) s.add()
def post_install(self, extra_vars, dbpasswd=""): with open(os.path.join(self.path, 'package.json'), 'r') as f: d = json.loads(f.read()) del d['dependencies']['bcryptjs'] d['dependencies']['bcrypt'] = '0.8.5' d['engines']['node'] = '~0.10.0 || ~0.12.0 || ^4.2.0 || ^5.6.0' with open(os.path.join(self.path, 'package.json'), 'w') as f: f.write(json.dumps(d)) with open(os.path.join(self.path, 'core/server/models/user.js'), 'r') as f: d = f.read() d = d.replace('bcryptjs', 'bcrypt') with open(os.path.join(self.path, 'core/server/models/user.js'), 'w') as f: f.write(d) if os.path.exists(os.path.join(self.path, 'npm-shrinkwrap.json')): os.unlink(os.path.join(self.path, 'npm-shrinkwrap.json')) nodejs.install_from_package(self.path, 'production', {'python': '/usr/bin/python2'}) users.SystemUser("ghost").add() # Get Mail settings mail_settings = { 'transport': extra_vars.get('gh-transport') or "", 'service': extra_vars.get('gh-service') or "", 'mail_user': extra_vars.get('gh-mail-user') or "", 'mail_pass': extra_vars.get('gh-mail-pass') or "", 'from_address': extra_vars.get('gh-from-address') or "" } # Create/Edit the Ghost config file with open(os.path.join(self.path, 'config.example.js'), 'r') as f: data = f.read() data = data.replace("port: '2368'", "port: '{0}'".format(self.backend_port)) data = data.replace( 'http://my-ghost-blog.com', 'http://{0}' + (':' + str(self.port) if str(self.port) != '80' else '').format( self.addr)) if len(set(mail_settings.values())) != 1 and\ mail_settings['transport'] != '': # If the mail settings exist, add them data = data.replace( "mail: {},", 'mail: {\n' "\tfromaddress: '" + mail_settings['from_address'] + "',\n" "\ttransport: '" + mail_settings['transport'] + "',\n" "\t\toptions: {\n" "\t\t\tservice: '" + mail_settings['service'] + "',\n" "\t\t\tauth: {\n" "\t\t\t\tuser: '******'mail_user'] + "',\n" "\t\t\t\tpass: '******'mail_pass'] + "'\n" "\t\t\t}\n" "\t\t}\n" "},\n") with open(os.path.join(self.path, 'config.js'), 'w') as f: f.write(data) # Finally, make sure that permissions are set so that Ghost # can make adjustments and save plugins when need be. uid = users.get_system("ghost").uid for r, d, f in os.walk(self.path): for x in d: os.chown(os.path.join(r, x), uid, -1) for x in f: os.chown(os.path.join(r, x), uid, -1) cfg = { 'directory': self.path, 'user': '******', 'command': 'node {0}'.format(os.path.join(self.path, 'index.js')), 'autostart': 'true', 'autorestart': 'true', 'environment': 'NODE_ENV="production"', 'stdout_logfile': '/var/log/ghost.log', 'stderr_logfile': '/var/log/ghost.log' } s = services.Service(self.id, "supervisor", cfg=cfg) s.add()