Create snapshots functions

This commit is contained in:
Vinicius Silva 2023-05-15 22:23:11 -03:00
parent 8dcca9d8bc
commit aa09c59a56
9 changed files with 351 additions and 74 deletions

View File

@ -1,38 +1,39 @@
import uuid, os, settings, app
from settings import MAIN_REPO
from time import sleep
class Danix():
@staticmethod
def remove_snapshot(snapshot_name):
return os.system(f"rm -r {MAIN_REPO}.snapshots/{snapshot_name}")
@staticmethod
def rm(filesystem_name):
return os.system(f"rm {filesystem_name}")
return os.system(f"rm -r {MAIN_REPO}{filesystem_name}")
@staticmethod
def snapshot(filesystem_name):
return os.system(f"tar -czf /opt/danix/{filesystem_name}.tar.gz /opt/danix/{filesystem_name}")
def make_snapshot(filesystem_name, snapshot_name):
@staticmethod
def stop(filesystem_name):
os.system(f"mkdir {MAIN_REPO}.snapshots/{snapshot_name}")
resp = os.system(f"tar -czf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz {MAIN_REPO}{filesystem_name}/")
print("Wait a minute: Stoping subsystem")
resp = Danix.snapshot(filesystem_name)
os.system(f"rm -r /opt/danix/{filesystem_name}")
return resp
@staticmethod
def start(filesystem_name):
def back_snapshot(filesystem_name, snapshot_name):
print("Wait a minute: Starting subsystem")
os.system(f"mkdir /opt/danix/{filesystem_name}")
resp = os.system(f"tar -xf /opt/danix/{filesystem_name}.tar.gz -C /opt/danix/{filesystem_name} > /dev/null")
os.system(f"rm -r /opt/danix/{filesystem_name}.tar.gz > /dev/null")
return resp
os.system(f"rm -r {MAIN_REPO}{filesystem_name} > /dev/null")
resp1 = os.system(f"tar -xf {MAIN_REPO}.snapshots/{snapshot_name}/{filesystem_name}.tar.gz -C {MAIN_REPO}")
resp2 = os.system(f"mv {MAIN_REPO}/opt/danix/{filesystem_name} {MAIN_REPO}")
resp3 = os.system(f"rm -r {MAIN_REPO}opt")
return 0 if resp1+resp2+resp3 == 0 else 1
@staticmethod
def navigate(filesystem_uuid):
return os.system(f"chroot /opt/danix/{filesystem_uuid}/danixfs sh /opt/danix/init.d/init.sh")
return os.system(f"chroot {MAIN_REPO}{filesystem_uuid}/danixfs sh {MAIN_REPO}init.d/init.sh")
@staticmethod
def build_environment(packages, filesystem_uuid):
@ -42,7 +43,7 @@ class Danix():
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} /opt/danix/")
os.system(f"mv /tmp/{filesystem} {MAIN_REPO}")
print("\nPlease! Wait a moment!!")
@ -50,11 +51,12 @@ class Danix():
print(f"Installing {len(packages)} packages\n")
for package in packages:
os.system(f"chroot /opt/danix/{filesystem}/danixfs apk add {package}")
os.system(f"chroot {MAIN_REPO}{filesystem}/danixfs apk add {package}")
os.system(f"chroot /opt/danix/{filesystem}/danixfs apk add ruby")
os.system(f"chroot /opt/danix/{filesystem}/danixfs gem install lolcat")
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")
print(f"Environment builded succesfully!")
print("0 erros reported!")

View File

