Commit e29445a8 authored by Oleg Borisenko's avatar Oleg Borisenko
Browse files

restore models + alembic

parent e7605d11
"""restore
Revision ID: 9d586b037818
Revises:
Create Date: 2021-06-15 06:03:31.831568
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '9d586b037818'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('restoretarget',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('unique_label', sa.VARCHAR(length=64), nullable=True),
sa.Column('enabled', sa.Boolean(), nullable=True),
sa.Column('fullpath', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('id', name=op.f('pk_restoretarget'))
)
op.create_table('restorehistory',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('file_to_restore_id', sa.BIGINT(), nullable=True),
sa.Column('restore_target_id', sa.Integer(), nullable=True),
sa.Column('restored_at_time', sa.DateTime(), nullable=True),
sa.Column('status', sa.Boolean(), nullable=True),
sa.ForeignKeyConstraint(['file_to_restore_id'], ['files_to_backup.id'], name=op.f('fk_restorehistory_file_to_restore_id_files_to_backup')),
sa.ForeignKeyConstraint(['restore_target_id'], ['restoretarget.id'], name=op.f('fk_restorehistory_restore_target_id_restoretarget')),
sa.PrimaryKeyConstraint('id', name=op.f('pk_restorehistory'))
)
op.create_index('restore_history_index', 'restorehistory', ['status'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('restore_history_index', table_name='restorehistory')
op.drop_table('restorehistory')
op.drop_table('restoretarget')
# ### end Alembic commands ###
......@@ -10,6 +10,8 @@ from .tape import TapeState
from .file_to_backup import FileToBackup
from .file_to_backup import FidSeq
from .backuptarget import BackupTarget
from .restoretarget import RestoreTarget
from .restorehistory import RestoreHistory
from .batch import Batch
from .meta import BatchStatus
from .meta import DataKind
......
......@@ -43,6 +43,7 @@ class FileToBackup(Base):
back_populates="files_to_backup")
# batches = association_proxy("CopyQueue", "file_to_backup", creator=lambda file_to_back: CopyQueue(file_to_backup=file_to_back))
relative_path = Column(Text, primary_key=True) # filepath suffix after backup target fullpath
restored_to = relationship("RestoreHistory", back_populates='file_to_restore')
def to_dict(self):
return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}
......
import datetime
from sqlalchemy import (
Column,
VARCHAR,
Boolean,
Integer,
BIGINT,
DateTime,
ForeignKey,
Index
)
import logging
from tapebackup import utils
from sqlalchemy.orm import relationship
log = logging.getLogger(__name__)
from .meta import Base
class RestoreHistory(Base):
__tablename__ = 'restorehistory'
id = Column(Integer, primary_key=True)
file_to_restore_id = Column(BIGINT, ForeignKey('files_to_backup.id'))
file_to_restore = relationship("FileToBackup", back_populates='restored_to')
restore_target_id = Column(Integer, ForeignKey('restoretarget.id'))
restore_target = relationship('RestoreTarget', back_populates='restored_to')
restored_at_time = Column(DateTime)
status = Column(Boolean) #False - not restored, True - restored
def restore(self, mountpoint):
restoring = self.file_to_restore
checksum = restoring.checksum
src = mountpoint + restoring.relative_path
dest = self.restore_target.fullpath + restoring.relative_path
log.debug("Source: %s, destination: %s", src, dest)
copy_result = utils.secure_copy(src, dest)
if copy_result == 0:
self.status = True
self.restored_at_time = datetime.datetime.now()
log.info("Restored successfully %s", restoring.relative_path)
return True
else:
log.warning("Restoration %s failed, status %d", restoring.relative_path, copy_result)
return False
Index('restore_history_index', RestoreHistory.status, unique=False)
from sqlalchemy import (
Column,
VARCHAR,
Boolean,
Integer,
Text
)
import logging
from sqlalchemy.orm import relationship
log = logging.getLogger(__name__)
from .meta import Base
class RestoreTarget(Base):
__tablename__ = 'restoretarget'
id = Column(Integer, primary_key=True)
unique_label = Column(VARCHAR(64))
enabled = Column(Boolean)
fullpath = Column(Text) # it's meant to be local mount fullpath
restored_to = relationship("RestoreHistory", back_populates='restore_target')
def to_dict(self):
return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns}
\ No newline at end of file
......@@ -31,13 +31,13 @@
Тип
</td>
<td>
Размер
Размер (Гбайт)
</td>
<td>
Чексумма
</td>
<td>
Последнее изменение
Последнее изменение оригинального файла
</td>
<td>
Время бэкапа
......@@ -53,9 +53,9 @@
<td>{{ f.tape_label }}</td>
<td>{{ f.target_unique_label }}</td>
<td>{{ f.kind }}</td>
<td>{{ f.size }}</td>
<td>{{ f.fsize / 1024**3 | round(2) }}</td>
<td>{{ f.checksum }}</td>
<td>{{ f.mtime }}</td>
<td>{{ f.file_mtime }}</td>
<td>{{ f.copied_at_time }}</td>
<td>{{ f.relative_path }}</td>
</tr>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment