Updated images model
This commit is contained in:
@@ -1,34 +1,34 @@
|
||||
import streamlit as st
|
||||
import pandas as pd
|
||||
from streamlit_server.utils.helpers import format_timestamp
|
||||
|
||||
def render_list():
|
||||
"""
|
||||
Renders a list of all images.
|
||||
"""
|
||||
st.header("Image Management")
|
||||
|
||||
# Create Image Form
|
||||
with st.expander("Create New Image"):
|
||||
with st.form("create_image"):
|
||||
location = st.text_input("Location (URL or Path)")
|
||||
size = st.number_input("Size (in MB)", min_value=0.0)
|
||||
location_type = st.selectbox("Location Type", ["url", "local"])
|
||||
os_family = st.text_input("OS Family")
|
||||
os_version = st.text_input("OS Version")
|
||||
checksum = st.text_input("Checksum")
|
||||
name = st.text_input("Image Name")
|
||||
location = st.text_input("Image Location (e.g., /images/image.img)")
|
||||
location_type = st.selectbox("Location Type", ["Local", "Remote"])
|
||||
size = st.number_input("Size (GB)", min_value=0.1, step=0.1)
|
||||
os_family = st.text_input("OS Family (e.g., Linux)")
|
||||
os_version = st.text_input("OS Version (e.g., 20.04)")
|
||||
checksum = st.text_input("Checksum (optional)")
|
||||
submit = st.form_submit_button("Create Image")
|
||||
|
||||
if submit and location and size:
|
||||
result = st.session_state.client.create_image({
|
||||
"location": location,
|
||||
"size": size,
|
||||
"location_type": location_type,
|
||||
"os_family": os_family,
|
||||
"os_version": os_version,
|
||||
"checksum": checksum
|
||||
})
|
||||
if submit and name and location:
|
||||
result = st.session_state.client.create_image(
|
||||
name=name,
|
||||
location=location,
|
||||
location_type=location_type,
|
||||
size=size,
|
||||
os_family=os_family,
|
||||
os_version=os_version,
|
||||
checksum=checksum
|
||||
)
|
||||
if result:
|
||||
st.success(f"Image created successfully!")
|
||||
st.success(f"Image '{name}' created successfully!")
|
||||
|
||||
# List Images
|
||||
st.subheader("Existing Images")
|
||||
@@ -39,95 +39,45 @@ def render_list():
|
||||
with st.container():
|
||||
col1, col2, col3 = st.columns([3, 1, 1])
|
||||
with col1:
|
||||
st.markdown(f"### {image['location']}")
|
||||
st.text(f"Size: {image['size']} MB")
|
||||
st.text(f"OS: {image.get('os_family', 'N/A')} {image.get('os_version', 'N/A')}")
|
||||
st.markdown(f"### {image['name']}")
|
||||
st.text(f"Location: {image['location']}")
|
||||
st.text(f"Size: {image['size']} GB")
|
||||
with col2:
|
||||
st.text(f"ID: {image['id'][:8]}...")
|
||||
with col3:
|
||||
if st.button("View Details", key=f"view_{image['id']}"):
|
||||
st.session_state.selected_resource = image
|
||||
st.session_state.view_type = 'detail'
|
||||
st.session_state.selected_resource_type='image'
|
||||
st.session_state.selected_resource_type = 'image'
|
||||
st.rerun() # Force Streamlit to rerun the script
|
||||
|
||||
else:
|
||||
st.info("No images found.")
|
||||
|
||||
def render_detail():
|
||||
"""
|
||||
Renders the details of a specific image.
|
||||
"""
|
||||
image = st.session_state.client.get_image(st.session_state.selected_resource['id'])
|
||||
if not image:
|
||||
st.error("Image not found.")
|
||||
st.session_state.selected_resource = None
|
||||
st.session_state.view_type = 'list'
|
||||
st.session_state.selected_resource_type = None
|
||||
return
|
||||
|
||||
st.title(f"Image: {image['location']}")
|
||||
st.title(f"Image: {image['name']}")
|
||||
if st.button("Back to list view"):
|
||||
st.session_state.view_type = 'list'
|
||||
st.rerun()
|
||||
|
||||
|
||||
|
||||
st.header("Image Details")
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.markdown(f"**ID:** `{image['id']}`")
|
||||
st.markdown(f"**Created:** {format_timestamp(image.get('created_at', 'Unknown'))}")
|
||||
st.markdown(f"**Size:** {image['size']} MB")
|
||||
st.markdown(f"**Location Type:** {image.get('location_type', 'N/A')}")
|
||||
st.markdown(f"**Created:** {format_timestamp(image['created_at'])}")
|
||||
st.markdown(f"**Location:** `{image['location']}`")
|
||||
st.markdown(f"**Location Type:** `{image['location_type']}`")
|
||||
with col2:
|
||||
st.markdown(f"**Size:** `{image['size']} GB`")
|
||||
st.markdown(f"**OS Family:** `{image['os_family']}`")
|
||||
st.markdown(f"**OS Version:** `{image['os_version']}`")
|
||||
if image.get('checksum'):
|
||||
st.markdown(f"**Checksum:** `{image['checksum']}`")
|
||||
if image.get('updated_at'):
|
||||
st.markdown(f"**Last Updated:** {format_timestamp(image['updated_at'])}")
|
||||
st.markdown(f"**OS Family:** {image.get('os_family', 'N/A')}")
|
||||
st.markdown(f"**OS Version:** {image.get('os_version', 'N/A')}")
|
||||
st.markdown(f"**Checksum:** {image.get('checksum', 'N/A')}")
|
||||
|
||||
# Edit Image Form
|
||||
with st.expander("Edit Image"):
|
||||
with st.form("edit_image"):
|
||||
new_location = st.text_input("Location (URL or Path)", value=image['location'])
|
||||
new_size = st.number_input("Size (in MB)", min_value=0.0, value=image['size'])
|
||||
new_location_type = st.selectbox("Location Type", ["url", "local"], index=0 if image.get('location_type') == "url" else 1)
|
||||
new_os_family = st.text_input("OS Family", value=image.get('os_family', ''))
|
||||
new_os_version = st.text_input("OS Version", value=image.get('os_version', ''))
|
||||
new_checksum = st.text_input("Checksum", value=image.get('checksum', ''))
|
||||
submit = st.form_submit_button("Update Image")
|
||||
|
||||
if submit:
|
||||
result = st.session_state.client.update_image(image['id'], {
|
||||
"location": new_location,
|
||||
"size": new_size,
|
||||
"location_type": new_location_type,
|
||||
"os_family": new_os_family,
|
||||
"os_version": new_os_version,
|
||||
"checksum": new_checksum
|
||||
})
|
||||
if result:
|
||||
st.success("Image updated successfully!")
|
||||
st.session_state.selected_resource = image
|
||||
st.session_state.view_type = 'detail'
|
||||
st.session_state.selected_resource_type='image'
|
||||
|
||||
# Delete Image Button
|
||||
if st.button("Delete Image"):
|
||||
result = st.session_state.client.delete_image(image['id'])
|
||||
if result:
|
||||
st.success("Image deleted successfully!")
|
||||
st.session_state.view_type = 'list'
|
||||
st.session_state.selected_resource_type='image'
|
||||
|
||||
# def render():
|
||||
"""
|
||||
Main render function for the Images page.
|
||||
"""
|
||||
# Read query parameters for routing
|
||||
|
||||
|
||||
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='image':
|
||||
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type == 'image':
|
||||
render_detail()
|
||||
else:
|
||||
render_list()
|
||||
@@ -46,14 +46,44 @@ def render_list():
|
||||
st.session_state.volumes = []
|
||||
|
||||
for i, volume in enumerate(st.session_state.volumes):
|
||||
col1, col2 = st.columns([3, 2])
|
||||
col1, col2, col3, col4 = st.columns([3, 2, 2, 2])
|
||||
|
||||
with col1:
|
||||
volume_name = st.text_input(f"Volume Name {i+1}", value=volume['name'], key=f"volume_name_{i}")
|
||||
|
||||
with col2:
|
||||
volume_size = st.number_input(f"Size (GB) {i+1}", min_value=1, value=volume['size_gb'], key=f"volume_size_{i}")
|
||||
|
||||
with col3:
|
||||
volume_type = st.selectbox(f"Type {i+1}", options=["local", "ceph"], index=0 if volume.get('type', 'local') == 'local' else 1, key=f"volume_type_{i}")
|
||||
|
||||
with col4:
|
||||
# Get image options
|
||||
image_list = st.session_state.client.get_images()
|
||||
|
||||
# Create a mapping of image names to IDs
|
||||
image_name_to_id = {img['name']: img['id'] for img in image_list}
|
||||
image_name_to_id["blank"] = "" # Add a blank option
|
||||
|
||||
# Default selected image name (fallback to 'blank' if not found)
|
||||
default_image_name = volume.get('image_name', 'blank')
|
||||
|
||||
# Dropdown to display image names
|
||||
selected_image_name = st.selectbox(
|
||||
f"Image {i+1}",
|
||||
options=list(image_name_to_id.keys()),
|
||||
index=list(image_name_to_id.keys()).index(default_image_name) if default_image_name in image_name_to_id else 0,
|
||||
key=f"volume_image_{i}"
|
||||
)
|
||||
|
||||
# Get the corresponding image ID for the selected image name
|
||||
selected_image_id = image_name_to_id[selected_image_name]
|
||||
|
||||
# Store updated volume info
|
||||
st.session_state.volumes[i] = {"name": volume_name, "size_gb": volume_size}
|
||||
if selected_image_name == "blank":
|
||||
st.session_state.volumes[i] = {"name": volume_name, "size_gb": volume_size, "type": volume_type}
|
||||
else:
|
||||
st.session_state.volumes[i] = {"name": volume_name, "size_gb": volume_size, "type": volume_type, "image_id": selected_image_id}
|
||||
|
||||
submit = st.form_submit_button("Create VM Workload")
|
||||
|
||||
@@ -61,7 +91,7 @@ def render_list():
|
||||
col1, col2 = st.columns([1, 1])
|
||||
with col1:
|
||||
if st.button("Add Volume"):
|
||||
st.session_state.volumes.append({"name": "", "size_gb": 10})
|
||||
st.session_state.volumes.append({"name": "", "size_gb": 10, "type": "", "image":""})
|
||||
st.rerun()
|
||||
|
||||
with col2:
|
||||
@@ -75,7 +105,7 @@ def render_list():
|
||||
vdc_id = vdc_options[selected_vdc_name_create]
|
||||
|
||||
result = st.session_state.client.create_virtual_machine({
|
||||
"vdc": vdc_id,
|
||||
"virtual_data_center": vdc_id,
|
||||
"virtual-machines": [{
|
||||
"name": vm_name,
|
||||
"memory": memory,
|
||||
@@ -157,7 +187,7 @@ def render_list():
|
||||
status = VirtualMachine['status']
|
||||
if status == "error":
|
||||
status_color = "red"
|
||||
elif status == "started":
|
||||
elif status == "running":
|
||||
status_color = "green"
|
||||
elif status == "pending-allocated":
|
||||
status_color = "orange"
|
||||
|
||||
Reference in New Issue
Block a user