@ -0,0 +1,32 @@
# Generated by Django 4.2.1 on 2023-05-15 17:34
import datetime
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('db', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='environment',
name='created',
field=models.DateField(default=datetime.datetime(2023, 5, 15, 17, 34, 29, 592476)),
),
migrations.CreateModel(
name='Snapshot',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('snapshot_name', models.UUIDField()),
('created', models.DateField(default=datetime.datetime(2023, 5, 15, 17, 34, 29, 592767))),
('environment_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='db.environment')),
],
options={
'db_table': 'snapshot',
},
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.1 on 2023-05-15 18:47
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('db', '0002_alter_environment_created_snapshot'),
]
operations = [
migrations.AlterField(
model_name='environment',
name='created',
field=models.DateField(default=datetime.datetime(2023, 5, 15, 18, 47, 7, 58667)),
),
migrations.AlterField(
model_name='snapshot',
name='created',
field=models.DateField(default=datetime.datetime(2023, 5, 15, 18, 47, 7, 58959)),
),
]

View File

@ -0,0 +1,29 @@
# Generated by Django 4.2.1 on 2023-05-15 18:56
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('db', '0003_alter_environment_created_alter_snapshot_created'),
]
operations = [
migrations.AddField(
model_name='snapshot',
name='last',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='environment',
name='created',
field=models.DateField(default=datetime.datetime(2023, 5, 15, 18, 56, 13, 154851)),
),
migrations.AlterField(
model_name='snapshot',
name='created',
field=models.DateField(default=datetime.datetime(2023, 5, 15, 18, 56, 13, 155149)),
),
]

View File

