This commit is contained in:
parent
58a2231e35
commit
5cd6d42f17
38
Dockerfile
38
Dockerfile
@ -1,24 +1,28 @@
|
|||||||
FROM frolvlad/alpine-glibc
|
FROM nginx:mainline
|
||||||
ENV SEAF=/opt/seafile
|
|
||||||
|
|
||||||
RUN apk add --no-cache py-pip sqlite-dev py-mysqldb py-pillow curl bash openssl-dev libevent
|
|
||||||
|
|
||||||
COPY requirements.txt /tmp/requirements.txt
|
|
||||||
|
|
||||||
RUN pip install -r /tmp/requirements.txt
|
|
||||||
|
|
||||||
COPY conf $SEAF/
|
|
||||||
COPY scripts/upgrade.py /usr/local/sbin/upgrade
|
|
||||||
COPY scripts/seafile-server.sh /sbin/seafile-server
|
|
||||||
|
|
||||||
RUN ulimit -n 30000 && mkdir -p $SEAF/pids && rm /tmp/requirements.txt && \
|
|
||||||
chmod +x /usr/local/sbin/upgrade /sbin/seafile-server
|
|
||||||
|
|
||||||
VOLUME /opt/seafile
|
VOLUME /opt/seafile
|
||||||
|
|
||||||
EXPOSE 80 10001 12001 8000 8080 8082
|
EXPOSE 80 10001 12001 8000 8080 8082
|
||||||
|
|
||||||
# Baseimage init process
|
ENV SEAF=/opt/seafile
|
||||||
|
|
||||||
|
COPY requirements.txt /tmp/requirements.txt
|
||||||
|
|
||||||
|
RUN apt update && apt install locales -y && apt install -y --no-install-recommends procps openssl python2.7 sqlite3 python-mysqldb python-pil curl libjansson4 libfuse2 python-pip python-pip-whl python-setuptools \
|
||||||
|
&& pip install -r /tmp/requirements.txt && apt remove -y python-pip \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* /tmp/requirements.txt
|
||||||
|
|
||||||
|
COPY conf /opt/seafile/conf
|
||||||
|
COPY conf /etc/seafile
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
COPY scripts/upgrade.py /usr/local/sbin/upgrade
|
||||||
|
COPY scripts/seafile-server.sh /sbin/seafile-server
|
||||||
|
|
||||||
|
RUN ulimit -n 30000 && mkdir -p $SEAF/pids && \
|
||||||
|
chmod +x /usr/local/sbin/upgrade /sbin/seafile-server
|
||||||
|
|
||||||
|
ENV SEAF_UPGRADE_INTERVAL=3
|
||||||
|
|
||||||
ENTRYPOINT ["/sbin/seafile-server"]
|
ENTRYPOINT ["/sbin/seafile-server"]
|
||||||
#Default to run options include: run, run-upgrade, upgrade, stop, stop-upgrade
|
#Defaults to run-upgrade options include: run, run-upgrade, upgrade, stop, stop-upgrade
|
||||||
CMD ["run-upgrade"]
|
CMD ["run-upgrade"]
|
||||||
|
118
nginx.conf
118
nginx.conf
@ -2,76 +2,82 @@ events {
|
|||||||
worker_connections 12;
|
worker_connections 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid /opt/seafile/pids/nginx.pid;
|
http{
|
||||||
|
|
||||||
server {
|
upstream hub {
|
||||||
listen 80;
|
server 127.0.0.1:8000;
|
||||||
|
keepalive 2;
|
||||||
|
}
|
||||||
|
|
||||||
error_log syslog:server=unix:/dev/log;
|
upstream files {
|
||||||
access_log syslog:server=unix:/dev/log;
|
server 127.0.0.1:8082;
|
||||||
|
keepalive 4;
|
||||||
|
}
|
||||||
|
|
||||||
upstream hub {
|
upstream webdav {
|
||||||
server 127.0.0.1:8000;
|
server 127.0.0.1:8080;
|
||||||
keepalive 2;
|
keepalive 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
upstream files {
|
disable_symlinks off;
|
||||||
server 127.0.0.1:8082;
|
|
||||||
keepalive 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
upstream webdav {
|
server {
|
||||||
server 127.0.0.1:8080;
|
listen 80;
|
||||||
keepalive 2;
|
|
||||||
}
|
error_log syslog:server=unix:/dev/log;
|
||||||
|
access_log syslog:server=unix:/dev/log;
|
||||||
|
|
||||||
|
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://hub;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Host $server_name;
|
|
||||||
proxy_read_timeout 1200s;
|
|
||||||
|
|
||||||
# used for view/edit office file via Office Online Server
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
client_max_body_size 0;
|
|
||||||
|
|
||||||
}
|
location / {
|
||||||
|
proxy_pass http://hub;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
proxy_read_timeout 1200s;
|
||||||
|
|
||||||
location /seafhttp {
|
# used for view/edit office file via Office Online Server
|
||||||
rewrite ^/seafhttp(.*)$ $1 break;
|
client_max_body_size 0;
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_pass http://files;
|
|
||||||
client_max_body_size 0;
|
|
||||||
proxy_connect_timeout 3s;
|
|
||||||
proxy_read_timeout 3600s;
|
|
||||||
proxy_send_timeout 3600s;
|
|
||||||
send_timeout 3600s;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /seafdav {
|
}
|
||||||
fastcgi_pass webdav;
|
|
||||||
fastcgi_keep_conn on;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
fastcgi_param PATH_INFO $fastcgi_script_name;
|
|
||||||
|
|
||||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
location /seafhttp {
|
||||||
fastcgi_param QUERY_STRING $query_string;
|
rewrite ^/seafhttp(.*)$ $1 break;
|
||||||
fastcgi_param REQUEST_METHOD $request_method;
|
proxy_pass http://files;
|
||||||
fastcgi_param CONTENT_TYPE $content_type;
|
proxy_http_version 1.1;
|
||||||
fastcgi_param CONTENT_LENGTH $content_length;
|
client_max_body_size 0;
|
||||||
fastcgi_param SERVER_ADDR $server_addr;
|
proxy_connect_timeout 3s;
|
||||||
fastcgi_param SERVER_PORT $server_port;
|
proxy_read_timeout 3600s;
|
||||||
fastcgi_param SERVER_NAME $server_name;
|
proxy_send_timeout 3600s;
|
||||||
|
send_timeout 3600s;
|
||||||
|
}
|
||||||
|
|
||||||
client_max_body_size 0;
|
location /seafdav {
|
||||||
|
fastcgi_pass webdav;
|
||||||
|
fastcgi_keep_conn on;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_script_name;
|
||||||
|
|
||||||
}
|
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||||
|
fastcgi_param QUERY_STRING $query_string;
|
||||||
|
fastcgi_param REQUEST_METHOD $request_method;
|
||||||
|
fastcgi_param CONTENT_TYPE $content_type;
|
||||||
|
fastcgi_param CONTENT_LENGTH $content_length;
|
||||||
|
fastcgi_param SERVER_ADDR $server_addr;
|
||||||
|
fastcgi_param SERVER_PORT $server_port;
|
||||||
|
fastcgi_param SERVER_NAME $server_name;
|
||||||
|
|
||||||
|
client_max_body_size 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# location /media {
|
||||||
|
# root /opt/seafile/seafile-server-latest/seahub;
|
||||||
|
# }
|
||||||
|
}
|
||||||
|
|
||||||
location /media {
|
|
||||||
root /opt/seafile/seafile-server-latest/seahub/media/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,79 +1,165 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
LATEST=$SEAF/seafile-server-latest
|
LATEST=$SEAF/seafile-server-latest
|
||||||
PIDS=$SEAF/pids
|
PIDS=$SEAF/pids
|
||||||
|
PIDFILES=("$PIDS" "$LATEST/runtime" "/var/run/nginx")
|
||||||
|
COMMANDS=("seaf-server $LATEST/seafile.sh start" "seahub $LATEST/seahub.sh ${SEAF_HUB_MODE:-start} 8000" "nginx /usr/sbin/nginx")
|
||||||
|
|
||||||
function stop() {
|
function stop {
|
||||||
|
#Kill when hitting CTRL+C repeatedly
|
||||||
|
trap stop_kill SIGTERM
|
||||||
$0 stop
|
$0 stop
|
||||||
}
|
}
|
||||||
|
function stop_kill {
|
||||||
|
$0 kill
|
||||||
|
}
|
||||||
|
function ext_url {
|
||||||
|
echo "${SEAF_URL:-http://$(hostname)}/seafhttp"
|
||||||
|
}
|
||||||
|
function patch_seahub_conf {
|
||||||
|
KEY="FILE_SERVER_ROOT"
|
||||||
|
ENTRY="$KEY = '$(ext_url)'"
|
||||||
|
CONF="$SEAF/conf/seahub_settings.py"
|
||||||
|
grep "$KEY" -i "$CONF"
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
echo "Patched seahub_settings.py: set $ENTRY"
|
||||||
|
echo -e "\n$ENTRY" >> "$CONF"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function last_update {
|
||||||
|
if [ -e "$LATEST/install_date" ]; then
|
||||||
|
date -d $(cat "$LATEST/install_date") "+%s"
|
||||||
|
else
|
||||||
|
echo 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function pid {
|
||||||
|
for LOC in ${PIDFILES[@]}; do
|
||||||
|
if [ -e "$LOC/$1.pid" ]; then
|
||||||
|
cat "$LOC/$1.pid"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
pgrep -f "/$1"
|
||||||
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
run)
|
run)
|
||||||
if [ ! -e "$LATEST" ]; then
|
if [ ! -e "$LATEST" ]; then
|
||||||
(>&2 echo This appears to be the fist run, installing..)
|
(>&2 echo This appears to be the fist run, installing..)
|
||||||
|
mkdir -p $SEAF/conf
|
||||||
|
cp /etc/seafile/* $SEAF/conf/* -rf
|
||||||
$0 run-upgrade
|
$0 run-upgrade
|
||||||
|
exit
|
||||||
else
|
else
|
||||||
$0 manage-component seaf-server start $LATEST/seafile.sh start
|
patch_seahub_conf
|
||||||
$0 manage-component seahub start $LATEST/seahub.sh "${SEAF_HUB_MODE:-start} 8000" &
|
for CMD in "${COMMANDS[@]}"; do
|
||||||
$0 manage-component nginx start nginx &
|
INFO=($CMD)
|
||||||
|
$0 manage-component "${INFO[0]}" start "${INFO[1]}" "${INFO[@]:2}"
|
||||||
|
done
|
||||||
wait
|
wait
|
||||||
fi
|
fi
|
||||||
trap stop SIGINT SIGTERM
|
trap stop SIGINT SIGQUIT SIGTERM
|
||||||
while pgrep -f "seafile-controller" 2>&1 >/dev/null; do
|
LAST_UPGRADE=$(last_update)
|
||||||
sleep 2;
|
UPGRADE=0
|
||||||
|
while eval "$0 status > /dev/null"; do
|
||||||
|
sleep 10;
|
||||||
|
SINCE_UPGRADE=$(((($(date "+%s") - $LAST_UPGRADE))/(60*60*24)))
|
||||||
|
if [ $LAST_UPGRADE -gt 0 ] && [ "0$SEAF_UPGRADE_INTERVAL" -gt 0 ] && [ $SINCE_UPGRADE -gt "0$SEAF_UPGRADE_INTERVAL" ]; then
|
||||||
|
echo "It's been $SINCE_UPGRADE days since the last Upgrade\nSTOPPING TO PERFORM UPGRADE NOW\nSet SEAF_UPGRADE_INTERVAL=0 disable automatic updates"
|
||||||
|
UPGRADE=1
|
||||||
|
$0 stop
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
if [ $UPGRADE -eq 1 ]; then
|
||||||
|
$0 stop-upgrade-run
|
||||||
|
else
|
||||||
|
echo "Terminated"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
run-upgrade)
|
run-upgrade)
|
||||||
$0 upgrade && $0 run
|
$0 upgrade
|
||||||
|
RES=$?
|
||||||
|
if [ $RES -eq 127 ]; then
|
||||||
|
#No upgrade
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
if [ $RES -eq 126 ] && [ ! -e "$LATEST/install_date" ]; then
|
||||||
|
date +%Y-%m-%d > "$LATEST/install_date"
|
||||||
|
fi
|
||||||
|
$0 run
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
$0 manage-component seaf-server stop &
|
PIDS=""
|
||||||
$0 manage-component seahub stop &
|
for CMD in seafile-controller ccnet seafdav "${COMMANDS[@]}" seafile-controller ccnet; do
|
||||||
$0 manage-component nginx stop &
|
$0 manage-component $(echo $CMD | cut -d' ' -f1) stop &
|
||||||
$0 manage-component ccnet stop &
|
PIDS="$PIDS $!"
|
||||||
wait
|
done
|
||||||
|
wait $PIDS
|
||||||
;;
|
;;
|
||||||
stop-upgrade)
|
kill)
|
||||||
$0 stop && $0 upgrade
|
export SEAF_STOP_TRIES=0
|
||||||
|
$0 stop
|
||||||
|
;;
|
||||||
|
stop-upgrade-run)
|
||||||
|
$0 stop && $0 upgrade && $0 run
|
||||||
;;
|
;;
|
||||||
upgrade)
|
upgrade)
|
||||||
/usr/local/sbin/upgrade main
|
/usr/local/sbin/upgrade main
|
||||||
kill -SIGHUP $(pgrep -o nginx) #Reload nginx
|
kill -SIGHUP $(pgrep -o nginx) #Reload nginx
|
||||||
;;
|
;;
|
||||||
|
status)
|
||||||
|
RUNNING=1
|
||||||
|
for CMD in seafile-controller ccnet "${COMMANDS[@]}"; do
|
||||||
|
SERVICE="$(echo $CMD | cut -d' ' -f1)"
|
||||||
|
echo -n "$SERVICE: "
|
||||||
|
$0 manage-component $SERVICE status
|
||||||
|
[ $? -eq 0 ] || [ $RUNNING -eq 0 ]
|
||||||
|
RUNNING=$?
|
||||||
|
done
|
||||||
|
[ $RUNNING -eq 0 ]
|
||||||
|
;;
|
||||||
manage-component)
|
manage-component)
|
||||||
mkdir -p /var/run/seafile
|
mkdir -p /var/run/seafile
|
||||||
NAME="$2"
|
NAME="$2"
|
||||||
PIDFILE=/var/run/seafile/$NAME.pid
|
PID=$(pid $NAME)
|
||||||
case "$3" in
|
case "$3" in
|
||||||
start)
|
start)
|
||||||
CMD="$4"; ARGS="$5"
|
CMD="$4"
|
||||||
"$CMD $ARGS &"
|
ARGS="$5"
|
||||||
|
eval "$CMD $ARGS"
|
||||||
sleep 1
|
sleep 1
|
||||||
( ! "$0 $1 $NAME status") && ((>&2 echo Failed to start $NAME); exit 1)
|
( ! eval "$0 $1 $NAME status" ) && ((>&2 echo Failed to start $NAME); exit 1)
|
||||||
PID=$?
|
|
||||||
#echo $PID > /var/run/seafile/$NAME.pid
|
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
([ -e "$PIDFILE" ] && kill -0 $(cat $PIDFILE) 2> /dev/null && echo Running) || (echo Stopped && exit 1)
|
(kill -0 $PID 2> /dev/null && echo Running) || (echo Stopped && exit 1)
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
if "$0 $1 $NAME status"; then
|
QUERY="$0 $1 $NAME status > /dev/null"
|
||||||
kill $(cat $PIDFILE)
|
if eval "$QUERY"; then
|
||||||
TRIES=30
|
kill $PID
|
||||||
while "$0 $1 $NAME status"; do
|
TRIES=${SEAF_STOP_TRIES:-30}
|
||||||
|
while eval "$QUERY"; do
|
||||||
TRIES=$((TRIES - 1))
|
TRIES=$((TRIES - 1))
|
||||||
if [ $TRIES -eq 0 ]; then
|
if [ $TRIES -lt 1 ]; then
|
||||||
(>&2 echo Failed to stop $NAME)
|
(>&2 echo Failed to stop gracefully $NAME)
|
||||||
|
kill -9 $PID
|
||||||
exit 1
|
exit 1
|
||||||
|
else
|
||||||
|
kill $PID
|
||||||
|
[ $? -eq 1 ] && break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
(>&2 echo $NAME has been stopped)
|
(>&2 echo $NAME has been stopped)
|
||||||
else
|
else
|
||||||
(>&2 echo $NAME is not running)
|
(>&2 echo $NAME is not running)
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
*)
|
||||||
|
echo "You're doing wrong pal"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
|
||||||
import requests, platform, re, collections, tempfile, os, sys, shutil
|
import requests, platform, re, collections, tempfile, os, sys, shutil, math
|
||||||
from subprocess import call
|
from subprocess import call
|
||||||
|
|
||||||
version_re = "seafile-server-?_?([\d\.]*)"
|
version_re = "seafile-server-?_?([\d\.]*)"
|
||||||
@ -19,6 +19,16 @@ def available(page):
|
|||||||
available[m.group(2)] = m.group(0) #{version: link}
|
available[m.group(2)] = m.group(0) #{version: link}
|
||||||
return collections.OrderedDict(sorted(available.items(), reverse=True))
|
return collections.OrderedDict(sorted(available.items(), reverse=True))
|
||||||
|
|
||||||
|
def version_int(version):
|
||||||
|
parts=version.split('.')
|
||||||
|
rank=len(parts)
|
||||||
|
from math import pow
|
||||||
|
no=0
|
||||||
|
for p in parts:
|
||||||
|
rank=rank-1
|
||||||
|
no=no+int(p)*pow(10,rank)
|
||||||
|
return no
|
||||||
|
|
||||||
def list_command(page="https://www.seafile.com/en/download/"):
|
def list_command(page="https://www.seafile.com/en/download/"):
|
||||||
for (version, link) in available(page).items():
|
for (version, link) in available(page).items():
|
||||||
print("- %s: %s" % (version, link))
|
print("- %s: %s" % (version, link))
|
||||||
@ -30,7 +40,7 @@ def current_version_command():
|
|||||||
def current_version():
|
def current_version():
|
||||||
current = os.path.realpath(os.path.join(seaf_home, "seafile-server-latest"))
|
current = os.path.realpath(os.path.join(seaf_home, "seafile-server-latest"))
|
||||||
res = re.findall(version_re,current)
|
res = re.findall(version_re,current)
|
||||||
res[0] = "0" + res[0]
|
if len(res[0]) == 0: return '0'
|
||||||
return '.'.join(res)
|
return '.'.join(res)
|
||||||
|
|
||||||
def perform_upgrade_command(version,mysql=False,yes=True):
|
def perform_upgrade_command(version,mysql=False,yes=True):
|
||||||
@ -39,6 +49,7 @@ def perform_upgrade_command(version,mysql=False,yes=True):
|
|||||||
target = map(lambda x: int(x), version.split("."))
|
target = map(lambda x: int(x), version.split("."))
|
||||||
print len(current) == 1 and current[0] == 0
|
print len(current) == 1 and current[0] == 0
|
||||||
if len(current) == 1 and current[0] == 0: #Not installed
|
if len(current) == 1 and current[0] == 0: #Not installed
|
||||||
|
print("Running installer, please don't change any default values regarding ports.")
|
||||||
installer = os.path.join(seaf_home,"seafile-server-%s" % version,"setup-seafile%s.sh" % ("-mysql" if mysql else ""))
|
installer = os.path.join(seaf_home,"seafile-server-%s" % version,"setup-seafile%s.sh" % ("-mysql" if mysql else ""))
|
||||||
call(["sh","-c",installer],stdout=sys.stdout, stdin=sys.stdin)
|
call(["sh","-c",installer],stdout=sys.stdout, stdin=sys.stdin)
|
||||||
return 0
|
return 0
|
||||||
@ -71,7 +82,7 @@ def install_command(url):
|
|||||||
if len(current) == 1: current = current[0]
|
if len(current) == 1: current = current[0]
|
||||||
else: current = "0.0.0"
|
else: current = "0.0.0"
|
||||||
print("Upgrading from: %s -> %s" % (current, target_version))
|
print("Upgrading from: %s -> %s" % (current, target_version))
|
||||||
perform_upgrade_command(target_version)
|
perform_upgrade_command(target_version,mysql=(os.environ["SEAF_MYSQL"] or False))
|
||||||
if len(os.listdir(tmp)) != 0:
|
if len(os.listdir(tmp)) != 0:
|
||||||
print("Failed to unpack update")
|
print("Failed to unpack update")
|
||||||
os.rmdir(tmp)
|
os.rmdir(tmp)
|
||||||
@ -79,14 +90,18 @@ def install_command(url):
|
|||||||
os.rmdir(tmp)
|
os.rmdir(tmp)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
#TODO: figure out how to rename main to ""
|
||||||
def main_command(version="latest",page="https://www.seafile.com/en/download/"):
|
def main_command(version="latest",page="https://www.seafile.com/en/download/"):
|
||||||
avail = available(page)
|
avail = available(page)
|
||||||
install = None
|
install = None
|
||||||
if version == "latest":
|
if version == "latest":
|
||||||
install = avail.items()[0]
|
(install,version) = avail.items()
|
||||||
else:
|
else:
|
||||||
if version in dict(avail.items()):
|
if version in dict(avail.items()):
|
||||||
install = dict(avail.items())[version]
|
install = dict(avail.items())[version]
|
||||||
|
if version_int(current_version()) == version_int(version):
|
||||||
|
print("%s(%s) is already installed" % (version,version_int(version)))
|
||||||
|
return 1
|
||||||
if install:
|
if install:
|
||||||
print("Installing: %s" % install[1])
|
print("Installing: %s" % install[1])
|
||||||
return install_command(install[1])
|
return install_command(install[1])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user