add python framework with basic routines
This commit is contained in:
parent
6a8907c89c
commit
11de31c1b9
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
Session.vim
|
Session.vim
|
||||||
|
__pycache__
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
# roadmap
|
# roadmap
|
||||||
- [x] virtualenv
|
- [x] virtualenv
|
||||||
- [x] git repo
|
- [x] git repo
|
||||||
- [ ] implement config file
|
- [x] how to make a daemon?
|
||||||
- [ ] how to make a daemon?
|
|
||||||
- [ ] get argparse working
|
- [ ] get argparse working
|
||||||
|
- [ ] implement config file
|
||||||
- [ ] model default system
|
- [ ] model default system
|
||||||
- [ ] list / add / edit / delete operating systems
|
- [ ] list / add / edit / delete operating systems
|
||||||
- [ ] model -> storage -> bool overwrite_always false
|
- [ ] model -> storage -> bool overwrite_always false
|
||||||
|
|
||||||
# cli
|
# cli
|
||||||
|
./quickos os storage
|
||||||
|
os: operating_system
|
||||||
|
storage: storage where to flash the os
|
||||||
- install a system (arch, ubuntu, debian, suse, etc.) to a stick
|
- install a system (arch, ubuntu, debian, suse, etc.) to a stick
|
||||||
- list / add / edit / delete operating systems
|
- list / add / edit / delete operating systems
|
||||||
|
|
||||||
@ -25,3 +28,5 @@
|
|||||||
- string label
|
- string label
|
||||||
- string uuid
|
- string uuid
|
||||||
[- bool overwrite_always false]
|
[- bool overwrite_always false]
|
||||||
|
|
||||||
|
|
||||||
|
1
__init__.py
Normal file
1
__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
all = ['pyf']
|
BIN
__pycache__/pyf.cpython-35.pyc
Normal file
BIN
__pycache__/pyf.cpython-35.pyc
Normal file
Binary file not shown.
11
database.txt
Normal file
11
database.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"raspbian": {
|
||||||
|
"file_url":"https://downloads.raspberrypi.org/raspbian_latest",
|
||||||
|
"test_url":"http://downloads.raspberrypi.org/raspbian/release_notes.txt",
|
||||||
|
"interval":"5",
|
||||||
|
"file_name": "",
|
||||||
|
"test_name":"",
|
||||||
|
"test_sha256":"",
|
||||||
|
"last_check":""
|
||||||
|
}
|
||||||
|
}
|
37
index.html
Normal file
37
index.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>willipink</title>
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
|
<meta name="msapplication-TileColor" content="#ffffff">
|
||||||
|
<meta name="msapplication-TileImage" content="/favicon/ms-icon-144x144.png">
|
||||||
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
|
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-icon-76x76.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-icon-114x114.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-icon-120x120.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-icon-144x144.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-icon-152x152.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-icon-180x180.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="192x192" href="/favicon/android-icon-192x192.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/favicon/manifest.json">
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/styles.css">
|
||||||
|
|
||||||
|
<base target="_parent">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<iframe src="navi.html"></iframe>
|
||||||
|
<p>Hello world!</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
31
pyf.py
Normal file
31
pyf.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
''' pyf - a simple python framework '''
|
||||||
|
|
||||||
|
import os
|
||||||
|
WORKDIR = os.getcwd()
|
||||||
|
|
||||||
|
|
||||||
|
def prt(message):
|
||||||
|
''' print a message with style '''
|
||||||
|
print('::: {}'.format(message))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def download(url, file_name, progress=True):
|
||||||
|
''' download a given url to a file
|
||||||
|
@return the absolute filename
|
||||||
|
'''
|
||||||
|
from urllib.request import urlretrieve
|
||||||
|
if progress:
|
||||||
|
from tqdm import tqdm
|
||||||
|
prt('downloading {}'.format(url))
|
||||||
|
file_name = '{}/{}'.format(WORKDIR, url.split('/')[-1])
|
||||||
|
class TqdmUpTo(tqdm):
|
||||||
|
def update_to(self, b=1, bsize=1, tsize=None):
|
||||||
|
if tsize is not None:
|
||||||
|
self.total = tsize
|
||||||
|
self.update(b * bsize - self.n)
|
||||||
|
|
||||||
|
with TqdmUpTo(unit='B', unit_scale=True, miniters=1, desc=file_name) as t:
|
||||||
|
urlretrieve(url, filename=file_name, reporthook=t.update_to)
|
||||||
|
else:
|
||||||
|
urlretrieve(url, filename=file_name)
|
101
quickos.py
Executable file
101
quickos.py
Executable file
@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
import daemon
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from pyf import download, prt
|
||||||
|
|
||||||
|
WORKDIR = os.getcwd()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TMP = '/tmp/quickos.log'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def init_parser():
|
||||||
|
''' initialize the argument parser
|
||||||
|
@return agrs: the parsed arguments
|
||||||
|
'''
|
||||||
|
parser = argparse.ArgumentParser(description='flash linux operating systems on the fly')
|
||||||
|
parser.add_argument('os',
|
||||||
|
default='arch',
|
||||||
|
metavar='os',
|
||||||
|
help='the operating system that should be flashed')
|
||||||
|
parser.add_argument('storage',
|
||||||
|
metavar='storage',
|
||||||
|
help='the storage where the os shall be flashed')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
''' write to logfile TMP
|
||||||
|
@param message: the message which shall be written to the log file
|
||||||
|
'''
|
||||||
|
with open(TMP, 'a') as f:
|
||||||
|
f.write('{} {}\n'.format(time.ctime(), message))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# algo check if new version should be downloaded
|
||||||
|
# a: is image file there?
|
||||||
|
# -> no: download image file
|
||||||
|
# -> yes: goto b
|
||||||
|
#
|
||||||
|
# b: is the age of the file older than *today* - *interval*
|
||||||
|
# -> no: break
|
||||||
|
# -> yes: goto c
|
||||||
|
#
|
||||||
|
# c: is there a *testfile_sha256* sum?
|
||||||
|
# -> no: download image file
|
||||||
|
# -> yes: goto d
|
||||||
|
#
|
||||||
|
# d: download testfile
|
||||||
|
# is sha256 sum of testfile and *testfile_sha256* equivalent?
|
||||||
|
# -> no: download image file
|
||||||
|
# -> yes: break
|
||||||
|
def check_update(database):
|
||||||
|
''' check if update is necessary '''
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from os import path
|
||||||
|
for name, ops in database.items():
|
||||||
|
prt('checking operating system {} ...'.format(name))
|
||||||
|
|
||||||
|
if ops['file_name'] == '':
|
||||||
|
file_name = urlparse(ops['file_url'])
|
||||||
|
file_name = file_name.path
|
||||||
|
file_name = path.basename(file_name)
|
||||||
|
print(file_name)
|
||||||
|
download(ops['file_url'], file_name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def read_os_database():
|
||||||
|
''' read the os database.txt file
|
||||||
|
@return a json object of the database
|
||||||
|
'''
|
||||||
|
with open('{}/database.txt'.format(WORKDIR), 'r') as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# https://stackoverflow.com/questions/4637420/efficient-python-daemon#8375012
|
||||||
|
def run_daemon():
|
||||||
|
''' run the daemon '''
|
||||||
|
with daemon.DaemonContext():
|
||||||
|
check_update()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = init_parser()
|
||||||
|
database = read_os_database()
|
||||||
|
check_update(database)
|
||||||
|
# run_daemon()
|
Loading…
x
Reference in New Issue
Block a user