@ -1,9 +1,10 @@
from django.db import models
import uuid
from danixfs import Danix
from datetime import datetime
from settings import SNAPSHOT_LIMIT
from django.core.exceptions import ValidationError
class Environment(models.Model):
filesystem_name = models.UUIDField()
status = models.BooleanField(default=True)
@ -18,14 +19,20 @@ class Environment(models.Model):
environment = Environment.objects.filter(filesystem_name=filesystem_name)
if environment.count() == 0:
print("Environment doenst exist!")
print("Environment does exist!")
exit(1)
else:
resp = Danix.navigate(filesystem_name)
if environment.first().status:
if resp != 0:
print("Error!")
resp = Danix.navigate(filesystem_name)
if resp != 0:
print("Error!")
exit(1)
else:
print("Error! The environment is spopped!")
exit(1)
except ValidationError as error:
print("Environment doenst exist!")
exit(1)
@ -36,7 +43,7 @@ class Environment(models.Model):
environment = Environment.objects.filter(filesystem_name=filesystem_name)
if environment.count() == 0:
print("Environment doesnt exist!")
print("Environment does not exist!")
exit(1)
else:
@ -54,19 +61,14 @@ class Environment(models.Model):
if environment.count() == 0:
print("Environment doesnt exist!")
print("Environment does not exist!")
exit(1)
else:
resp = Danix.start(filesystem_name)
if resp == 0:
env = environment.first()
env.status = True
env.save()
print("Environment started successfully!")
exit(0)
else:
print("Starting error!")
exit(1)
env = environment.first()
env.status = True
env.save()
print("Environment started successfully!")
exit(0)
@staticmethod
def set_active(filesystem_name):
@ -78,30 +80,26 @@ class Environment(models.Model):
@staticmethod
def stop_environment(filesystem_name):
resp = Danix.stop(filesystem_name)
environment = Environment.objects.filter(filesystem_name=filesystem_name)
if resp == 0:
environment = Environment.objects.filter(filesystem_name=filesystem_name)
if environment.count() == 0:
print("Environment doesnt exist!")
exit(1)
else:
env = environment.first()
env.status = False
env.save()
print("Environment stopped successfully!")
exit(0)
if environment.count() == 0:
print("Environment does not exist!")
exit(1)
else:
env = environment.first()
env.status = False
env.save()
print("Environment stopped successfully!")
exit(0)
@staticmethod
def list_environments():
environments = Environment.objects.all()
print("==================================================================================================================================")
print("ENVIRONMENT NAME | TEMPLATE | CREATED | CONTAINER NAME | IMAGE | STATUS")
print("==================================================================================================================================")
print("============================================================================================================================================")
print("| ENVIRONMENT NAME | TEMPLATE | CREATED | SUBSYSTEM NAME | IMAGE | STATUS | SIZE |")
print("=============================================================================================================================================")
if environments.count() > 0:
for environment in environments:
@ -113,11 +111,131 @@ class Environment(models.Model):
repeat_template = (6-len(template)) * ' '
print(f"{name[0:11]}{repeat} {template}{repeat_template} {environment.created} {environment.filesystem_name} Alpine {status_icon}")
print(f" {name[0:11]}{repeat} {template}{repeat_template} {environment.created} {environment.filesystem_name} Alpine {status_icon} 11 GB")
print("==================================================================================================================================")
print("=============================================================================================================================================")
class Meta:
db_table = "environment"
class Snapshot(models.Model):
snapshot_name = models.UUIDField()
environment_id = models.ForeignKey(Environment, null=True, on_delete=models.SET_NULL)
created = models.DateField(default=datetime.now())
last = models.BooleanField(default=True)
@staticmethod
def rm_snapshot(snapshot_name):
try:
snapshot = Snapshot.objects.filter(snapshot_name=snapshot_name)
if snapshot.count() > 0:
resp = Danix.remove_snapshot(snapshot_name)
if resp == 0:
Snapshot.objects.get(snapshot_name=snapshot_name).delete()
print("Snapshot removed successfully")
exit(0)
else:
print("Error: Snapshot can not remove")
exit(1)
else:
print("Snapshot does not exist!")
exit(1)
except ValidationError:
print("Snapshot does not exist!")
exit(1)
@staticmethod
def back_snapshot(snapshot_name):
try:
snapshot = Snapshot.objects.filter(snapshot_name=snapshot_name)
if snapshot.count() > 0:
filesystem_name = Environment.objects.filter(id=snapshot.first().environment_id.id).first().filesystem_name
resp = Danix.back_snapshot(filesystem_name, snapshot_name)
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:
print("Snapshot does not exist!")
exit(1)
@staticmethod
def create(subsystem_name):
try:
environment = Environment.objects.get(filesystem_name=subsystem_name)
environment_id = environment.id
snapshots = Snapshot.objects.filter(environment_id=environment_id)
if snapshots.count() > int(SNAPSHOT_LIMIT):
print("Snapshot limit exceeded! Please remove 1 snapshot to continue")
exit(1)
else:
for snapshot in snapshots:
snapshot.last = False
snapshot.save()
snapshot_name = uuid.uuid4()
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}")
exit(0)
else:
Snapshot.objects.get(snapshot_name=snapshot_name,environment_id=environment).delete()
print("Snapshot create error!")
exit(1)
except ValidationError:
print("Snapshot create error: Environment does not exist!")
exit(1)
@staticmethod
def list_snapshots():
snapshots = Snapshot.objects.all()
print("=========================================================================================================================================")
print("| SNAPSHOT NAME | ENVIRONMENT NAME | CREATED | LAST SNAPSHOT | SIZE |")
print("=========================================================================================================================================")
if snapshots.count() > 0:
for snapshot in snapshots:
name = str(snapshot.snapshot_name)
lastsnapshot_icon = "🟢 Yes" if snapshot.last else "🟠 No"
if snapshot.environment_id:
environment_name = Environment.objects.filter(id=snapshot.environment_id.id).first().filesystem_name
else:
repeated = 14*' '
environment_name = f'Environment Removed 🔴{repeated}'
print(f" {name} {environment_name} {snapshot.created} {lastsnapshot_icon} 11 GB")
print("==========================================================================================================================================")
class Meta:
db_table = "snapshot"
# Create your models here.

View File

