Compare commits
68 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
da06ede555 | |
|
|
08eb84a5fc | |
|
|
06239d1edb | |
|
|
3622dde8eb | |
|
|
03a9d65e8e | |
|
|
65f01bab9e | |
|
|
cac54b5485 | |
|
|
dc5c5d2ede | |
|
|
063bc2373d | |
|
|
b3f22323af | |
|
|
36cc9f6b63 | |
|
|
e635205525 | |
|
|
63f28ac36c | |
|
|
b4dc3d04b7 | |
|
|
628a80aff0 | |
|
|
c3a87711a0 | |
|
|
404cd09e59 | |
|
|
f7b27a953c | |
|
|
22e66f6255 | |
|
|
0725e73ba4 | |
|
|
470e5ab766 | |
|
|
e7902f245f | |
|
|
3ed215ebcf | |
|
|
7936763398 | |
|
|
1dd94576cb | |
|
|
76ef136fb4 | |
|
|
80dd2e3287 | |
|
|
862c5b2b4b | |
|
|
23ee4a3eb2 | |
|
|
4874994543 | |
|
|
3b887fee42 | |
|
|
a0db883249 | |
|
|
879ae4f7ea | |
|
|
e9bcb25b23 | |
|
|
c7f0f8d486 | |
|
|
a9f7ee04b4 | |
|
|
f7e5305fea | |
|
|
ad1dd82e9c | |
|
|
2d689c4258 | |
|
|
67dcdf2631 | |
|
|
2da93a0977 | |
|
|
0e048be922 | |
|
|
0ce17668c3 | |
|
|
8f1f050946 | |
|
|
74102b0803 | |
|
|
176efae1b2 | |
|
|
56a1b2ca92 | |
|
|
a51eaa50b6 | |
|
|
9f96be7af8 | |
|
|
eefbb55f2c | |
|
|
c8936a9176 | |
|
|
fdef3b3e3a | |
|
|
abaed27575 | |
|
|
9174121cd8 | |
|
|
1409610025 | |
|
|
4e8e8161c3 | |
|
|
40c560f750 | |
|
|
e7d9fcd1d5 | |
|
|
131693af0a | |
|
|
a105eea090 | |
|
|
e2fa6afacb | |
|
|
8d170ffbb9 | |
|
|
eda8aca0c2 | |
|
|
994217f14a | |
|
|
87443c7bb4 | |
|
|
8f97d36788 | |
|
|
342e2bf1c1 | |
|
|
9ad501806a |
|
|
@ -0,0 +1,29 @@
|
||||||
|
name: Danix File System
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
continuous-integration:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: "3.10"
|
||||||
|
|
||||||
|
- name: Install danix
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd danix
|
||||||
|
sudo apt install make -y
|
||||||
|
sudo make install
|
||||||
|
sudo python /usr/share/danix/main.py --help
|
||||||
|
|
||||||
|
|
@ -6,6 +6,7 @@ __pycache__/
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
.obsidian
|
||||||
# Distribution / packaging
|
# Distribution / packaging
|
||||||
.Python
|
.Python
|
||||||
build/
|
build/
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"accentColor": ""
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"file-explorer": true,
|
|
||||||
"global-search": true,
|
|
||||||
"switcher": true,
|
|
||||||
"graph": true,
|
|
||||||
"backlink": true,
|
|
||||||
"canvas": true,
|
|
||||||
"outgoing-link": true,
|
|
||||||
"tag-pane": true,
|
|
||||||
"page-preview": true,
|
|
||||||
"daily-notes": true,
|
|
||||||
"templates": true,
|
|
||||||
"note-composer": true,
|
|
||||||
"command-palette": true,
|
|
||||||
"slash-command": false,
|
|
||||||
"editor-status": true,
|
|
||||||
"bookmarks": true,
|
|
||||||
"markdown-importer": false,
|
|
||||||
"zk-prefixer": false,
|
|
||||||
"random-note": false,
|
|
||||||
"outline": true,
|
|
||||||
"word-count": true,
|
|
||||||
"slides": false,
|
|
||||||
"audio-recorder": false,
|
|
||||||
"workspaces": false,
|
|
||||||
"file-recovery": true,
|
|
||||||
"publish": false,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
[
|
|
||||||
"file-explorer",
|
|
||||||
"global-search",
|
|
||||||
"switcher",
|
|
||||||
"graph",
|
|
||||||
"backlink",
|
|
||||||
"canvas",
|
|
||||||
"outgoing-link",
|
|
||||||
"tag-pane",
|
|
||||||
"page-preview",
|
|
||||||
"daily-notes",
|
|
||||||
"templates",
|
|
||||||
"note-composer",
|
|
||||||
"command-palette",
|
|
||||||
"editor-status",
|
|
||||||
"bookmarks",
|
|
||||||
"outline",
|
|
||||||
"word-count",
|
|
||||||
"file-recovery"
|
|
||||||
]
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
{
|
|
||||||
"main": {
|
|
||||||
"id": "683db9948478d0f5",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "a905c00f12ba46a8",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "9dc0c2825057834f",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "README.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "vertical"
|
|
||||||
},
|
|
||||||
"left": {
|
|
||||||
"id": "7e868bf1b448074e",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "8fca1960ef31b421",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "25fbe0fcd9c25fd0",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "file-explorer",
|
|
||||||
"state": {
|
|
||||||
"sortOrder": "alphabetical"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dff4013cf8dfedc3",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "search",
|
|
||||||
"state": {
|
|
||||||
"query": "",
|
|
||||||
"matchingCase": false,
|
|
||||||
"explainSearch": false,
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "83bfd13d38d5b76d",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "bookmarks",
|
|
||||||
"state": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 300
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
"id": "d0b0379d5ff97957",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "2f341c12d53e65aa",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "b32b580e05d21b5c",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "backlink",
|
|
||||||
"state": {
|
|
||||||
"file": "README.md",
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical",
|
|
||||||
"showSearch": false,
|
|
||||||
"searchQuery": "",
|
|
||||||
"backlinkCollapsed": false,
|
|
||||||
"unlinkedCollapsed": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bbfc208669b9169d",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "outgoing-link",
|
|
||||||
"state": {
|
|
||||||
"file": "README.md",
|
|
||||||
"linksCollapsed": false,
|
|
||||||
"unlinkedCollapsed": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "621cfddeb8f85c0a",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "tag",
|
|
||||||
"state": {
|
|
||||||
"sortOrder": "frequency",
|
|
||||||
"useHierarchy": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4d5cce8fb3df8ab2",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "outline",
|
|
||||||
"state": {
|
|
||||||
"file": "README.md"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 300,
|
|
||||||
"collapsed": true
|
|
||||||
},
|
|
||||||
"left-ribbon": {
|
|
||||||
"hiddenItems": {
|
|
||||||
"switcher:Open quick switcher": false,
|
|
||||||
"graph:Open graph view": false,
|
|
||||||
"canvas:Create new canvas": false,
|
|
||||||
"daily-notes:Open today's daily note": false,
|
|
||||||
"templates:Insert template": false,
|
|
||||||
"command-palette:Open command palette": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"active": "9dc0c2825057834f",
|
|
||||||
"lastOpenFiles": [
|
|
||||||
"img/logo.png",
|
|
||||||
"img/img_vi.png",
|
|
||||||
"img/img_v.png",
|
|
||||||
"img/img_iv.png",
|
|
||||||
"img/img_iii.png",
|
|
||||||
"img/img_ii.png",
|
|
||||||
"img/img_i.png",
|
|
||||||
"img",
|
|
||||||
"danix/wsgi.py",
|
|
||||||
"danix/utils.py",
|
|
||||||
"danix/templates.py",
|
|
||||||
"danix/settings.py",
|
|
||||||
"danix/requirements.txt",
|
|
||||||
"danix/manage.py",
|
|
||||||
"danix/main.py",
|
|
||||||
"danix/db/models.py",
|
|
||||||
"danix/db/migrations/__init__.py",
|
|
||||||
"Pasted image 20230516121302.png",
|
|
||||||
"README.md",
|
|
||||||
"img/img.vi.png",
|
|
||||||
"Pasted image 20230516120949.png",
|
|
||||||
"example.png.md",
|
|
||||||
"logo.png.md"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
81
README.md
81
README.md
|
|
@ -3,19 +3,13 @@
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
* Author: Vinicius F. da Silva
|
* Author: Vinicius F. da Silva
|
||||||
* Version 0.1
|
* Version 0.1.4
|
||||||
* Released: 2023
|
* Released: 2023
|
||||||
|
|
||||||
A very simple subsystem builder!
|
A very simple subsystem builder!
|
||||||
|
|
||||||
The Danixfs is a root filesystem management! Build a Alpine subsystem and pre install
|
The Danixfs is a root filesystem management! Build a Alpine subsystem and pre install
|
||||||
essentials packages and compiers from languanges choice by user:
|
essentials packages and compilers from languages choice by user:
|
||||||
|
|
||||||
Avaliable system arguments:
|
|
||||||
|
|
||||||
* "clike" : Build a C/C++ environment, installing from template with cpp, g++ and clang compilers
|
|
||||||
|
|
||||||
|
|
||||||
# Image:
|
# Image:
|
||||||
|
|
||||||
#### Building a clike environment
|
#### Building a clike environment
|
||||||
|
|
@ -30,14 +24,79 @@ Avaliable system arguments:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Run Danix
|
|
||||||
|
# Required packages
|
||||||
|
|
||||||
|
* curl 7.81.0 or higher
|
||||||
|
* tar 1.34 or higher
|
||||||
|
* python3 or higher
|
||||||
|
* pip3 or higher
|
||||||
|
* python-is-python3
|
||||||
|
# Install Danix
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ sudo make config
|
$ cd danixfs
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
To clean configuration run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo make clean
|
||||||
```
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ sudo python main.py -h
|
$ danix -h
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
# Remove Danix
|
||||||
|
|
||||||
|
To remove danix run:
|
||||||
|
```shell
|
||||||
|
$ sudo danixclean
|
||||||
|
```
|
||||||
|
# Common erros
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
To fix this problem open file *registry.py*
|
||||||
|
|
||||||
|
Search for
|
||||||
|
|
||||||
|
```python
|
||||||
|
raise RuntimeError("populate() isn't reentrant")"
|
||||||
|
```
|
||||||
|
|
||||||
|
line. And replace by following code:
|
||||||
|
|
||||||
|
```python
|
||||||
|
self.app_configs = {}
|
||||||
|
```
|
||||||
|
|
||||||
|
Save file and run
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo make aliases
|
||||||
|
```
|
||||||
|
|
||||||
|
Close terminal, open again and run
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ danix --help
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,113 @@
|
||||||
import uuid, os, settings, app
|
import os, settings, app
|
||||||
from sh import du
|
from sh import du
|
||||||
from settings import MAIN_REPO
|
from settings import MAIN_REPO
|
||||||
from time import sleep
|
from utils import download_checksum, validate_checksum
|
||||||
|
from utils import get_message, check_equal_sentence as equals, generate_checksum, remove_checksum_files
|
||||||
class Danix():
|
class Danix():
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def copy(environent_is_first, filesystem_name, environment_dir, host_directory):
|
||||||
|
|
||||||
|
if environent_is_first:
|
||||||
|
return os.system(f"cp -r {MAIN_REPO}{filesystem_name}/danixfs{environment_dir} {host_directory} >/dev/null 2>&1")
|
||||||
|
else:
|
||||||
|
return os.system(f"cp -r {host_directory} {MAIN_REPO}{filesystem_name}/danixfs{environment_dir} >/dev/null 2>&1")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_snapshot(snapshot_name):
|
def remove_snapshot(snapshot_name):
|
||||||
return os.system(f"rm -r {MAIN_REPO}.snapshots/{snapshot_name}")
|
return os.system(f"rm -r {MAIN_REPO}.snapshots/{snapshot_name} >/dev/null 2>&1")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def rm(filesystem_name):
|
def rm(filesystem_name):
|
||||||
|
|
||||||
return os.system(f"rm -r {MAIN_REPO}{filesystem_name}")
|
return os.system(f"rm -r {MAIN_REPO}{filesystem_name}")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_size(environment_name, snapshot_name):
|
def get_size(environment_name, snapshot_name):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if snapshot_name is None:
|
if snapshot_name is None:
|
||||||
return du(f'{MAIN_REPO}{environment_name}/','-ch').split('\n')[-2].split('\t')[0]
|
return du(
|
||||||
|
f'{MAIN_REPO}{environment_name}/',f'-ch',
|
||||||
|
f'--exclude={MAIN_REPO}{environment_name}/danixfs/proc/*',
|
||||||
|
f'--exclude={MAIN_REPO}{environment_name}/danixfs/dev/*',
|
||||||
|
f'--exclude={MAIN_REPO}{environment_name}/danixfs/sys/*'
|
||||||
|
).split('\n')[-2].split('\t')[0]
|
||||||
else:
|
else:
|
||||||
return du(f'{MAIN_REPO}.snapshots/{snapshot_name}/{environment_name}.tar.gz','-ch').split('\n')[-2].split('\t')[0]
|
return du(f'{MAIN_REPO}.snapshots/{snapshot_name}/{environment_name}.tar.gz','-ch').split('\n')[-2].split('\t')[0]
|
||||||
except Exception:
|
except Exception as e:
|
||||||
return "0M"
|
print(e)
|
||||||
|
return "00M"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def make_snapshot(filesystem_name, snapshot_name):
|
def make_snapshot(filesystem_name, snapshot_name):
|
||||||
|
|
||||||
os.system(f"mkdir {MAIN_REPO}.snapshots/{snapshot_name} >/dev/null 2>&1")
|
os.system(f"mkdir {MAIN_REPO}.snapshots/{snapshot_name} >/dev/null 2>&1")
|
||||||
resp = os.system(f"tar czf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz {MAIN_REPO}{filesystem_name}/ >/dev/null 2>&1")
|
exclude_proc_dir = f"{MAIN_REPO}{filesystem_name}/danixfs/proc/*"
|
||||||
|
exclude_sys_dir = f"{MAIN_REPO}{filesystem_name}/danixfs/sys/*"
|
||||||
|
exclude_dev_dir = f"{MAIN_REPO}{filesystem_name}/danixfs/dev/*"
|
||||||
|
|
||||||
|
resp = os.system(f"tar -czf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz --exclude={exclude_proc_dir} --exclude={exclude_dev_dir} --exclude={exclude_sys_dir} {MAIN_REPO}{filesystem_name}/ >/dev/null 2>&1")
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def back_snapshot(filesystem_name, snapshot_name):
|
def back_snapshot(filesystem_name, snapshot_name):
|
||||||
|
|
||||||
os.system(f"rm -r {MAIN_REPO}{filesystem_name} > /dev/null")
|
Danix.rm(filesystem_name)
|
||||||
resp1 = os.system(f"tar -xf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz -C {MAIN_REPO} >/dev/null 2>&1")
|
resp1 = os.system(f"tar -xf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz -C {MAIN_REPO} >/dev/null 2>&1")
|
||||||
resp2 = os.system(f"mv {MAIN_REPO}/opt/danix/{filesystem_name} {MAIN_REPO}")
|
resp2 = os.system(f"mv {MAIN_REPO}opt/danix/{filesystem_name} {MAIN_REPO}")
|
||||||
resp3 = os.system(f"rm -r {MAIN_REPO}opt")
|
resp3 = os.system(f"rm -r {MAIN_REPO}opt")
|
||||||
|
|
||||||
return 0 if resp1+resp2+resp3 == 0 else 1
|
return 0 if resp1+resp2+resp3 == 0 else 1
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def navigate(filesystem_uuid):
|
def navigate(filesystem_uuid):
|
||||||
|
return os.system(f"{MAIN_REPO}{filesystem_uuid}/danixfs/proot -r {MAIN_REPO}{filesystem_uuid}/danixfs/ -w / -0 -b /dev -b /sys -b /proc -b /run sh {MAIN_REPO}init.d/init.sh")
|
||||||
return os.system(f"chroot {MAIN_REPO}{filesystem_uuid}/danixfs sh {MAIN_REPO}init.d/init.sh")
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_environment(packages, filesystem_uuid):
|
def build_environment(packages, config_comands, filesystem_uuid):
|
||||||
filesystem = filesystem_uuid
|
filesystem = filesystem_uuid
|
||||||
|
|
||||||
os.system(f"mkdir /tmp/{filesystem}")
|
os.system(f"mkdir /tmp/{filesystem}")
|
||||||
os.system(f"curl --silent -LO --output-dir /tmp/{filesystem} {settings.REPO_NAME}/{settings.ROOT_FS}")
|
os.system(f"curl --silent -LO --output-dir /tmp/{filesystem} {settings.REPO_NAME}/{settings.ROOT_FS}")
|
||||||
os.system(f"tar -xf /tmp/{filesystem}/{settings.ROOT_FS} -C /tmp/{filesystem}")
|
|
||||||
os.system(f"rm /tmp/{filesystem}/{settings.ROOT_FS}")
|
|
||||||
os.system(f"mv /tmp/{filesystem} {MAIN_REPO}")
|
|
||||||
|
|
||||||
|
resp_downloaded_checksum = download_checksum()
|
||||||
|
resp_generateed_checksum = generate_checksum(f"/tmp/{filesystem}/{settings.ROOT_FS}")
|
||||||
|
|
||||||
print("\nPlease! Wait a moment!!")
|
is_downloaded_and_generate = equals(resp_downloaded_checksum, 0) and equals(resp_generateed_checksum, 0)
|
||||||
print("Building container:")
|
|
||||||
print(f"Installing {len(packages)} packages\n")
|
|
||||||
|
|
||||||
for package in packages:
|
is_valid_checksum = validate_checksum(filesystem)
|
||||||
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add {package}")
|
|
||||||
|
|
||||||
|
remove_checksum_files()
|
||||||
|
|
||||||
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add fish")
|
if is_downloaded_and_generate and is_valid_checksum:
|
||||||
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add ruby")
|
|
||||||
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs gem install lolcat")
|
|
||||||
|
|
||||||
print(f"Environment builded succesfully!")
|
os.system(f"tar -xf /tmp/{filesystem}/{settings.ROOT_FS} -C /tmp/{filesystem}")
|
||||||
print("0 erros reported!")
|
os.system(f"rm /tmp/{filesystem}/{settings.ROOT_FS}")
|
||||||
|
os.system(f"mv /tmp/{filesystem} {MAIN_REPO}")
|
||||||
|
|
||||||
Danix.navigate(filesystem)
|
print("\nPlease! Wait a moment!!")
|
||||||
|
print("Building container:")
|
||||||
|
print(f"Installing {len(packages)} packages\n")
|
||||||
|
|
||||||
|
for command in config_comands:
|
||||||
|
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs {command}")
|
||||||
|
|
||||||
|
for package in packages:
|
||||||
|
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add {package}")
|
||||||
|
|
||||||
|
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add fish")
|
||||||
|
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add ruby")
|
||||||
|
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs gem install lolcat")
|
||||||
|
|
||||||
|
os.system(f"rm -r {MAIN_REPO}{filesystem}/danixfs/dev >/dev/null 2>&1")
|
||||||
|
os.system(f"rm -r {MAIN_REPO}{filesystem}/danixfs/proc >/dev/null 2>&1")
|
||||||
|
os.system(f"rm -r {MAIN_REPO}{filesystem}/danixfs/sys >/dev/null 2>&1")
|
||||||
|
|
||||||
|
print(f"Environment builded succesfully!")
|
||||||
|
print("0 erros reported!")
|
||||||
|
|
||||||
|
Danix.navigate(filesystem)
|
||||||
|
else:
|
||||||
|
get_message("🔴 Failed integrity base image verification!", True, 1)
|
||||||
|
|
|
||||||
|
|
@ -1,121 +1,235 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import Q
|
||||||
import uuid
|
import uuid
|
||||||
|
import settings
|
||||||
from danixfs import Danix
|
from danixfs import Danix
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from settings import SNAPSHOT_LIMIT
|
from settings import SNAPSHOT_LIMIT
|
||||||
|
from utils import separate, get_size_in_mb_or_gb, print_snapshot_list_header, print_footer, print_environment_list_header, is_unique_database_tuple, get_message, check_equal_sentence, check_not_equal_sentence
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
def get_queryset_filtered(model, sub_attribute):
|
||||||
|
|
||||||
|
if model == Environment:
|
||||||
|
return model.objects.filter(filesystem_name__startswith=sub_attribute)
|
||||||
|
|
||||||
|
return model.objects.filter(snapshot_name__startswith=sub_attribute)
|
||||||
|
|
||||||
class Environment(models.Model):
|
class Environment(models.Model):
|
||||||
filesystem_name = models.UUIDField()
|
filesystem_name = models.UUIDField()
|
||||||
status = models.BooleanField(default=True)
|
status = models.BooleanField(default=True)
|
||||||
name = models.TextField()
|
name = models.TextField()
|
||||||
created = models.DateField(default=datetime.now())
|
created = models.DateField(default=datetime.now())
|
||||||
template = models.TextField(default="")
|
template = models.TextField(default="")
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def copy(path):
|
||||||
|
|
||||||
|
environent_is_first , environment_uuid, environment_dir, host_directory = separate(path)
|
||||||
|
|
||||||
|
if environment_uuid and environment_dir and host_directory:
|
||||||
|
|
||||||
|
environment = get_queryset_filtered(Environment, environment_uuid)
|
||||||
|
filesystem_name = environment.first().filesystem_name
|
||||||
|
|
||||||
|
resp = Danix.copy(
|
||||||
|
environent_is_first,
|
||||||
|
filesystem_name,
|
||||||
|
environment_dir,
|
||||||
|
host_directory
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_equal_sentence(resp, 0):
|
||||||
|
get_message("🟢 Elements copied successfuly!", True, 0)
|
||||||
|
else:
|
||||||
|
get_message("🔴 Copy error!", True, 1)
|
||||||
|
else:
|
||||||
|
if environent_is_first:
|
||||||
|
get_message(f"🔴 Syntax error or element exist in {host_directory}!", True, 1)
|
||||||
|
else:
|
||||||
|
get_message(f"🔴 Syntax error or path not exist in subsystem!", True, 1)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def navigate(filesystem_name):
|
def navigate(filesystem_name):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
environment = Environment.objects.filter(filesystem_name=filesystem_name)
|
environment = get_queryset_filtered(Environment, filesystem_name)
|
||||||
|
environments_count = environment.count()
|
||||||
|
environment_first = environment.first()
|
||||||
|
|
||||||
|
if check_equal_sentence(environments_count, 0):
|
||||||
|
|
||||||
|
get_message(message=settings.ENV_NOT_FOUND, is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
|
expression = is_unique_database_tuple(environment) and environment_first.status
|
||||||
|
|
||||||
|
if is_unique_database_tuple(environment) and environment_first.status:
|
||||||
|
resp = Danix.navigate(environment_first.filesystem_name)
|
||||||
|
|
||||||
|
if not check_not_equal_sentence(resp, 0):
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_GENERIC_ERROR}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
|
elif expression ^ (not environment_first.status):
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_STOPPED_ERROR}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
if environment.count() == 0:
|
|
||||||
print("Environment does not exist!")
|
|
||||||
exit(1)
|
|
||||||
else:
|
else:
|
||||||
if environment.first().status:
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
resp = Danix.navigate(filesystem_name)
|
except ValidationError:
|
||||||
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
if resp != 0:
|
|
||||||
print("Error!")
|
|
||||||
exit(1)
|
|
||||||
else:
|
|
||||||
print("Error! The environment is spopped!")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
except ValidationError as error:
|
|
||||||
print("Environment doenst not exist!")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def rm_environment(filesystem_name):
|
def rm_environment(filesystem_name):
|
||||||
try:
|
|
||||||
environment = Environment.objects.filter(filesystem_name=filesystem_name)
|
|
||||||
|
|
||||||
if environment.count() == 0:
|
try:
|
||||||
print("Environment does not exist!")
|
environment = get_queryset_filtered(Environment, filesystem_name)
|
||||||
exit(1)
|
|
||||||
|
if is_unique_database_tuple(environment):
|
||||||
|
|
||||||
|
environment_count = environment.count()
|
||||||
|
environment = environment.first()
|
||||||
|
|
||||||
|
if check_equal_sentence(environment_count, 0):
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_NOT_FOUND}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
|
Danix.rm(environment.filesystem_name)
|
||||||
|
environment.delete()
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🟢 {settings.ENV_REMOVED} - {environment.filesystem_name}",
|
||||||
|
is_finishprogram=False,
|
||||||
|
finish_status_code=-1
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
Danix.rm(filesystem_name)
|
get_message(
|
||||||
env = environment.first()
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
env.delete()
|
is_finishprogram=True,
|
||||||
print(f"Environment removed successfully! - {filesystem_name}")
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Environment does not exist!")
|
get_message(
|
||||||
exit(1)
|
message=f"🔴 {settings.ENV_NOT_FOUND}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_environment(filesystem_name):
|
def start_environment(filesystem_name):
|
||||||
|
|
||||||
environment = Environment.objects.filter(filesystem_name=filesystem_name)
|
environment = get_queryset_filtered(Environment, filesystem_name)
|
||||||
|
|
||||||
if environment.count() == 0:
|
if is_unique_database_tuple(environment):
|
||||||
|
|
||||||
print("Environment does not exist!")
|
environment_counter = environment.count()
|
||||||
exit(1)
|
environment = environment.first()
|
||||||
|
|
||||||
|
if check_equal_sentence(environment_counter, 0):
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🔴 {settings.ENV_NOT_FOUND}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
|
environment.status = True
|
||||||
|
environment.save()
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🟢 {settings.ENV_STARTED}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
env = environment.first()
|
get_message(
|
||||||
env.status = True
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
env.save()
|
is_finishprogram=True,
|
||||||
print("Environment started successfully!")
|
finish_status_code=1
|
||||||
exit(0)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_active(filesystem_name):
|
def set_active(filesystem_name):
|
||||||
environment = Environment.objects.filter(filesystem_name=filesystem_name).first()
|
|
||||||
|
|
||||||
|
environment = Environment.objects.filter(filesystem_name=filesystem_name).first()
|
||||||
environment.status = True
|
environment.status = True
|
||||||
environment.save()
|
environment.save()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def stop_environment(filesystem_name):
|
def stop_environment(filesystem_name):
|
||||||
|
|
||||||
|
environment = get_queryset_filtered(Environment, filesystem_name)
|
||||||
|
|
||||||
environment = Environment.objects.filter(filesystem_name=filesystem_name)
|
if is_unique_database_tuple(environment):
|
||||||
|
|
||||||
|
environment_counter = environment.count()
|
||||||
|
environment = environment.first()
|
||||||
|
|
||||||
|
if check_equal_sentence(environment_counter, 0):
|
||||||
|
|
||||||
|
get_message(message=f"🔴 {settings.ENV_NOT_FOUND}", is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
|
environment.status = False
|
||||||
|
environment.save()
|
||||||
|
|
||||||
|
get_message(message=f"🟢 {settings.ENV_STOPPED}", is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
if environment.count() == 0:
|
|
||||||
print("Environment does not exist!")
|
|
||||||
exit(1)
|
|
||||||
else:
|
else:
|
||||||
env = environment.first()
|
get_message(
|
||||||
env.status = False
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
env.save()
|
is_finishprogram=True,
|
||||||
print("Environment stopped successfully!")
|
finish_status_code=1
|
||||||
exit(0)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_environments():
|
def list_environments():
|
||||||
|
|
||||||
environments = Environment.objects.all()
|
environments = Environment.objects.all()
|
||||||
print("===============================================================================================================================================")
|
environment_counter = environments.count()
|
||||||
print("| ENVIRONMENT NAME | TEMPLATE | CREATED | SUBSYSTEM NAME | IMAGE | STATUS | SIZE |")
|
|
||||||
print("|=============================================================================================================================================|")
|
print_environment_list_header()
|
||||||
|
|
||||||
|
if environment_counter > 0:
|
||||||
|
|
||||||
if environments.count() > 0:
|
|
||||||
for environment in environments:
|
for environment in environments:
|
||||||
name = str(environment.name)
|
|
||||||
status_icon = "🟢 Running" if environment.status else "🔴 Stopped"
|
|
||||||
repeat = (11-len(name)) * '.'
|
|
||||||
|
|
||||||
|
name = str(environment.name)
|
||||||
|
|
||||||
|
status_icon = "🟢 Running" if environment.status else "🔴 Stopped"
|
||||||
template = str(environment.template)
|
template = str(environment.template)
|
||||||
|
|
||||||
repeat_template = (6-len(template)) * ' '
|
size_str = str(Danix.get_size(environment.filesystem_name, None))
|
||||||
|
|
||||||
size = Danix.get_size(environment.filesystem_name, None)
|
size_str = get_size_in_mb_or_gb(size_str)
|
||||||
print(f"| {name[0:11]}{repeat} {template}{repeat_template} {environment.created} {environment.filesystem_name} Alpine {status_icon} {size}B |")
|
|
||||||
|
|
||||||
print("===============================================================================================================================================")
|
print(f"| {name[0:11]}{(11-len(name)) * '.'} {template}{(6-len(template)) * ' '} {environment.created} {environment.filesystem_name} Alpine {status_icon} {size_str} |")
|
||||||
|
|
||||||
|
print_footer()
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -131,101 +245,133 @@ class Snapshot(models.Model):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def rm_snapshot(snapshot_name):
|
def rm_snapshot(snapshot_name):
|
||||||
try:
|
try:
|
||||||
snapshot = Snapshot.objects.filter(snapshot_name=snapshot_name)
|
snapshot = get_queryset_filtered(Snapshot, snapshot_name)
|
||||||
|
|
||||||
if snapshot.count() > 0:
|
if is_unique_database_tuple(snapshot):
|
||||||
|
|
||||||
resp = Danix.remove_snapshot(snapshot_name)
|
snapshot_counter = snapshot.count()
|
||||||
|
|
||||||
if resp == 0:
|
if snapshot_counter > 0:
|
||||||
Snapshot.objects.get(snapshot_name=snapshot_name).delete()
|
|
||||||
|
|
||||||
print(f"Snapshot removed successfully - {snapshot_name}")
|
snapshot = snapshot.first()
|
||||||
|
resp = Danix.remove_snapshot(snapshot.snapshot_name)
|
||||||
|
|
||||||
|
if check_equal_sentence(resp, 0):
|
||||||
|
|
||||||
|
Snapshot.objects.get(snapshot_name=snapshot.snapshot_name).delete()
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=f"🟢 Snapshot removed successfully - {snapshot.snapshot_name}",
|
||||||
|
is_finishprogram=False,
|
||||||
|
finish_status_code=-1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
get_message(message="🔴 Error: Snapshot can not remove", is_finishprogram=True, finish_status_code=1)
|
||||||
else:
|
else:
|
||||||
print("Error: Snapshot can not remove")
|
get_message(message="🔴 Snapshot does not exist!", is_finishprogram=True, finish_status_code=1)
|
||||||
exit(1)
|
|
||||||
else:
|
else:
|
||||||
print("Snapshot does not exist!")
|
get_message(
|
||||||
exit(1)
|
message=f"🔴 {settings.ENV_PATTERN_ERROR}",
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
print("Snapshot does not exist!")
|
get_message(message="🔴 Snapshot does not exist!", is_finishprogram=True, finish_status_code=1)
|
||||||
exit(1)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def back_snapshot(snapshot_name):
|
def back_snapshot(snapshot_name):
|
||||||
try:
|
try:
|
||||||
snapshot = Snapshot.objects.filter(snapshot_name=snapshot_name)
|
snapshot = get_queryset_filtered(Snapshot, snapshot_name)
|
||||||
|
snapshot_counter = snapshot.count()
|
||||||
|
|
||||||
if snapshot.count() > 0:
|
snapshot = snapshot.first()
|
||||||
filesystem_name = Environment.objects.filter(id=snapshot.first().environment_id.id).first().filesystem_name
|
|
||||||
|
|
||||||
resp = Danix.back_snapshot(filesystem_name, snapshot_name)
|
if snapshot_counter > 0:
|
||||||
|
|
||||||
|
if snapshot.environment_id:
|
||||||
|
filesystem_name = Environment.objects.filter(id=snapshot.environment_id.id).first().filesystem_name
|
||||||
|
|
||||||
|
resp = Danix.back_snapshot(filesystem_name, snapshot.snapshot_name)
|
||||||
|
|
||||||
|
if check_equal_sentence(resp, 0):
|
||||||
|
get_message(message="🟢 Environment roll back successfully!", is_finishprogram=True, finish_status_code=0)
|
||||||
|
get_message(message="🔴 Error: Snapshot can not back", is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
|
get_message(message="🔴 Error: Environment was removed!", is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
|
get_message(message="🔴 Snapshot does not exist!", is_finishprogram=True, finish_status_code=1)
|
||||||
|
|
||||||
if resp == 0:
|
|
||||||
print("Snapshot backed successfully")
|
|
||||||
exit(0)
|
|
||||||
else:
|
|
||||||
print("Error: Snapshot can not back")
|
|
||||||
exit(1)
|
|
||||||
else:
|
|
||||||
print("Snapshot does not exist!")
|
|
||||||
exit(1)
|
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
|
|
||||||
print("Snapshot does not exist!")
|
get_message(message="🔴 Snapshot does not exist!", is_finishprogram=True, finish_status_code=1)
|
||||||
exit(1)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(subsystem_name):
|
def create(subsystem_name):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
environment = Environment.objects.get(filesystem_name=subsystem_name)
|
|
||||||
|
|
||||||
environment_id = environment.id
|
environment = get_queryset_filtered(Environment, subsystem_name)
|
||||||
snapshots = Snapshot.objects.filter(environment_id=environment_id)
|
|
||||||
|
|
||||||
if snapshots.count() >= int(SNAPSHOT_LIMIT):
|
if is_unique_database_tuple(environment):
|
||||||
print("Snapshot limit exceeded! Please remove 1 snapshot to continue")
|
|
||||||
exit(1)
|
|
||||||
else:
|
|
||||||
|
|
||||||
for snapshot in snapshots:
|
environment = environment.first()
|
||||||
|
|
||||||
snapshot.last = False
|
environment_id = environment.id
|
||||||
snapshot.save()
|
snapshots = Snapshot.objects.filter(environment_id=environment_id)
|
||||||
|
|
||||||
snapshot_name = uuid.uuid4()
|
if snapshots.count() >= int(SNAPSHOT_LIMIT):
|
||||||
|
get_message(message="🟠 Snapshot limit exceeded! Please remove 1 snapshot to continue!", is_finishprogram=True, finish_status_code=1)
|
||||||
print('Wait a minute! Taking snapshot')
|
|
||||||
snapshot = Snapshot.objects.create(snapshot_name=snapshot_name,environment_id=environment).save()
|
|
||||||
resp = Danix.make_snapshot(subsystem_name, snapshot_name)
|
|
||||||
|
|
||||||
if resp == 0:
|
|
||||||
print("Snapshot created successfully")
|
|
||||||
print(f"Snapshot name {snapshot_name}\n")
|
|
||||||
print(f"======================================")
|
|
||||||
print(f"Environment size: {Danix.get_size(subsystem_name, None)}B")
|
|
||||||
print(f"Snapshot size: {Danix.get_size(subsystem_name, snapshot_name)}B")
|
|
||||||
print(f"======================================")
|
|
||||||
exit(0)
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
Snapshot.objects.get(snapshot_name=snapshot_name,environment_id=environment).delete()
|
for snapshot in snapshots:
|
||||||
print("Snapshot create error!")
|
|
||||||
exit(1)
|
snapshot.last = False
|
||||||
|
snapshot.save()
|
||||||
|
|
||||||
|
snapshot_name = uuid.uuid4()
|
||||||
|
|
||||||
|
print('Wait a minute! Taking snapshot')
|
||||||
|
|
||||||
|
environment_queryset = Environment.objects.get(filesystem_name=environment.filesystem_name)
|
||||||
|
|
||||||
|
snapshot = Snapshot.objects.create(snapshot_name=snapshot_name, environment_id=environment_queryset).save()
|
||||||
|
|
||||||
|
resp = Danix.make_snapshot(environment.filesystem_name, snapshot_name)
|
||||||
|
|
||||||
|
if check_equal_sentence(resp, 0):
|
||||||
|
print("🟢 Snapshot created successfully")
|
||||||
|
print(f"Snapshot name {snapshot_name}\n")
|
||||||
|
print(f"======================================")
|
||||||
|
print(f"Environment size: {Danix.get_size(environment.filesystem_name, None)}B")
|
||||||
|
print(f"Snapshot size: {Danix.get_size(environment.filesystem_name, snapshot_name)}B")
|
||||||
|
print(f"======================================")
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
|
||||||
|
Snapshot.objects.get(snapshot_name=snapshot_name,environment_id=environment).delete()
|
||||||
|
print("🔴 Snapshot create error!")
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
|
||||||
|
get_message(
|
||||||
|
message=settings.ENV_PATTERN_ERROR,
|
||||||
|
is_finishprogram=True,
|
||||||
|
finish_status_code=1
|
||||||
|
)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Snapshot create error: Environment does not exist!")
|
get_message(message="🔴 Snapshot create error: Environment does not exist!", is_finishprogram=True, finish_status_code=1)
|
||||||
exit(1)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_snapshots():
|
def list_snapshots():
|
||||||
|
|
||||||
snapshots = Snapshot.objects.all()
|
snapshots = Snapshot.objects.all()
|
||||||
|
|
||||||
print("===========================================================================================================================================")
|
print_snapshot_list_header()
|
||||||
print("| SNAPSHOT NAME | ENVIRONMENT NAME | CREATED | LAST SNAPSHOT | SIZE |")
|
|
||||||
print("|==========================================================================================================================================|")
|
|
||||||
|
|
||||||
if snapshots.count() > 0:
|
if snapshots.count() > 0:
|
||||||
for snapshot in snapshots:
|
for snapshot in snapshots:
|
||||||
|
|
@ -235,16 +381,19 @@ class Snapshot(models.Model):
|
||||||
|
|
||||||
if snapshot.environment_id:
|
if snapshot.environment_id:
|
||||||
|
|
||||||
|
|
||||||
environment_name = Environment.objects.filter(id=snapshot.environment_id.id).first().filesystem_name
|
environment_name = Environment.objects.filter(id=snapshot.environment_id.id).first().filesystem_name
|
||||||
size = Danix.get_size(environment_name, name)
|
size_str = str(Danix.get_size(environment_name, name))
|
||||||
else:
|
|
||||||
repeated = 14*' '
|
|
||||||
environment_name = f'Environment Removed 🔴{repeated}'
|
|
||||||
size = "---"
|
|
||||||
|
|
||||||
print(f"| {name} {environment_name} {snapshot.created} {lastsnapshot_icon} {size}B |")
|
size_str = get_size_in_mb_or_gb(size_str)
|
||||||
print("===========================================================================================================================================")
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
environment_name = f'Environment Removed 🔴{14*" "}'
|
||||||
|
size_str = "-----"
|
||||||
|
|
||||||
|
print(f"| {name} {environment_name} {snapshot.created} {lastsnapshot_icon} {size_str} |")
|
||||||
|
|
||||||
|
print_footer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "snapshot"
|
db_table = "snapshot"
|
||||||
|
|
|
||||||
109
danix/main.py
109
danix/main.py
|
|
@ -1,7 +1,7 @@
|
||||||
#!./venv/bin/python
|
#!./venv/bin/python
|
||||||
import argparse, os
|
import argparse, os
|
||||||
import app
|
import app
|
||||||
from utils import is_root
|
from utils import is_root, check_system_configuration
|
||||||
from templates import Languanges
|
from templates import Languanges
|
||||||
|
|
||||||
from db.models import Environment, Snapshot
|
from db.models import Environment, Snapshot
|
||||||
|
|
@ -14,19 +14,20 @@ parser = argparse.ArgumentParser(prog="Danix", add_help=True)
|
||||||
|
|
||||||
usages = parser.add_argument_group("usages")
|
usages = parser.add_argument_group("usages")
|
||||||
|
|
||||||
usages.add_argument("-l", "--list", action="store_true" , help="List all environments avaliable", required=False)
|
usages.add_argument("-l" , "--list" , action="store_true" , help="List all environments avaliable", required=False)
|
||||||
usages.add_argument("-sl", "--snapshotlist", action="store_true", help="List all subsystems snapshots", required=False)
|
usages.add_argument("-sl", "--snapshotlist", action="store_true" , help="List all subsystems snapshots", required=False)
|
||||||
|
|
||||||
usages.add_argument("-S", "--start", help="Start system environment", required=False)
|
usages.add_argument("-S", "--start" , help="Start system environment", required=False)
|
||||||
usages.add_argument("-s", "--stop", help="Stop system environment", required=False)
|
usages.add_argument("-s", "--stop" , help="Stop system environment", required=False)
|
||||||
usages.add_argument("-r", "--rm", help="Remove system environment", required=False)
|
usages.add_argument("-r", "--rm" , help="Remove system environment", required=False)
|
||||||
usages.add_argument("-n", "--navigate", help="Navigate inside the environment", required=False)
|
usages.add_argument("-n", "--navigate", help="Navigate inside the environment", required=False)
|
||||||
|
|
||||||
usages.add_argument("-sr", "--snapshotremove", help="Remove snapshot", required=False)
|
usages.add_argument("-sr", "--snapshotremove", help="Remove snapshot", required=False)
|
||||||
usages.add_argument("-sc", "--snapshotcreate", help="Create snapshot", required=False)
|
usages.add_argument("-sc", "--snapshotcreate", help="Create snapshot", required=False)
|
||||||
usages.add_argument("-sb", "--snapshotback", help="Back snapshot", required=False)
|
usages.add_argument("-sb", "--snapshotback" , help="Back snapshot", required=False)
|
||||||
|
usages.add_argument("-c", "--copy" , help="Copy files and directories", required=False)
|
||||||
|
|
||||||
usages.add_argument("-o", "--option", choices=["clike", "java", "python", "ruby"], required=False)
|
usages.add_argument("-o", "--option", choices=["clike", "java", "python", "ruby", "lua", "go", "ada", "dotnet", "v"], required=False)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
@ -34,64 +35,76 @@ languanges_and_softwares = {
|
||||||
"clike" : Languanges.CLike(),
|
"clike" : Languanges.CLike(),
|
||||||
"java" : Languanges.Java(),
|
"java" : Languanges.Java(),
|
||||||
"python" : Languanges.Python(),
|
"python" : Languanges.Python(),
|
||||||
#"ruby" : Languanges.Ruby()
|
"ruby" : Languanges.Ruby(),
|
||||||
|
"lua" : Languanges.Lua(),
|
||||||
|
"go" : Languanges.Go(),
|
||||||
|
"ada" : Languanges.Ada(),
|
||||||
|
"dotnet" : Languanges.Dotnet(),
|
||||||
|
"v" : Languanges.VLang()
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.option:
|
if check_system_configuration():
|
||||||
|
if args.option:
|
||||||
|
|
||||||
name = input("Please enter environment name: ")
|
name = input("Please enter environment name: ")
|
||||||
languanges_and_softwares.get(args.option).install(name, args.option)
|
languanges_and_softwares.get(args.option).install(name, args.option)
|
||||||
|
|
||||||
if args.navigate:
|
if args.navigate:
|
||||||
Environment.navigate(args.navigate)
|
Environment.navigate(args.navigate)
|
||||||
|
|
||||||
if args.start:
|
if args.start:
|
||||||
Environment.start_environment(args.start)
|
Environment.start_environment(args.start)
|
||||||
|
|
||||||
if args.rm:
|
if args.rm:
|
||||||
user_confirm = input("Type 'y' to continue: ")
|
user_confirm = input("Type 'y' to continue: ")
|
||||||
|
|
||||||
if user_confirm == 'y':
|
if user_confirm == 'y':
|
||||||
environments = str(args.rm).split(" ")
|
environments = str(args.rm).split(" ")
|
||||||
|
|
||||||
for environment in environments:
|
for environment in environments:
|
||||||
Environment.rm_environment(environment)
|
Environment.rm_environment(environment)
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
print("[Danix]: System abort!")
|
print("🔴 [Danix]: System abort!")
|
||||||
|
|
||||||
if args.stop:
|
if args.stop:
|
||||||
Environment.stop_environment(args.stop)
|
Environment.stop_environment(args.stop)
|
||||||
|
|
||||||
if args.snapshotcreate:
|
if args.snapshotcreate:
|
||||||
user_confirm = input("Type 'y' to continue: ")
|
user_confirm = input("Type 'y' to continue: ")
|
||||||
|
|
||||||
if user_confirm == 'y':
|
if user_confirm == 'y':
|
||||||
Snapshot.create(args.snapshotcreate)
|
Snapshot.create(args.snapshotcreate)
|
||||||
print("[Danix]: System abort!")
|
print("🔴 [Danix]: System abort!")
|
||||||
|
|
||||||
if args.list:
|
if args.list:
|
||||||
Environment.list_environments()
|
Environment.list_environments()
|
||||||
|
|
||||||
if args.snapshotlist:
|
if args.snapshotlist:
|
||||||
Snapshot.list_snapshots()
|
Snapshot.list_snapshots()
|
||||||
|
|
||||||
if args.snapshotback:
|
if args.snapshotback:
|
||||||
user_confirm = input("Type 'y' to continue: ")
|
user_confirm = input("Type 'y' to continue: ")
|
||||||
|
|
||||||
if user_confirm == 'y':
|
if user_confirm == 'y':
|
||||||
Snapshot.back_snapshot(args.snapshotback)
|
Snapshot.back_snapshot(args.snapshotback)
|
||||||
print("[Danix]: System abort!")
|
print("🔴 [Danix]: System abort!")
|
||||||
|
|
||||||
if args.snapshotremove:
|
if args.snapshotremove:
|
||||||
user_confirm = input("Type y to continue: ")
|
user_confirm = input("Type y to continue: ")
|
||||||
|
|
||||||
if user_confirm == 'y':
|
if user_confirm == 'y':
|
||||||
|
|
||||||
snapshots = str(args.snapshotremove).split(" ")
|
snapshots = str(args.snapshotremove).split(" ")
|
||||||
|
|
||||||
for snapshot in snapshots:
|
for snapshot in snapshots:
|
||||||
Snapshot.rm_snapshot(snapshot)
|
Snapshot.rm_snapshot(snapshot)
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
print("[Danix]: System abort!")
|
print("🔴 [Danix]: System abort!")
|
||||||
|
|
||||||
|
if args.copy:
|
||||||
|
Environment.copy(args.copy)
|
||||||
|
else:
|
||||||
|
print("🔴 Danix system is not configured!")
|
||||||
|
print("Plase run 'danixclean' after 'danixconfig'\n\n")
|
||||||
103
danix/makefile
103
danix/makefile
|
|
@ -4,29 +4,108 @@ SNAPSHOT_LIMIT=3
|
||||||
DB_NAME=db.sqlite3
|
DB_NAME=db.sqlite3
|
||||||
MAIN_REPO=/opt/danix/
|
MAIN_REPO=/opt/danix/
|
||||||
ROOT_FS=danixfs.tar.gz
|
ROOT_FS=danixfs.tar.gz
|
||||||
DANIX_PATH=$(shell pwd)
|
DANIX_PATH=/usr/share/danix
|
||||||
REPO_NAME=https://silvavinicius.com.br/danixfs/
|
REPO_NAME=https://silvavinicius.com.br/danixfs/
|
||||||
|
|
||||||
|
ENV_GENERIC_ERROR=Error!
|
||||||
|
ENV_NOT_FOUND=Environment does not exist!
|
||||||
|
ENV_REMOVED=Environment removed successfully!
|
||||||
|
ENV_STARTED=Environment started successfully!
|
||||||
|
ENV_STOPPED=Environment stopped successfully!
|
||||||
|
ENV_STOPPED_ERROR=Error! The environment is stopped!
|
||||||
|
ENV_PATTERN_ERROR=Environment name pattern contains in multiples environments
|
||||||
|
PYTHON_PATH := $(shell python -c "import sysconfig; print(sysconfig.get_paths()['purelib'])")
|
||||||
|
|
||||||
|
install:
|
||||||
|
|
||||||
|
ifneq ($(shell id -u), 0)
|
||||||
|
|
||||||
|
@echo "You are not root, run this target as root please"
|
||||||
|
@exit 0
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
@mkdir $(DANIX_PATH) 2>&1
|
||||||
|
@cp -r * $(DANIX_PATH) 2>&1
|
||||||
|
|
||||||
|
@mkdir $(MAIN_REPO) 2>&1
|
||||||
|
@mkdir $(MAIN_REPO)/.snapshots 2>&1
|
||||||
|
|
||||||
|
@touch $(DANIX_PATH)/.env 2>&1
|
||||||
|
|
||||||
|
@echo REPO_NAME=$(REPO_NAME) >> $(DANIX_PATH)/.env
|
||||||
|
@echo MAIN_REPO=$(MAIN_REPO) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ROOT_FS=$(ROOT_FS) >> $(DANIX_PATH)/.env
|
||||||
|
@echo SNAPSHOT_LIMIT=$(SNAPSHOT_LIMIT) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_NOT_FOUND=$(ENV_NOT_FOUND) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_GENERIC_ERROR=$(ENV_GENERIC_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STOPPED_ERROR=$(ENV_STOPPED_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_PATTERN_ERROR=$(ENV_PATTERN_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_REMOVED=$(ENV_REMOVED) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STARTED=$(ENV_STARTED) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STOPPED=$(ENV_STOPPED) >> $(DANIX_PATH)/.env
|
||||||
|
|
||||||
|
@touch $(DANIX_PATH)/db/$(DB_NAME)
|
||||||
|
@$(PIP) install -r $(DANIX_PATH)/requirements.txt
|
||||||
|
|
||||||
|
@rm -r $(PYTHON_PATH)/django/apps/registry.py
|
||||||
|
@mv $(DANIX_PATH)/registry.py $(PYTHON_PATH)/django/apps/
|
||||||
|
|
||||||
|
@$(PYTHON) $(DANIX_PATH)/manage.py migrate
|
||||||
|
|
||||||
|
@echo "Installation successfully!!! Please 'make aliases without' sudo"
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
aliases:
|
||||||
|
|
||||||
|
@touch $(HOME)/.danix_aliases
|
||||||
|
@echo "if [ -f $(HOME)/.danix_aliases ]; then" >> $(HOME)/.bashrc
|
||||||
|
@echo " . $(HOME)/.danix_aliases" >> $(HOME)/.bashrc
|
||||||
|
@echo "fi" >> $(HOME)/.bashrc
|
||||||
|
@echo alias danix="'sudo python $(DANIX_PATH)/main.py'" >> $(HOME)/.danix_aliases
|
||||||
|
@echo alias danixconfig="'make -C $(DANIX_PATH) config'" >> $(HOME)/.danix_aliases
|
||||||
|
@echo alias danixclean="'make -C $(DANIX_PATH) clean'" >> $(HOME)/.danix_aliases
|
||||||
|
|
||||||
|
|
||||||
config:
|
config:
|
||||||
|
|
||||||
@mkdir $(MAIN_REPO) > /dev/null 2>&1
|
ifneq ($(shell id -u), 0)
|
||||||
@mkdir $(MAIN_REPO)/.snapshot > /dev/null 2>&1
|
|
||||||
|
|
||||||
@echo REPO_NAME =$(REPO_NAME) >> $(DANIX_PATH)/.env
|
@echo "You are not root, run this target as root please"
|
||||||
@echo MAIN_REPO =$(MAIN_REPO) >> $(DANIX_PATH)/.env
|
@exit 0
|
||||||
@echo ROOT_FS =$(ROOT_FS) >> $(DANIX_PATH)/.env
|
|
||||||
@echo SNAPSHOT_LIMIT =$(SNAPSHOT_LIMIT) >> $(DANIX_PATH)/.env
|
else
|
||||||
|
|
||||||
|
@mkdir $(MAIN_REPO) > /dev/null 2>&1
|
||||||
|
@mkdir $(MAIN_REPO)/.snapshots > /dev/null 2>&1
|
||||||
|
|
||||||
|
@echo touch $(DANIX_PATH)/.env
|
||||||
|
|
||||||
|
@echo REPO_NAME=$(REPO_NAME) >> $(DANIX_PATH)/.env
|
||||||
|
@echo MAIN_REPO=$(MAIN_REPO) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ROOT_FS=$(ROOT_FS) >> $(DANIX_PATH)/.env
|
||||||
|
@echo SNAPSHOT_LIMIT=$(SNAPSHOT_LIMIT) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_NOT_FOUND=$(ENV_NOT_FOUND) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_GENERIC_ERROR=$(ENV_GENERIC_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STOPPED_ERROR=$(ENV_STOPPED_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_PATTERN_ERROR=$(ENV_PATTERN_ERROR) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_REMOVED=$(ENV_REMOVED) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STARTED=$(ENV_STARTED) >> $(DANIX_PATH)/.env
|
||||||
|
@echo ENV_STOPPED=$(ENV_STOPPED) >> $(DANIX_PATH)/.env
|
||||||
|
|
||||||
|
@touch $(DANIX_PATH)/db/$(DB_NAME) > /dev/null 2>&1
|
||||||
|
|
||||||
@$(PIP) install -r $(DANIX_PATH)/requirements.txt > /dev/null 2>&1
|
@$(PIP) install -r $(DANIX_PATH)/requirements.txt > /dev/null 2>&1
|
||||||
|
|
||||||
$(PYTHON) $(DANIX_PATH)/manage.py migrate
|
@$(PYTHON) $(DANIX_PATH)/manage.py migrate
|
||||||
|
|
||||||
alias danix="sudo main.py"
|
endif
|
||||||
|
|
||||||
echo Danix configured successfully! Please run danix -h!
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
||||||
|
|
||||||
@rm -r $(MAIN_REPO) > /dev/null 2>&1
|
@rm -r $(MAIN_REPO) > /dev/null 2>&1
|
||||||
@rm $(DANIX_PATH)/$(DB_NAME) > /dev/null 2>&1
|
@rm -r $(DANIX_PATH) > /dev/null 2>&1
|
||||||
echo Danix cleaned!
|
@echo Danix cleaned!
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,437 @@
|
||||||
|
import functools
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import warnings
|
||||||
|
from collections import Counter, defaultdict
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
|
||||||
|
|
||||||
|
from .config import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class Apps:
|
||||||
|
"""
|
||||||
|
A registry that stores the configuration of installed applications.
|
||||||
|
|
||||||
|
It also keeps track of models, e.g. to provide reverse relations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, installed_apps=()):
|
||||||
|
# installed_apps is set to None when creating the main registry
|
||||||
|
# because it cannot be populated at that point. Other registries must
|
||||||
|
# provide a list of installed apps and are populated immediately.
|
||||||
|
if installed_apps is None and hasattr(sys.modules[__name__], "apps"):
|
||||||
|
raise RuntimeError("You must supply an installed_apps argument.")
|
||||||
|
|
||||||
|
# Mapping of app labels => model names => model classes. Every time a
|
||||||
|
# model is imported, ModelBase.__new__ calls apps.register_model which
|
||||||
|
# creates an entry in all_models. All imported models are registered,
|
||||||
|
# regardless of whether they're defined in an installed application
|
||||||
|
# and whether the registry has been populated. Since it isn't possible
|
||||||
|
# to reimport a module safely (it could reexecute initialization code)
|
||||||
|
# all_models is never overridden or reset.
|
||||||
|
self.all_models = defaultdict(dict)
|
||||||
|
|
||||||
|
# Mapping of labels to AppConfig instances for installed apps.
|
||||||
|
self.app_configs = {}
|
||||||
|
|
||||||
|
# Stack of app_configs. Used to store the current state in
|
||||||
|
# set_available_apps and set_installed_apps.
|
||||||
|
self.stored_app_configs = []
|
||||||
|
|
||||||
|
# Whether the registry is populated.
|
||||||
|
self.apps_ready = self.models_ready = self.ready = False
|
||||||
|
# For the autoreloader.
|
||||||
|
self.ready_event = threading.Event()
|
||||||
|
|
||||||
|
# Lock for thread-safe population.
|
||||||
|
self._lock = threading.RLock()
|
||||||
|
self.loading = False
|
||||||
|
|
||||||
|
# Maps ("app_label", "modelname") tuples to lists of functions to be
|
||||||
|
# called when the corresponding model is ready. Used by this class's
|
||||||
|
# `lazy_model_operation()` and `do_pending_operations()` methods.
|
||||||
|
self._pending_operations = defaultdict(list)
|
||||||
|
|
||||||
|
# Populate apps and models, unless it's the main registry.
|
||||||
|
if installed_apps is not None:
|
||||||
|
self.populate(installed_apps)
|
||||||
|
|
||||||
|
def populate(self, installed_apps=None):
|
||||||
|
"""
|
||||||
|
Load application configurations and models.
|
||||||
|
|
||||||
|
Import each application module and then each model module.
|
||||||
|
|
||||||
|
It is thread-safe and idempotent, but not reentrant.
|
||||||
|
"""
|
||||||
|
if self.ready:
|
||||||
|
return
|
||||||
|
|
||||||
|
# populate() might be called by two threads in parallel on servers
|
||||||
|
# that create threads before initializing the WSGI callable.
|
||||||
|
with self._lock:
|
||||||
|
if self.ready:
|
||||||
|
return
|
||||||
|
|
||||||
|
# An RLock prevents other threads from entering this section. The
|
||||||
|
# compare and set operation below is atomic.
|
||||||
|
if self.loading:
|
||||||
|
# Prevent reentrant calls to avoid running AppConfig.ready()
|
||||||
|
# methods twice.
|
||||||
|
self.app_configs = {}
|
||||||
|
#raise RuntimeError("populate() isn't reentrant")
|
||||||
|
self.loading = True
|
||||||
|
|
||||||
|
# Phase 1: initialize app configs and import app modules.
|
||||||
|
for entry in installed_apps:
|
||||||
|
if isinstance(entry, AppConfig):
|
||||||
|
app_config = entry
|
||||||
|
else:
|
||||||
|
app_config = AppConfig.create(entry)
|
||||||
|
if app_config.label in self.app_configs:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"Application labels aren't unique, "
|
||||||
|
"duplicates: %s" % app_config.label
|
||||||
|
)
|
||||||
|
|
||||||
|
self.app_configs[app_config.label] = app_config
|
||||||
|
app_config.apps = self
|
||||||
|
|
||||||
|
# Check for duplicate app names.
|
||||||
|
counts = Counter(
|
||||||
|
app_config.name for app_config in self.app_configs.values()
|
||||||
|
)
|
||||||
|
duplicates = [name for name, count in counts.most_common() if count > 1]
|
||||||
|
if duplicates:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"Application names aren't unique, "
|
||||||
|
"duplicates: %s" % ", ".join(duplicates)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.apps_ready = True
|
||||||
|
|
||||||
|
# Phase 2: import models modules.
|
||||||
|
for app_config in self.app_configs.values():
|
||||||
|
app_config.import_models()
|
||||||
|
|
||||||
|
self.clear_cache()
|
||||||
|
|
||||||
|
self.models_ready = True
|
||||||
|
|
||||||
|
# Phase 3: run ready() methods of app configs.
|
||||||
|
for app_config in self.get_app_configs():
|
||||||
|
app_config.ready()
|
||||||
|
|
||||||
|
self.ready = True
|
||||||
|
self.ready_event.set()
|
||||||
|
|
||||||
|
def check_apps_ready(self):
|
||||||
|
"""Raise an exception if all apps haven't been imported yet."""
|
||||||
|
if not self.apps_ready:
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
# If "not ready" is due to unconfigured settings, accessing
|
||||||
|
# INSTALLED_APPS raises a more helpful ImproperlyConfigured
|
||||||
|
# exception.
|
||||||
|
settings.INSTALLED_APPS
|
||||||
|
raise AppRegistryNotReady("Apps aren't loaded yet.")
|
||||||
|
|
||||||
|
def check_models_ready(self):
|
||||||
|
"""Raise an exception if all models haven't been imported yet."""
|
||||||
|
if not self.models_ready:
|
||||||
|
raise AppRegistryNotReady("Models aren't loaded yet.")
|
||||||
|
|
||||||
|
def get_app_configs(self):
|
||||||
|
"""Import applications and return an iterable of app configs."""
|
||||||
|
self.check_apps_ready()
|
||||||
|
return self.app_configs.values()
|
||||||
|
|
||||||
|
def get_app_config(self, app_label):
|
||||||
|
"""
|
||||||
|
Import applications and returns an app config for the given label.
|
||||||
|
|
||||||
|
Raise LookupError if no application exists with this label.
|
||||||
|
"""
|
||||||
|
self.check_apps_ready()
|
||||||
|
try:
|
||||||
|
return self.app_configs[app_label]
|
||||||
|
except KeyError:
|
||||||
|
message = "No installed app with label '%s'." % app_label
|
||||||
|
for app_config in self.get_app_configs():
|
||||||
|
if app_config.name == app_label:
|
||||||
|
message += " Did you mean '%s'?" % app_config.label
|
||||||
|
break
|
||||||
|
raise LookupError(message)
|
||||||
|
|
||||||
|
# This method is performance-critical at least for Django's test suite.
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def get_models(self, include_auto_created=False, include_swapped=False):
|
||||||
|
"""
|
||||||
|
Return a list of all installed models.
|
||||||
|
|
||||||
|
By default, the following models aren't included:
|
||||||
|
|
||||||
|
- auto-created models for many-to-many relations without
|
||||||
|
an explicit intermediate table,
|
||||||
|
- models that have been swapped out.
|
||||||
|
|
||||||
|
Set the corresponding keyword argument to True to include such models.
|
||||||
|
"""
|
||||||
|
self.check_models_ready()
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for app_config in self.app_configs.values():
|
||||||
|
result.extend(app_config.get_models(include_auto_created, include_swapped))
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_model(self, app_label, model_name=None, require_ready=True):
|
||||||
|
"""
|
||||||
|
Return the model matching the given app_label and model_name.
|
||||||
|
|
||||||
|
As a shortcut, app_label may be in the form <app_label>.<model_name>.
|
||||||
|
|
||||||
|
model_name is case-insensitive.
|
||||||
|
|
||||||
|
Raise LookupError if no application exists with this label, or no
|
||||||
|
model exists with this name in the application. Raise ValueError if
|
||||||
|
called with a single argument that doesn't contain exactly one dot.
|
||||||
|
"""
|
||||||
|
if require_ready:
|
||||||
|
self.check_models_ready()
|
||||||
|
else:
|
||||||
|
self.check_apps_ready()
|
||||||
|
|
||||||
|
if model_name is None:
|
||||||
|
app_label, model_name = app_label.split(".")
|
||||||
|
|
||||||
|
app_config = self.get_app_config(app_label)
|
||||||
|
|
||||||
|
if not require_ready and app_config.models is None:
|
||||||
|
app_config.import_models()
|
||||||
|
|
||||||
|
return app_config.get_model(model_name, require_ready=require_ready)
|
||||||
|
|
||||||
|
def register_model(self, app_label, model):
|
||||||
|
# Since this method is called when models are imported, it cannot
|
||||||
|
# perform imports because of the risk of import loops. It mustn't
|
||||||
|
# call get_app_config().
|
||||||
|
model_name = model._meta.model_name
|
||||||
|
app_models = self.all_models[app_label]
|
||||||
|
if model_name in app_models:
|
||||||
|
if (
|
||||||
|
model.__name__ == app_models[model_name].__name__
|
||||||
|
and model.__module__ == app_models[model_name].__module__
|
||||||
|
):
|
||||||
|
warnings.warn(
|
||||||
|
"Model '%s.%s' was already registered. Reloading models is not "
|
||||||
|
"advised as it can lead to inconsistencies, most notably with "
|
||||||
|
"related models." % (app_label, model_name),
|
||||||
|
RuntimeWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Conflicting '%s' models in application '%s': %s and %s."
|
||||||
|
% (model_name, app_label, app_models[model_name], model)
|
||||||
|
)
|
||||||
|
app_models[model_name] = model
|
||||||
|
self.do_pending_operations(model)
|
||||||
|
self.clear_cache()
|
||||||
|
|
||||||
|
def is_installed(self, app_name):
|
||||||
|
"""
|
||||||
|
Check whether an application with this name exists in the registry.
|
||||||
|
|
||||||
|
app_name is the full name of the app e.g. 'django.contrib.admin'.
|
||||||
|
"""
|
||||||
|
self.check_apps_ready()
|
||||||
|
return any(ac.name == app_name for ac in self.app_configs.values())
|
||||||
|
|
||||||
|
def get_containing_app_config(self, object_name):
|
||||||
|
"""
|
||||||
|
Look for an app config containing a given object.
|
||||||
|
|
||||||
|
object_name is the dotted Python path to the object.
|
||||||
|
|
||||||
|
Return the app config for the inner application in case of nesting.
|
||||||
|
Return None if the object isn't in any registered app config.
|
||||||
|
"""
|
||||||
|
self.check_apps_ready()
|
||||||
|
candidates = []
|
||||||
|
for app_config in self.app_configs.values():
|
||||||
|
if object_name.startswith(app_config.name):
|
||||||
|
subpath = object_name[len(app_config.name) :]
|
||||||
|
if subpath == "" or subpath[0] == ".":
|
||||||
|
candidates.append(app_config)
|
||||||
|
if candidates:
|
||||||
|
return sorted(candidates, key=lambda ac: -len(ac.name))[0]
|
||||||
|
|
||||||
|
def get_registered_model(self, app_label, model_name):
|
||||||
|
"""
|
||||||
|
Similar to get_model(), but doesn't require that an app exists with
|
||||||
|
the given app_label.
|
||||||
|
|
||||||
|
It's safe to call this method at import time, even while the registry
|
||||||
|
is being populated.
|
||||||
|
"""
|
||||||
|
model = self.all_models[app_label].get(model_name.lower())
|
||||||
|
if model is None:
|
||||||
|
raise LookupError("Model '%s.%s' not registered." % (app_label, model_name))
|
||||||
|
return model
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def get_swappable_settings_name(self, to_string):
|
||||||
|
"""
|
||||||
|
For a given model string (e.g. "auth.User"), return the name of the
|
||||||
|
corresponding settings name if it refers to a swappable model. If the
|
||||||
|
referred model is not swappable, return None.
|
||||||
|
|
||||||
|
This method is decorated with lru_cache because it's performance
|
||||||
|
critical when it comes to migrations. Since the swappable settings don't
|
||||||
|
change after Django has loaded the settings, there is no reason to get
|
||||||
|
the respective settings attribute over and over again.
|
||||||
|
"""
|
||||||
|
to_string = to_string.lower()
|
||||||
|
for model in self.get_models(include_swapped=True):
|
||||||
|
swapped = model._meta.swapped
|
||||||
|
# Is this model swapped out for the model given by to_string?
|
||||||
|
if swapped and swapped.lower() == to_string:
|
||||||
|
return model._meta.swappable
|
||||||
|
# Is this model swappable and the one given by to_string?
|
||||||
|
if model._meta.swappable and model._meta.label_lower == to_string:
|
||||||
|
return model._meta.swappable
|
||||||
|
return None
|
||||||
|
|
||||||
|
def set_available_apps(self, available):
|
||||||
|
"""
|
||||||
|
Restrict the set of installed apps used by get_app_config[s].
|
||||||
|
|
||||||
|
available must be an iterable of application names.
|
||||||
|
|
||||||
|
set_available_apps() must be balanced with unset_available_apps().
|
||||||
|
|
||||||
|
Primarily used for performance optimization in TransactionTestCase.
|
||||||
|
|
||||||
|
This method is safe in the sense that it doesn't trigger any imports.
|
||||||
|
"""
|
||||||
|
available = set(available)
|
||||||
|
installed = {app_config.name for app_config in self.get_app_configs()}
|
||||||
|
if not available.issubset(installed):
|
||||||
|
raise ValueError(
|
||||||
|
"Available apps isn't a subset of installed apps, extra apps: %s"
|
||||||
|
% ", ".join(available - installed)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stored_app_configs.append(self.app_configs)
|
||||||
|
self.app_configs = {
|
||||||
|
label: app_config
|
||||||
|
for label, app_config in self.app_configs.items()
|
||||||
|
if app_config.name in available
|
||||||
|
}
|
||||||
|
self.clear_cache()
|
||||||
|
|
||||||
|
def unset_available_apps(self):
|
||||||
|
"""Cancel a previous call to set_available_apps()."""
|
||||||
|
self.app_configs = self.stored_app_configs.pop()
|
||||||
|
self.clear_cache()
|
||||||
|
|
||||||
|
def set_installed_apps(self, installed):
|
||||||
|
"""
|
||||||
|
Enable a different set of installed apps for get_app_config[s].
|
||||||
|
|
||||||
|
installed must be an iterable in the same format as INSTALLED_APPS.
|
||||||
|
|
||||||
|
set_installed_apps() must be balanced with unset_installed_apps(),
|
||||||
|
even if it exits with an exception.
|
||||||
|
|
||||||
|
Primarily used as a receiver of the setting_changed signal in tests.
|
||||||
|
|
||||||
|
This method may trigger new imports, which may add new models to the
|
||||||
|
registry of all imported models. They will stay in the registry even
|
||||||
|
after unset_installed_apps(). Since it isn't possible to replay
|
||||||
|
imports safely (e.g. that could lead to registering listeners twice),
|
||||||
|
models are registered when they're imported and never removed.
|
||||||
|
"""
|
||||||
|
if not self.ready:
|
||||||
|
raise AppRegistryNotReady("App registry isn't ready yet.")
|
||||||
|
self.stored_app_configs.append(self.app_configs)
|
||||||
|
self.app_configs = {}
|
||||||
|
self.apps_ready = self.models_ready = self.loading = self.ready = False
|
||||||
|
self.clear_cache()
|
||||||
|
self.populate(installed)
|
||||||
|
|
||||||
|
def unset_installed_apps(self):
|
||||||
|
"""Cancel a previous call to set_installed_apps()."""
|
||||||
|
self.app_configs = self.stored_app_configs.pop()
|
||||||
|
self.apps_ready = self.models_ready = self.ready = True
|
||||||
|
self.clear_cache()
|
||||||
|
|
||||||
|
def clear_cache(self):
|
||||||
|
"""
|
||||||
|
Clear all internal caches, for methods that alter the app registry.
|
||||||
|
|
||||||
|
This is mostly used in tests.
|
||||||
|
"""
|
||||||
|
# Call expire cache on each model. This will purge
|
||||||
|
# the relation tree and the fields cache.
|
||||||
|
self.get_models.cache_clear()
|
||||||
|
if self.ready:
|
||||||
|
# Circumvent self.get_models() to prevent that the cache is refilled.
|
||||||
|
# This particularly prevents that an empty value is cached while cloning.
|
||||||
|
for app_config in self.app_configs.values():
|
||||||
|
for model in app_config.get_models(include_auto_created=True):
|
||||||
|
model._meta._expire_cache()
|
||||||
|
|
||||||
|
def lazy_model_operation(self, function, *model_keys):
|
||||||
|
"""
|
||||||
|
Take a function and a number of ("app_label", "modelname") tuples, and
|
||||||
|
when all the corresponding models have been imported and registered,
|
||||||
|
call the function with the model classes as its arguments.
|
||||||
|
|
||||||
|
The function passed to this method must accept exactly n models as
|
||||||
|
arguments, where n=len(model_keys).
|
||||||
|
"""
|
||||||
|
# Base case: no arguments, just execute the function.
|
||||||
|
if not model_keys:
|
||||||
|
function()
|
||||||
|
# Recursive case: take the head of model_keys, wait for the
|
||||||
|
# corresponding model class to be imported and registered, then apply
|
||||||
|
# that argument to the supplied function. Pass the resulting partial
|
||||||
|
# to lazy_model_operation() along with the remaining model args and
|
||||||
|
# repeat until all models are loaded and all arguments are applied.
|
||||||
|
else:
|
||||||
|
next_model, *more_models = model_keys
|
||||||
|
|
||||||
|
# This will be executed after the class corresponding to next_model
|
||||||
|
# has been imported and registered. The `func` attribute provides
|
||||||
|
# duck-type compatibility with partials.
|
||||||
|
def apply_next_model(model):
|
||||||
|
next_function = partial(apply_next_model.func, model)
|
||||||
|
self.lazy_model_operation(next_function, *more_models)
|
||||||
|
|
||||||
|
apply_next_model.func = function
|
||||||
|
|
||||||
|
# If the model has already been imported and registered, partially
|
||||||
|
# apply it to the function now. If not, add it to the list of
|
||||||
|
# pending operations for the model, where it will be executed with
|
||||||
|
# the model class as its sole argument once the model is ready.
|
||||||
|
try:
|
||||||
|
model_class = self.get_registered_model(*next_model)
|
||||||
|
except LookupError:
|
||||||
|
self._pending_operations[next_model].append(apply_next_model)
|
||||||
|
else:
|
||||||
|
apply_next_model(model_class)
|
||||||
|
|
||||||
|
def do_pending_operations(self, model):
|
||||||
|
"""
|
||||||
|
Take a newly-prepared model and pass it to each function waiting for
|
||||||
|
it. This is called at the very end of Apps.register_model().
|
||||||
|
"""
|
||||||
|
key = model._meta.app_label, model._meta.model_name
|
||||||
|
for function in self._pending_operations.pop(key, []):
|
||||||
|
function(model)
|
||||||
|
|
||||||
|
|
||||||
|
apps = Apps(installed_apps=None)
|
||||||
|
|
@ -19,6 +19,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
env = environ.Env()
|
env = environ.Env()
|
||||||
|
|
||||||
MAIN_DIR = f"{BASE_DIR}/danix"
|
MAIN_DIR = f"{BASE_DIR}/danix"
|
||||||
|
|
||||||
environ.Env.read_env(os.path.join(MAIN_DIR, '.env'))
|
environ.Env.read_env(os.path.join(MAIN_DIR, '.env'))
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
|
|
@ -82,17 +83,25 @@ TEMPLATES = [
|
||||||
WSGI_APPLICATION = 'wsgi.application'
|
WSGI_APPLICATION = 'wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
ENV_NOT_FOUND=env('ENV_NOT_FOUND')
|
||||||
|
ENV_GENERIC_ERROR=env('ENV_GENERIC_ERROR')
|
||||||
|
ENV_STOPPED_ERROR=env('ENV_STOPPED_ERROR')
|
||||||
|
ENV_PATTERN_ERROR=env('ENV_PATTERN_ERROR')
|
||||||
|
ENV_REMOVED=env('ENV_REMOVED')
|
||||||
|
ENV_STARTED=env('ENV_STARTED')
|
||||||
|
ENV_STOPPED=env('ENV_STOPPED')
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': BASE_DIR / 'db.sqlite3',
|
'NAME': f"{MAIN_DIR}/db/db.sqlite3",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,103 +1,184 @@
|
||||||
import uuid, app
|
import uuid, app
|
||||||
from db.models import Environment
|
from db.models import Environment
|
||||||
from danixfs import Danix
|
from danixfs import Danix
|
||||||
|
from utils import check_equal_sentence
|
||||||
class Essentials():
|
class Essentials():
|
||||||
|
|
||||||
packages = ["vim", "nano", "micro", "git"]
|
packages = ["build-base", "vim","emacs","nano", "micro", "git"]
|
||||||
|
|
||||||
class Languanges():
|
|
||||||
|
|
||||||
class Python():
|
class Template():
|
||||||
|
|
||||||
packages = ["python3", "py3-pip"]
|
@staticmethod
|
||||||
|
def install(packages, environment_name, config_commands, template):
|
||||||
|
|
||||||
def install(self, environment_name, template):
|
filesystem_name = uuid.uuid4()
|
||||||
|
|
||||||
packages = input("")
|
environment_count = Environment.objects.filter(
|
||||||
filesystem_name = uuid.uuid4()
|
filesystem_name=filesystem_name
|
||||||
|
).count()
|
||||||
|
|
||||||
environment_count = Environment.objects.filter(filesystem_name=filesystem_name).count()
|
if check_equal_sentence(environment_count, 0):
|
||||||
|
|
||||||
if environment_count == 0:
|
Environment.objects.create(
|
||||||
Environment.objects.create(filesystem_name=filesystem_name, template=template, name=environment_name).save()
|
filesystem_name=filesystem_name,
|
||||||
|
template=template,
|
||||||
|
name=environment_name).save()
|
||||||
|
|
||||||
joined_packages = self.packages + Essentials().packages
|
joined_packages = Template.menu(packages)
|
||||||
|
|
||||||
Environment.set_active(filesystem_name)
|
Environment.set_active(filesystem_name)
|
||||||
Danix.build_environment(joined_packages, filesystem_name)
|
Danix.build_environment(joined_packages, config_commands, filesystem_name)
|
||||||
|
|
||||||
class CLike():
|
|
||||||
|
|
||||||
packages = ["gcc", "g++", "clang", "rust cargo"]
|
@staticmethod
|
||||||
|
def languange_menu(packages):
|
||||||
|
i = 1
|
||||||
|
|
||||||
def select_packages(self):
|
for package in packages:
|
||||||
|
print(f"[{i}] - Package {package}")
|
||||||
|
i += 1
|
||||||
|
|
||||||
essentials_packages = Essentials().packages
|
print('Select essentials packages:')
|
||||||
|
print(f'Example: 1 2 to install {packages[0]}, {packages[1]}')
|
||||||
|
|
||||||
i = 1
|
packages_selected = input()
|
||||||
|
|
||||||
for essential in essentials_packages:
|
list_selected_packages = []
|
||||||
|
|
||||||
print(f'[{i}] - Package {essential}')
|
try:
|
||||||
i += 1
|
|
||||||
|
|
||||||
print('Select essentials packages:')
|
for pos in packages_selected.split(" "):
|
||||||
print('Example: 1 2 3 to install vim, nano, and git')
|
list_selected_packages.append(packages[int(pos)-1])
|
||||||
essentials_packages_selected = input()
|
|
||||||
|
|
||||||
list_essentials_packages = []
|
except Exception:
|
||||||
|
|
||||||
|
print("🔴 Invalid option: Please select a valid menu option!\n")
|
||||||
|
Template.languange_menu(packages)
|
||||||
|
|
||||||
|
return list_selected_packages
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def essentials_menu():
|
||||||
|
essentials_packages = Essentials().packages
|
||||||
|
|
||||||
|
i = 1
|
||||||
|
|
||||||
|
for essential in essentials_packages:
|
||||||
|
|
||||||
|
print(f'[{i}] - Package {essential}')
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
print('Select essentials packages:')
|
||||||
|
print(f'Example: 1 2 3 to install {essentials_packages[0]}, {essentials_packages[1]}, and {essentials_packages[2]}')
|
||||||
|
essentials_packages_selected = input()
|
||||||
|
|
||||||
|
list_essentials_packages = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
for pos in essentials_packages_selected.split(" "):
|
for pos in essentials_packages_selected.split(" "):
|
||||||
list_essentials_packages.append(essentials_packages[int(pos)-1])
|
list_essentials_packages.append(essentials_packages[int(pos)-1])
|
||||||
|
|
||||||
i = 1
|
except Exception:
|
||||||
|
print("🔴 Invalid option: Please select a valid menu option!\n")
|
||||||
|
Template.essentials_menu()
|
||||||
|
|
||||||
for package in self.packages:
|
return list_essentials_packages
|
||||||
print(f"[{i}] - Package {package}")
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
print('Select essentials packages:')
|
@staticmethod
|
||||||
print('Example: 1 2 to install gcc, g++')
|
def menu(packages):
|
||||||
clike_packages_selected = input()
|
return Template.essentials_menu() + Template.languange_menu(packages)
|
||||||
|
|
||||||
list_clike_packages = []
|
|
||||||
|
|
||||||
for pos in clike_packages_selected.split(" "):
|
|
||||||
list_clike_packages.append(self.packages[int(pos)-1])
|
|
||||||
|
|
||||||
return list_essentials_packages + list_clike_packages
|
|
||||||
|
|
||||||
|
class Languanges():
|
||||||
|
|
||||||
|
class VLang():
|
||||||
|
packages = ["v"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
def install(self, environment_name, template):
|
def install(self, environment_name, template):
|
||||||
filesystem_name = uuid.uuid4()
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
environment_count = Environment.objects.filter(filesystem_name=filesystem_name).count()
|
class Python():
|
||||||
|
|
||||||
if environment_count == 0:
|
packages = ["python3 py3-pip", "python3"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
Environment.objects.create(filesystem_name=filesystem_name, template=template, name=environment_name).save()
|
def install(self, environment_name, template):
|
||||||
|
|
||||||
joined_packages = self.select_packages()
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
Environment.set_active(filesystem_name)
|
class CLike():
|
||||||
Danix.build_environment(joined_packages, filesystem_name)
|
|
||||||
|
packages = ["gcc", "g++", "clang", "rust cargo"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
|
def install(self, environment_name, template):
|
||||||
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
class Java():
|
class Java():
|
||||||
|
|
||||||
packages = ["openjdk8", "openjdk11", "openjdk17"]
|
packages = ["openjdk8", "openjdk11", "openjdk17"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
def install(self, environment_name, template):
|
def install(self, environment_name, template):
|
||||||
filesystem_name = uuid.uuid4()
|
Template.install(self.packages, environment_name, self.config_commands,template)
|
||||||
|
|
||||||
environment_count = Environment.objects.filter(filesystem_name=filesystem_name).count()
|
class Ruby():
|
||||||
|
packages = ["ruby", "ruby-full"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
if environment_count == 0:
|
def install(self, environment_name, template):
|
||||||
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
Environment.objects.create(filesystem_name=filesystem_name, template=template, name=environment_name).save()
|
|
||||||
|
|
||||||
joined_packages = self.packages + Essentials().packages
|
class Lua():
|
||||||
|
|
||||||
|
packages = ["lua5.4", "lua5.3", "lua5.2"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
|
def install(self, environment_name, template):
|
||||||
|
|
||||||
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
|
class Ada():
|
||||||
|
|
||||||
|
packages = ["gcc gcc-gnat", "gcc", "gcc-gnat"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
|
def install(self, environment_name, template):
|
||||||
|
|
||||||
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
|
|
||||||
|
class Dotnet():
|
||||||
|
|
||||||
|
package = ["dotnet7-sdk", "dotnet6-sdk"]
|
||||||
|
config_commands = [
|
||||||
|
"apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib",
|
||||||
|
"export HOME=/home/"
|
||||||
|
"export USERPROFILE=root",
|
||||||
|
]
|
||||||
|
|
||||||
|
def install(self, environment_name, template):
|
||||||
|
|
||||||
|
Template.install(self.package, environment_name,self.config_commands, template)
|
||||||
|
|
||||||
|
class Go():
|
||||||
|
|
||||||
|
packages = ["go", "musl-dev go"]
|
||||||
|
config_commands = []
|
||||||
|
|
||||||
|
config_commands = [
|
||||||
|
"export GOPATH=/root/go >/dev/null 2>&1",
|
||||||
|
"export PATH=${GOPATH}/bin:/usr/local/go/bin:$PATH >/dev/null 2>&1",
|
||||||
|
"export GOBIN=$GOROOT/bin >/dev/null 2>&1",
|
||||||
|
"mkdir -p ${GOPATH}/src ${GOPATH}/bin >/dev/null 2>&1",
|
||||||
|
"export GO111MODULE=on >/dev/null 2>&1",
|
||||||
|
"export GOCACHE=/root/go/cache >/dev/null 2>&1"
|
||||||
|
]
|
||||||
|
|
||||||
|
def install(self, environment_name, template):
|
||||||
|
Template.install(self.packages, environment_name, self.config_commands, template)
|
||||||
|
|
||||||
Environment.set_active(filesystem_name)
|
|
||||||
Danix.build_environment(joined_packages, filesystem_name)
|
|
||||||
142
danix/utils.py
142
danix/utils.py
|
|
@ -1,4 +1,146 @@
|
||||||
import os
|
import os
|
||||||
|
import sh
|
||||||
|
from settings import MAIN_REPO, MAIN_DIR, BASE_DIR, REPO_NAME
|
||||||
|
|
||||||
|
|
||||||
|
def download_checksum():
|
||||||
|
|
||||||
|
return os.system(f"curl --silent -LO --output-dir /tmp/ {REPO_NAME}danixfs.checksum")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_checksum(package_path):
|
||||||
|
os.system("touch /tmp/local_danixfs.checksum")
|
||||||
|
return os.system(f"sha256sum {package_path} >> /tmp/local_danixfs.checksum")
|
||||||
|
|
||||||
|
|
||||||
|
def remove_checksum_files():
|
||||||
|
os.system("rm /tmp/danixfs.checksum >/dev/null 2>&1")
|
||||||
|
os.system("rm /tmp/local_danixfs.checksum >/dev/null 2>&1")
|
||||||
|
|
||||||
|
def read_line(file_path):
|
||||||
|
file = open(file_path, 'r')
|
||||||
|
checksum = file.readlines()
|
||||||
|
return checksum
|
||||||
|
|
||||||
|
def validate_checksum(filesystem):
|
||||||
|
|
||||||
|
remote_checksum = ''.join(read_line(f"/tmp/danixfs.checksum")).replace(f"/tmp/{filesystem}/", "")
|
||||||
|
local_checksum = ''.join(read_line(f"/tmp/local_danixfs.checksum")).replace(f"/tmp/{filesystem}/", "")
|
||||||
|
|
||||||
|
return True if local_checksum == remote_checksum else False
|
||||||
|
|
||||||
|
def separate(path):
|
||||||
|
list_path = path.split(" ")
|
||||||
|
|
||||||
|
environment_path = None
|
||||||
|
environment_uuid = None
|
||||||
|
host_path = None
|
||||||
|
environent_is_first = False
|
||||||
|
|
||||||
|
if len(list_path) >= 2:
|
||||||
|
|
||||||
|
if list_path[1]:
|
||||||
|
if str(list_path[1]).__contains__(":"):
|
||||||
|
|
||||||
|
environment_uuid = list_path[1].split(":")[0]
|
||||||
|
environment_path = list_path[1].split(":")[1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
host_path = list_path[1]
|
||||||
|
|
||||||
|
if list_path[0]:
|
||||||
|
|
||||||
|
if str(list_path[0]).__contains__(":"):
|
||||||
|
|
||||||
|
environent_is_first = True
|
||||||
|
environment_uuid = list_path[0].split(":")[0]
|
||||||
|
environment_path = list_path[0].split(":")[1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
host_path = list_path[0]
|
||||||
|
|
||||||
|
return environent_is_first, environment_uuid, environment_path, host_path
|
||||||
|
|
||||||
|
def check_create_dir():
|
||||||
|
mainrepo_resp = os.system(f"cd {MAIN_REPO} >/dev/null 2>&1")
|
||||||
|
snapshot_resp = os.system(f" cd {MAIN_REPO}.snapshots >/dev/null 2>&1")
|
||||||
|
|
||||||
|
return True if mainrepo_resp == 0 and snapshot_resp == 0 else False
|
||||||
|
|
||||||
|
def check_create_db():
|
||||||
|
return True if os.system(f"cat {MAIN_DIR}/db/db.sqlite3 >/dev/null 2>&1") == 0 else False
|
||||||
|
|
||||||
|
def check_create_dotenv():
|
||||||
|
return True if os.system(f"cat {BASE_DIR}/danix/.env >/dev/null 2>&1") == 0 else False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_system_configuration():
|
||||||
|
|
||||||
|
check_dir_resp = check_create_dir()
|
||||||
|
check_db_resp = check_create_db()
|
||||||
|
check_env_resp = check_create_dotenv()
|
||||||
|
|
||||||
|
return check_dir_resp and check_db_resp and check_env_resp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def print_footer():
|
||||||
|
print("================================================================================================================================================")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_size_in_mb_or_gb(size_str):
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
size = int(size_str.replace("M","").replace(",","."))
|
||||||
|
|
||||||
|
if size >= 1000:
|
||||||
|
|
||||||
|
return f"{round(size/1000, 1)}GB"
|
||||||
|
elif size <= 100:
|
||||||
|
|
||||||
|
return size_str + "B "
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
return size_str.replace(",",".") + "B"
|
||||||
|
|
||||||
|
return size_str + "B"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def print_snapshot_list_header():
|
||||||
|
print("================================================================================================================================================")
|
||||||
|
print("| SNAPSHOT NAME | ENVIRONMENT NAME | CREATED | LAST SNAPSHOT | SIZE |")
|
||||||
|
print("|==============================================================================================================================================|")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def print_environment_list_header():
|
||||||
|
print("================================================================================================================================================")
|
||||||
|
print("| ENVIRONMENT NAME | TEMPLATE | CREATED | SUBSYSTEM NAME | IMAGE | STATUS | SIZE |")
|
||||||
|
print("|==============================================================================================================================================|")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_equal_sentence(left_expression, right_expression):
|
||||||
|
|
||||||
|
return left_expression == right_expression
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_not_equal_sentence(left_expression, right_expression):
|
||||||
|
return left_expression == right_expression
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_unique_database_tuple(model_queryset):
|
||||||
|
|
||||||
|
if model_queryset.count() == 0:
|
||||||
|
return Exception
|
||||||
|
|
||||||
|
return True if model_queryset.count() == 1 else False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_message(message, is_finishprogram, finish_status_code):
|
||||||
|
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
if is_finishprogram:
|
||||||
|
exit(finish_status_code)
|
||||||
|
|
||||||
def is_root():
|
def is_root():
|
||||||
return True if os.geteuid() == 0 else False
|
return True if os.geteuid() == 0 else False
|
||||||
BIN
danixfs.tar.gz
BIN
danixfs.tar.gz
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
Loading…
Reference in New Issue