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:
parent
f13b4e89b7
commit
078c42f185
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user