@ -3,7 +3,7 @@ import app
from utils import is_root
from templates import Languanges
from db.models import Environment
from db.models import Environment, Snapshot
if not is_root():
print("Please run this program with sudo!")
@ -13,15 +13,20 @@ parser = argparse.ArgumentParser(prog="Danix", add_help=True)
usages = parser.add_argument_group("usages")
usages.add_argument("-l", "--list", action="store_true" , help="List all environments avaliable", 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("-r", "--rm", help="Remove system environment", required=False)
usages.add_argument("-n", "--navigate", help="Navigate inside the environment", 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)
createenv = parser.add_argument_group("createenv")
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("-r", "--rm", help="Remove system 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("-sc", "--snapshotcreate", help="Create snapshot", required=False)
usages.add_argument("-sb", "--snapshotback", help="Back snapshot", required=False)
usages.add_argument("-o", "--option", choices=["clike", "java", "python", "ruby"], required=False)
createenv.add_argument("-o", "--option", choices=["clike", "java", "python", "ruby"], required=False)
#fullstack_package = parser.add_argument_group("WebStack", "")
#fullstack_package.add_argument("-d","--db", type=str, required=False)
@ -49,11 +54,35 @@ if args.navigate:
if args.start:
Environment.start_environment(args.start)
if args.list:
Environment.list_environments()
if args.rm:
Environment.rm_environment(args.rm)
if args.stop:
Environment.stop_environment(args.stop)
Environment.stop_environment(args.stop)
if args.snapshotcreate:
user_confirm = input("Type 'y' to continue: ")
if user_confirm == 'y':
Snapshot.create(args.snapshotcreate)
print("[Danix]: System abort!")
if args.list:
Environment.list_environments()
if args.snapshotlist:
Snapshot.list_snapshots()
if args.snapshotback:
user_confirm = input("Type 'y' to continue: ")
if user_confirm == 'y':
Snapshot.back_snapshot(args.snapshotback)
print("[Danix]: System abort!")
if args.snapshotremove:
user_confirm = input("Type y to continue: ")
if user_confirm == 'y':
Snapshot.rm_snapshot(args.snapshotremove)
print("[Danix]: System abort!")

View File

@ -1,3 +1,3 @@
django
argparse
django-environ
django-environ

View File

@ -31,6 +31,8 @@ SECRET_KEY = 'django-insecure-emd#8q%fzc#hdb=$ursx36s=qd2)7)q#d@j*(lpzuzja6_39y4
REPO_NAME=env('REPO_NAME')
ROOT_FS=env('ROOT_FS')
SNAPSHOT_LIMIT=env("SNAPSHOT_LIMIT")
MAIN_REPO=env('MAIN_REPO')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@ -130,4 +132,4 @@ STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

View File

@ -4,7 +4,7 @@ from danixfs import Danix
class Essentials():
packages = ["fish", "vim", "nano", "micro", "git"]
packages = ["vim", "nano", "micro", "git"]
class Languanges():
@ -13,6 +13,8 @@ class Languanges():
packages = ["python3", "py3-pip"]
def install(self, environment_name, template):
packages = input("")
filesystem_name = uuid.uuid4()
environment_count = Environment.objects.filter(filesystem_name=filesystem_name).count()
@ -29,6 +31,45 @@ class Languanges():
packages = ["gcc", "g++", "clang", "rust cargo"]
def select_packages(self):
essentials_packages = Essentials().packages
i = 1
for essential in essentials_packages:
print(f'[{i}] - Package {essential}')
i += 1
print('Select essentials packages:')
print('Example: 1 2 3 to install vim, nano, and git')
essentials_packages_selected = input()
list_essentials_packages = []
for pos in essentials_packages_selected.split(" "):
list_essentials_packages.append(essentials_packages[int(pos)-1])
i = 1
for package in self.packages:
print(f"[{i}] - Package {package}")
i += 1
print('Select essentials packages:')
print('Example: 1 2 to install gcc, g++')
clike_packages_selected = input()
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
def install(self, environment_name, template):
filesystem_name = uuid.uuid4()
@ -38,7 +79,7 @@ class Languanges():
Environment.objects.create(filesystem_name=filesystem_name, template=template, name=environment_name).save()
joined_packages = self.packages + Essentials().packages
joined_packages = self.select_packages()
Environment.set_active(filesystem_name)
Danix.build_environment(joined_packages, filesystem_name)