mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
commit
dddc92949c
7 changed files with 39 additions and 53 deletions
|
@ -49,12 +49,8 @@ do_post_regen() {
|
||||||
# retrieve variables
|
# retrieve variables
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
|
|
||||||
# FIXME : small optimization to do to avoid calling a yunohost command ...
|
|
||||||
# maybe another env variable like YNH_MAIN_DOMAINS idk
|
|
||||||
domain_list=$(yunohost domain list --exclude-subdomains --output-as plain --quiet)
|
|
||||||
|
|
||||||
# create metronome directories for domains
|
# create metronome directories for domains
|
||||||
for domain in $domain_list; do
|
for domain in $YNH_MAIN_DOMAINS; do
|
||||||
mkdir -p "/var/lib/metronome/${domain//./%2e}/pep"
|
mkdir -p "/var/lib/metronome/${domain//./%2e}/pep"
|
||||||
# http_upload directory must be writable by metronome and readable by nginx
|
# http_upload directory must be writable by metronome and readable by nginx
|
||||||
mkdir -p "/var/xmpp-upload/${domain}/upload"
|
mkdir -p "/var/xmpp-upload/${domain}/upload"
|
||||||
|
|
|
@ -735,6 +735,10 @@ app:
|
||||||
full: --full
|
full: --full
|
||||||
help: Display all details, including the app manifest and various other infos
|
help: Display all details, including the app manifest and various other infos
|
||||||
action: store_true
|
action: store_true
|
||||||
|
-u:
|
||||||
|
full: --upgradable
|
||||||
|
help: List only apps that can upgrade to a newer version
|
||||||
|
action: store_true
|
||||||
|
|
||||||
### app_info()
|
### app_info()
|
||||||
info:
|
info:
|
||||||
|
|
31
src/app.py
31
src/app.py
|
@ -95,7 +95,7 @@ APP_FILES_TO_COPY = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def app_list(full=False):
|
def app_list(full=False, upgradable=False):
|
||||||
"""
|
"""
|
||||||
List installed apps
|
List installed apps
|
||||||
"""
|
"""
|
||||||
|
@ -103,17 +103,19 @@ def app_list(full=False):
|
||||||
out = []
|
out = []
|
||||||
for app_id in sorted(_installed_apps()):
|
for app_id in sorted(_installed_apps()):
|
||||||
try:
|
try:
|
||||||
app_info_dict = app_info(app_id, full=full)
|
app_info_dict = app_info(app_id, full=full, upgradable=upgradable)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to read info for {app_id} : {e}")
|
logger.error(f"Failed to read info for {app_id} : {e}")
|
||||||
continue
|
continue
|
||||||
app_info_dict["id"] = app_id
|
app_info_dict["id"] = app_id
|
||||||
|
if upgradable and app_info_dict.get("upgradable") != "yes":
|
||||||
|
continue
|
||||||
out.append(app_info_dict)
|
out.append(app_info_dict)
|
||||||
|
|
||||||
return {"apps": out}
|
return {"apps": out}
|
||||||
|
|
||||||
|
|
||||||
def app_info(app, full=False):
|
def app_info(app, full=False, upgradable=False):
|
||||||
"""
|
"""
|
||||||
Get info for a specific app
|
Get info for a specific app
|
||||||
"""
|
"""
|
||||||
|
@ -139,6 +141,25 @@ def app_info(app, full=False):
|
||||||
if "domain" in settings and "path" in settings:
|
if "domain" in settings and "path" in settings:
|
||||||
ret["domain_path"] = settings["domain"] + settings["path"]
|
ret["domain_path"] = settings["domain"] + settings["path"]
|
||||||
|
|
||||||
|
if not upgradable and not full:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
absolute_app_name, _ = _parse_app_instance_name(app)
|
||||||
|
from_catalog = _load_apps_catalog()["apps"].get(absolute_app_name, {})
|
||||||
|
|
||||||
|
ret["upgradable"] = _app_upgradable({** ret, "from_catalog": from_catalog})
|
||||||
|
|
||||||
|
if ret["upgradable"] == "yes":
|
||||||
|
ret["current_version"] = ret.get("version", "?")
|
||||||
|
ret["new_version"] = from_catalog.get("manifest", {}).get("version", "?")
|
||||||
|
|
||||||
|
if ret["current_version"] == ret["new_version"]:
|
||||||
|
current_revision = settings.get("current_revision", "?")[:7]
|
||||||
|
new_revision = from_catalog.get("git", {}).get("revision", "?")[:7]
|
||||||
|
|
||||||
|
ret["current_version"] = " ({current_revision})"
|
||||||
|
ret["new_version"] = " ({new_revision})"
|
||||||
|
|
||||||
if not full:
|
if not full:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -149,9 +170,7 @@ def app_info(app, full=False):
|
||||||
)
|
)
|
||||||
ret["settings"] = settings
|
ret["settings"] = settings
|
||||||
|
|
||||||
absolute_app_name, _ = _parse_app_instance_name(app)
|
ret["from_catalog"] = from_catalog
|
||||||
ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {})
|
|
||||||
ret["upgradable"] = _app_upgradable(ret)
|
|
||||||
|
|
||||||
ret["is_webapp"] = "domain" in settings and "path" in settings
|
ret["is_webapp"] = "domain" in settings and "path" in settings
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ def domain_dns_suggest(domain):
|
||||||
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
||||||
|
|
||||||
if dns_conf["extra"]:
|
if dns_conf["extra"]:
|
||||||
|
result += "\n\n"
|
||||||
result += "; Extra"
|
result += "; Extra"
|
||||||
for record in dns_conf["extra"]:
|
for record in dns_conf["extra"]:
|
||||||
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
result += "\n{name} {ttl} IN {type} {value}".format(**record)
|
||||||
|
|
|
@ -140,6 +140,7 @@ def regen_conf(
|
||||||
# though kinda tight-coupled to the postinstall logic :s
|
# though kinda tight-coupled to the postinstall logic :s
|
||||||
if os.path.exists("/etc/yunohost/installed"):
|
if os.path.exists("/etc/yunohost/installed"):
|
||||||
env["YNH_DOMAINS"] = " ".join(domain_list()["domains"])
|
env["YNH_DOMAINS"] = " ".join(domain_list()["domains"])
|
||||||
|
env["YNH_MAIN_DOMAINS"] = " ".join(domain_list(exclude_subdomains=True)["domains"])
|
||||||
|
|
||||||
pre_result = hook_callback("conf_regen", names, pre_callback=_pre_call, env=env)
|
pre_result = hook_callback("conf_regen", names, pre_callback=_pre_call, env=env)
|
||||||
|
|
||||||
|
|
43
src/tools.py
43
src/tools.py
|
@ -37,8 +37,8 @@ from moulinette.utils.process import call_async_output
|
||||||
from moulinette.utils.filesystem import read_yaml, write_to_yaml, cp, mkdir, rm
|
from moulinette.utils.filesystem import read_yaml, write_to_yaml, cp, mkdir, rm
|
||||||
|
|
||||||
from yunohost.app import (
|
from yunohost.app import (
|
||||||
app_info,
|
|
||||||
app_upgrade,
|
app_upgrade,
|
||||||
|
app_list
|
||||||
)
|
)
|
||||||
from yunohost.app_catalog import (
|
from yunohost.app_catalog import (
|
||||||
_initialize_apps_catalog_system,
|
_initialize_apps_catalog_system,
|
||||||
|
@ -56,8 +56,6 @@ from yunohost.utils.packages import (
|
||||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||||
from yunohost.log import is_unit_operation, OperationLogger
|
from yunohost.log import is_unit_operation, OperationLogger
|
||||||
|
|
||||||
# FIXME this is a duplicate from apps.py
|
|
||||||
APPS_SETTING_PATH = "/etc/yunohost/apps/"
|
|
||||||
MIGRATIONS_STATE_PATH = "/etc/yunohost/migrations.yaml"
|
MIGRATIONS_STATE_PATH = "/etc/yunohost/migrations.yaml"
|
||||||
|
|
||||||
logger = getActionLogger("yunohost.tools")
|
logger = getActionLogger("yunohost.tools")
|
||||||
|
@ -391,7 +389,7 @@ def tools_update(target=None):
|
||||||
except YunohostError as e:
|
except YunohostError as e:
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
|
|
||||||
upgradable_apps = list(_list_upgradable_apps())
|
upgradable_apps = list(app_list(upgradable=True)["apps"])
|
||||||
|
|
||||||
if len(upgradable_apps) == 0 and len(upgradable_system_packages) == 0:
|
if len(upgradable_apps) == 0 and len(upgradable_system_packages) == 0:
|
||||||
logger.info(m18n.n("already_up_to_date"))
|
logger.info(m18n.n("already_up_to_date"))
|
||||||
|
@ -399,41 +397,6 @@ def tools_update(target=None):
|
||||||
return {"system": upgradable_system_packages, "apps": upgradable_apps}
|
return {"system": upgradable_system_packages, "apps": upgradable_apps}
|
||||||
|
|
||||||
|
|
||||||
def _list_upgradable_apps():
|
|
||||||
|
|
||||||
app_list_installed = os.listdir(APPS_SETTING_PATH)
|
|
||||||
for app_id in app_list_installed:
|
|
||||||
|
|
||||||
app_dict = app_info(app_id, full=True)
|
|
||||||
|
|
||||||
if app_dict["upgradable"] == "yes":
|
|
||||||
|
|
||||||
# FIXME : would make more sense for these infos to be computed
|
|
||||||
# directly in app_info and used to check the upgradability of
|
|
||||||
# the app...
|
|
||||||
current_version = app_dict.get("manifest", {}).get("version", "?")
|
|
||||||
current_commit = app_dict.get("settings", {}).get("current_revision", "?")[
|
|
||||||
:7
|
|
||||||
]
|
|
||||||
new_version = (
|
|
||||||
app_dict.get("from_catalog", {}).get("manifest", {}).get("version", "?")
|
|
||||||
)
|
|
||||||
new_commit = (
|
|
||||||
app_dict.get("from_catalog", {}).get("git", {}).get("revision", "?")[:7]
|
|
||||||
)
|
|
||||||
|
|
||||||
if current_version == new_version:
|
|
||||||
current_version += " (" + current_commit + ")"
|
|
||||||
new_version += " (" + new_commit + ")"
|
|
||||||
|
|
||||||
yield {
|
|
||||||
"id": app_id,
|
|
||||||
"label": app_dict["label"],
|
|
||||||
"current_version": current_version,
|
|
||||||
"new_version": new_version,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@is_unit_operation()
|
@is_unit_operation()
|
||||||
def tools_upgrade(operation_logger, target=None):
|
def tools_upgrade(operation_logger, target=None):
|
||||||
"""
|
"""
|
||||||
|
@ -466,7 +429,7 @@ def tools_upgrade(operation_logger, target=None):
|
||||||
|
|
||||||
# Make sure there's actually something to upgrade
|
# Make sure there's actually something to upgrade
|
||||||
|
|
||||||
upgradable_apps = [app["id"] for app in _list_upgradable_apps()]
|
upgradable_apps = [app["id"] for app in app_list(upgradable=True)["apps"]]
|
||||||
|
|
||||||
if not upgradable_apps:
|
if not upgradable_apps:
|
||||||
logger.info(m18n.n("apps_already_up_to_date"))
|
logger.info(m18n.n("apps_already_up_to_date"))
|
||||||
|
|
|
@ -289,6 +289,8 @@ class ConfigPanel:
|
||||||
question_class = ARGUMENTS_TYPE_PARSERS[option.get("type", "string")]
|
question_class = ARGUMENTS_TYPE_PARSERS[option.get("type", "string")]
|
||||||
# FIXME : maybe other properties should be taken from the question, not just choices ?.
|
# FIXME : maybe other properties should be taken from the question, not just choices ?.
|
||||||
option["choices"] = question_class(option).choices
|
option["choices"] = question_class(option).choices
|
||||||
|
option["default"] = question_class(option).default
|
||||||
|
option["pattern"] = question_class(option).pattern
|
||||||
else:
|
else:
|
||||||
result[key] = {"ask": ask}
|
result[key] = {"ask": ask}
|
||||||
if "current_value" in option:
|
if "current_value" in option:
|
||||||
|
@ -603,7 +605,7 @@ class ConfigPanel:
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def future_values(self): # TODO put this in ConfigPanel ?
|
def future_values(self):
|
||||||
return {**self.values, **self.new_values}
|
return {**self.values, **self.new_values}
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
@ -706,7 +708,7 @@ class Question:
|
||||||
self.ask = question.get("ask", {"en": self.name})
|
self.ask = question.get("ask", {"en": self.name})
|
||||||
self.help = question.get("help")
|
self.help = question.get("help")
|
||||||
self.redact = question.get("redact", False)
|
self.redact = question.get("redact", False)
|
||||||
self.filter = question.get("filter", "true")
|
self.filter = question.get("filter", None)
|
||||||
# .current_value is the currently stored value
|
# .current_value is the currently stored value
|
||||||
self.current_value = question.get("current_value")
|
self.current_value = question.get("current_value")
|
||||||
# .value is the "proposed" value which we got from the user
|
# .value is the "proposed" value which we got from the user
|
||||||
|
|
Loading…
Add table
Reference in a new issue