Add docker to needed.txt and add basic docker image support.
This commit is contained in:
parent
b7e9476431
commit
ae1f1edd76
5 changed files with 200 additions and 26 deletions
|
@ -1,6 +1,3 @@
|
||||||
cargo
|
cargo
|
||||||
gtk4-devel
|
gtk4-devel
|
||||||
|
docker
|
||||||
|
|
||||||
I didn't need to install this? - Deyo
|
|
||||||
cairo-gobject-devel
|
|
||||||
|
|
91
src/containers/images.rs
Normal file
91
src/containers/images.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
use gtk::{prelude::BoxExt, Label};
|
||||||
|
|
||||||
|
use super::Image;
|
||||||
|
|
||||||
|
pub fn images() -> gtk::Box {
|
||||||
|
let images_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Using unwrap here is allowed since this will always
|
||||||
|
return a Some when the second param is false
|
||||||
|
*/
|
||||||
|
let images = crate::pkexec("docker images".to_owned(), false)
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.map(|x| x.parse::<Image>().unwrap())
|
||||||
|
.collect::<Vec<Image>>();
|
||||||
|
|
||||||
|
for image in images {
|
||||||
|
let image_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
.css_classes(["image-box"])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let repo_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
repo_box.append(
|
||||||
|
&Label::builder()
|
||||||
|
.label("Repository: ")
|
||||||
|
.css_classes(["repo-label"])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
repo_box.append(&Label::builder().label(&image.repository).build());
|
||||||
|
|
||||||
|
let tag_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
tag_box.append(
|
||||||
|
&Label::builder()
|
||||||
|
.label("Tag: ")
|
||||||
|
.css_classes(["tag-label"])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
tag_box.append(&Label::builder().label(&image.tag).build());
|
||||||
|
|
||||||
|
let id_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
id_box.append(
|
||||||
|
&Label::builder()
|
||||||
|
.label("Image ID: ")
|
||||||
|
.css_classes(["id-label"])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
id_box.append(&Label::builder().label(&image.id).build());
|
||||||
|
|
||||||
|
let created_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
created_box.append(
|
||||||
|
&Label::builder()
|
||||||
|
.label("Created at: ")
|
||||||
|
.css_classes(["created-label"])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
created_box.append(&Label::builder().label(&image.created).build());
|
||||||
|
|
||||||
|
let size_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
size_box.append(
|
||||||
|
&Label::builder()
|
||||||
|
.label("Size: ")
|
||||||
|
.css_classes(["size-label"])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
size_box.append(&Label::builder().label(&image.size).build());
|
||||||
|
|
||||||
|
image_box.append(&repo_box);
|
||||||
|
image_box.append(&tag_box);
|
||||||
|
image_box.append(&id_box);
|
||||||
|
image_box.append(&created_box);
|
||||||
|
image_box.append(&size_box);
|
||||||
|
|
||||||
|
images_box.append(&image_box);
|
||||||
|
}
|
||||||
|
|
||||||
|
images_box
|
||||||
|
}
|
69
src/containers/mod.rs
Normal file
69
src/containers/mod.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use gtk::{prelude::BoxExt, Stack, StackSidebar};
|
||||||
|
use images::images;
|
||||||
|
|
||||||
|
pub mod images;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Page for managing Docker containers and images.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
- Move to it's own file/folder
|
||||||
|
- Add the following pages: "Containers", "Images", "Browse"
|
||||||
|
*/
|
||||||
|
pub fn containers() -> gtk::Box {
|
||||||
|
// Initialize the box that will be used as a page.
|
||||||
|
let containers_box = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
.css_classes(["containers-box"])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let containers_stack = Stack::builder()
|
||||||
|
.halign(gtk::Align::Fill)
|
||||||
|
.valign(gtk::Align::Fill)
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let containers_sidebar = StackSidebar::builder()
|
||||||
|
.stack(&containers_stack)
|
||||||
|
.halign(gtk::Align::Start)
|
||||||
|
.valign(gtk::Align::Fill)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
containers_stack.add_titled(&images(), Some("images"), "Images");
|
||||||
|
|
||||||
|
// Start the docker daemon if it isn't running.
|
||||||
|
if std::fs::metadata("/var/run/docker.pid").is_err() {
|
||||||
|
crate::pkexec("dockerd".to_owned(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a new label as a title and return the box.
|
||||||
|
containers_box.append(&containers_sidebar);
|
||||||
|
containers_box.append(&containers_stack);
|
||||||
|
|
||||||
|
containers_box
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Image {
|
||||||
|
pub repository: String,
|
||||||
|
pub tag: String,
|
||||||
|
pub id: String,
|
||||||
|
pub created: String,
|
||||||
|
pub size: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Image {
|
||||||
|
type Err = String;
|
||||||
|
fn from_str(value: &str) -> Result<Self, String> {
|
||||||
|
let mut parts = value.split_whitespace().map(|x| x.to_owned());
|
||||||
|
Ok(Self {
|
||||||
|
repository: parts.next().expect("Failed to get repository."),
|
||||||
|
tag: parts.next().expect("Failed to get tag."),
|
||||||
|
id: parts.next().expect("Failed to get ID."),
|
||||||
|
created: parts.next().expect("Failed to get created time."),
|
||||||
|
size: parts.next().expect("Failed to get size."),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
45
src/main.rs
45
src/main.rs
|
@ -6,6 +6,7 @@ use gtk::{
|
||||||
Stack, StackSwitcher,
|
Stack, StackSwitcher,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod containers;
|
||||||
pub mod drivers;
|
pub mod drivers;
|
||||||
pub mod packages;
|
pub mod packages;
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ fn on_activate(app: &Application) {
|
||||||
*/
|
*/
|
||||||
main_stack.add_titled(&packages::packages(), Some("packages"), "Packages");
|
main_stack.add_titled(&packages::packages(), Some("packages"), "Packages");
|
||||||
main_stack.add_titled(&drivers::drivers(), Some("drivers"), "Drivers");
|
main_stack.add_titled(&drivers::drivers(), Some("drivers"), "Drivers");
|
||||||
main_stack.add_titled(&containers(), Some("containers"), "Containers");
|
main_stack.add_titled(&containers::containers(), Some("containers"), "Containers");
|
||||||
main_stack.add_titled(&virtualization(), Some("virtualization"), "Virtualization");
|
main_stack.add_titled(&virtualization(), Some("virtualization"), "Virtualization");
|
||||||
|
|
||||||
// Append the switcher and stack to the main box
|
// Append the switcher and stack to the main box
|
||||||
|
@ -77,26 +78,6 @@ fn on_activate(app: &Application) {
|
||||||
main_window.present();
|
main_window.present();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Page for managing Docker containers and images.
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
- Move to it's own file/folder
|
|
||||||
- Add the following pages: "Containers", "Images", "Browse"
|
|
||||||
*/
|
|
||||||
fn containers() -> gtk::Box {
|
|
||||||
// Initialize the box that will be used as a page.
|
|
||||||
let containers_box = gtk::Box::builder()
|
|
||||||
.orientation(Horizontal)
|
|
||||||
.css_classes(["containers-box"])
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Append a new label as a title and return the box.
|
|
||||||
containers_box.append(>k::Label::new(Some("Containers")));
|
|
||||||
|
|
||||||
containers_box
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
For managing virtual machines.
|
For managing virtual machines.
|
||||||
|
|
||||||
|
@ -116,6 +97,28 @@ fn virtualization() -> gtk::Box {
|
||||||
virtualization_box
|
virtualization_box
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pkexec(cmd: String, spawn: bool) -> Option<String> {
|
||||||
|
dbg!(cmd.split_whitespace().next());
|
||||||
|
if spawn {
|
||||||
|
std::process::Command::new("pkexec")
|
||||||
|
.args(cmd.split_whitespace())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to spawn child process!");
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
String::from_utf8(
|
||||||
|
std::process::Command::new("pkexec")
|
||||||
|
.args(cmd.split_whitespace())
|
||||||
|
.output()
|
||||||
|
.expect("Failed to get output of command.")
|
||||||
|
.stdout,
|
||||||
|
)
|
||||||
|
.expect("Failed to convert command stdout to string!"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Function to link `style.css` to the application.
|
/// Function to link `style.css` to the application.
|
||||||
fn on_startup(_: &Application) {
|
fn on_startup(_: &Application) {
|
||||||
let css_provider = gtk::CssProvider::new();
|
let css_provider = gtk::CssProvider::new();
|
||||||
|
|
|
@ -26,9 +26,23 @@
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Packages */
|
||||||
.license-label,
|
.license-label,
|
||||||
.version-label,
|
.version-label,
|
||||||
.size-label,
|
.size-label,
|
||||||
.description-label {
|
.description-label,
|
||||||
|
|
||||||
|
/* Containers */
|
||||||
|
.repo-label,
|
||||||
|
.tag-label,
|
||||||
|
.id-label,
|
||||||
|
.created-label,
|
||||||
|
.size-label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-box {
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: -1px -1px #ff0000;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue