1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-12-26 00:38:10 +00:00

Save image size + start to automatic template creation based on image checksum.

This commit is contained in:
grossmj 2021-08-11 16:58:23 +09:30
parent f13b4e89b7
commit 078c42f185
7 changed files with 39 additions and 9 deletions

View File

@ -56,8 +56,8 @@ async def get_images(
@router.post("/upload/{image_name}", response_model=schemas.Image, status_code=status.HTTP_201_CREATED)
async def upload_image(
image_name: str,
image_type: schemas.ImageType,
request: Request,
image_type: schemas.ImageType = schemas.ImageType.qemu,
images_repo: ImagesRepository = Depends(get_repository(ImagesRepository)),
) -> schemas.Image:
"""
@ -78,6 +78,11 @@ async def upload_image(
except (OSError, InvalidImageError) as e:
raise ControllerError(f"Could not save {image_type} image '{image_name}': {e}")
# TODO: automatically create template based on image checksum
#from gns3server.controller import Controller
#controller = Controller.instance()
#controller.appliance_manager.find_appliance_with_image(image.checksum)
return image

View File

@ -56,6 +56,14 @@ class Appliance:
def name(self):
return self._data.get("name")
@property
def images(self):
return self._data.get("images")
@property
def versions(self):
return self._data.get("versions")
@symbol.setter
def symbol(self, new_symbol):
self._data["symbol"] = new_symbol

View File

@ -77,6 +77,20 @@ class ApplianceManager:
os.makedirs(appliances_path, exist_ok=True)
return appliances_path
#TODO: finish
def find_appliance_with_image(self, image_checksum):
for appliance in self._appliances.values():
if appliance.images:
for image in appliance.images:
if image["md5sum"] == image_checksum:
print(f"APPLIANCE FOUND {appliance.name}")
version = image["version"]
print(f"IMAGE VERSION {version}")
if image.versions:
for version in image.versions:
pass
def load_appliances(self, symbol_theme="Classic"):
"""
Loads appliance files from disk.

View File

@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sqlalchemy import Column, String, Integer
from sqlalchemy import Column, String, Integer, BigInteger
from sqlalchemy.orm import relationship
from .base import BaseTable
@ -28,6 +28,7 @@ class Image(BaseTable):
id = Column(Integer, primary_key=True, autoincrement=True)
filename = Column(String, unique=True, index=True)
image_type = Column(String)
image_size = Column(BigInteger)
path = Column(String)
checksum = Column(String)
checksum_algorithm = Column(String)

View File

@ -57,12 +57,13 @@ class ImagesRepository(BaseRepository):
result = await self._db_session.execute(query)
return result.scalars().first()
async def add_image(self, image_name, image_type, path, checksum, checksum_algorithm) -> models.Image:
async def add_image(self, image_name, image_type, image_size, path, checksum, checksum_algorithm) -> models.Image:
db_image = models.Image(
id=None,
filename=image_name,
image_type=image_type,
image_size=image_size,
path=path,
checksum=checksum,
checksum_algorithm=checksum_algorithm

View File

@ -34,6 +34,7 @@ class ImageBase(BaseModel):
filename: str = Field(..., description="Image name")
image_type: ImageType = Field(..., description="Image type")
image_size: int = Field(..., description="Image size in bytes")
checksum: str = Field(..., description="Checksum value")
checksum_algorithm: str = Field(..., description="Checksum algorithm")

View File

@ -236,9 +236,9 @@ def check_valid_image_header(data: bytes, image_type: str, header_magic_len: int
# (normal IOS images are big endian!)
if data[:header_magic_len] != b'\x7fELF\x01\x01\x01' and data[:7] != b'\x7fELF\x02\x01\x01':
raise InvalidImageError("Invalid IOU file detected")
# elif image_type == "qemu":
# if data[:expected_header_magic_len] != b'QFI\xfb':
# raise InvalidImageError("Invalid Qemu file detected (must be raw or qcow2)")
elif image_type == "qemu":
if data[:header_magic_len] != b'QFI\xfb':
raise InvalidImageError("Invalid Qemu file detected (must be qcow2 format)")
async def write_image(
@ -267,8 +267,8 @@ async def write_image(
await f.write(chunk)
checksum.update(chunk)
file_size = os.path.getsize(tmp_path)
if not file_size or file_size < header_magic_len:
image_size = os.path.getsize(tmp_path)
if not image_size or image_size < header_magic_len:
raise InvalidImageError("The image content is empty or too small to be valid")
checksum = checksum.hexdigest()
@ -280,4 +280,4 @@ async def write_image(
raise
os.chmod(tmp_path, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
shutil.move(tmp_path, path)
return await images_repo.add_image(image_name, image_type, path, checksum, checksum_algorithm="md5")
return await images_repo.add_image(image_name, image_type, image_size, path, checksum, checksum_algorithm="md5")