m/cup
1
0
mirror of https://github.com/sergi0g/cup.git synced 2025-11-11 06:33:49 -05:00

4 Commits

Author SHA1 Message Date
Sergio
e7673c04db Move icons in statistics to bottom right
Some checks failed
Deploy github pages / build (push) Has been cancelled
Nightly Release / build-binary (map[bin:cup command:build name:cup-linux-aarch64 os:ubuntu-latest release_for:linux-aarch64 target:aarch64-unknown-linux-musl]) (push) Has been cancelled
Nightly Release / build-binary (map[bin:cup command:build name:cup-linux-x86_64 os:ubuntu-latest release_for:linux-x86_64 target:x86_64-unknown-linux-musl]) (push) Has been cancelled
Nightly Release / build-image (push) Has been cancelled
Deploy github pages / deploy (push) Has been cancelled
2024-08-31 22:07:38 +03:00
Sergio
7292ed3d1b Forgot to handle another potential error 2024-08-31 21:44:31 +03:00
Sergio
def2efa0d1 Add better error handling
(mostly because I have bad internet)
2024-08-31 21:24:56 +03:00
Sergio
21c110011f Update README.md 2024-08-31 20:29:40 +03:00
4 changed files with 51 additions and 11 deletions

View File

@@ -27,7 +27,7 @@ Take a look at https://sergi0g.github.io/cup/docs!
Cup is a work in progress. It might not have as many features as What's up Docker. If one of these features is really important for you, please consider using another tool. Cup is a work in progress. It might not have as many features as What's up Docker. If one of these features is really important for you, please consider using another tool.
- ~~Cup currently doesn't support registries which use repositories without slashes. This includes Azure. This problem may sound a bit weird, but it's due to the regex that's used at the moment. This will (hopefully) be fixed in the future.~~ - ~~Cup currently doesn't support registries which use repositories without slashes. This includes Azure. This problem may sound a bit weird, but it's due to the regex that's used at the moment. This will (hopefully) be fixed in the future.~~
- Cup doesn't support private images. This is on the roadmap. Currently, it just returns unknown for those images. - ~~Cup doesn't support private images. This is on the roadmap. Currently, it just returns unknown for those images.~~
- Cup cannot trigger your integrations. If you want that to happen automatically, please use What's up docker instead. Cup was created to be simple. The data is there, and it's up to you to retrieve it (e.g. by running `cup check -r` with a cronjob or periodically requesting the `/json` url from the server) - Cup cannot trigger your integrations. If you want that to happen automatically, please use What's up docker instead. Cup was created to be simple. The data is there, and it's up to you to retrieve it (e.g. by running `cup check -r` with a cronjob or periodically requesting the `/json` url from the server)
## Roadmap ## Roadmap

View File

@@ -2,7 +2,7 @@ use std::sync::Mutex;
use json::JsonValue; use json::JsonValue;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use ureq::Error; use ureq::{Error, ErrorKind};
use http_auth::parse_challenges; use http_auth::parse_challenges;
@@ -17,6 +17,19 @@ pub fn check_auth(registry: &str, config: &JsonValue) -> Option<String> {
Some(challenge) => Some(parse_www_authenticate(challenge)), Some(challenge) => Some(parse_www_authenticate(challenge)),
None => error!("Unauthorized to access registry {} and no way to authenticate was provided", registry), None => error!("Unauthorized to access registry {} and no way to authenticate was provided", registry),
}, },
Err(Error::Transport(error)) => {
match error.kind() {
ErrorKind::Dns => {
warn!("Failed to lookup the IP of the registry, retrying.");
return check_auth(registry, config)
}, // If something goes really wrong, this can get stuck in a loop
ErrorKind::ConnectionFailed => {
warn!("Connection probably timed out, retrying.");
return check_auth(registry, config)
}, // Same here
_ => error!("{}", error)
}
},
Err(e) => error!("{}", e), Err(e) => error!("{}", e),
} }
} }
@@ -56,8 +69,20 @@ pub fn get_latest_digest(image: &Image, token: Option<&String>, config: &JsonVal
digest: None, digest: None,
..image.clone() ..image.clone()
} }
} },
Err(ureq::Error::Transport(e)) => error!("Failed to send request!\n{}", e), Err(Error::Transport(error)) => {
match error.kind() {
ErrorKind::Dns => {
warn!("Failed to lookup the IP of the registry, retrying.");
return get_latest_digest(image, token, config)
}, // If something goes really wrong, this can get stuck in a loop
ErrorKind::ConnectionFailed => {
warn!("Connection probably timed out, retrying.");
return get_latest_digest(image, token, config)
}, // Same here
_ => error!("Failed to retrieve image digest\n{}!", error)
}
},
}; };
match raw_response.header("docker-content-digest") { match raw_response.header("docker-content-digest") {
Some(digest) => Image { Some(digest) => Image {
@@ -83,7 +108,7 @@ pub fn get_latest_digests(images: Vec<&Image>, token: Option<&String>, config: &
pub fn get_token(images: Vec<&Image>, auth_url: &str, credentials: &Option<String>) -> String { pub fn get_token(images: Vec<&Image>, auth_url: &str, credentials: &Option<String>) -> String {
let mut final_url = auth_url.to_owned(); let mut final_url = auth_url.to_owned();
for image in images { for image in &images {
final_url = format!("{}&scope=repository:{}:pull", final_url, image.repository); final_url = format!("{}&scope=repository:{}:pull", final_url, image.repository);
} }
let mut base_request = ureq::get(&final_url).set("Accept", "application/vnd.oci.image.index.v1+json"); // Seems to be unnecesarry. Will probably remove in the future let mut base_request = ureq::get(&final_url).set("Accept", "application/vnd.oci.image.index.v1+json"); // Seems to be unnecesarry. Will probably remove in the future
@@ -99,6 +124,19 @@ pub fn get_token(images: Vec<&Image>, auth_url: &str, credentials: &Option<Strin
error!("Failed to parse response into string!\n{}", e) error!("Failed to parse response into string!\n{}", e)
} }
}, },
Err(Error::Transport(error)) => {
match error.kind() {
ErrorKind::Dns => {
warn!("Failed to lookup the IP of the registry, retrying.");
return get_token(images, auth_url, credentials)
}, // If something goes really wrong, this can get stuck in a loop
ErrorKind::ConnectionFailed => {
warn!("Connection probably timed out, retrying.");
return get_token(images, auth_url, credentials)
}, // Same here
_ => error!("Token request failed\n{}!", error)
}
},
Err(e) => { Err(e) => {
error!("Token request failed!\n{}", e) error!("Token request failed!\n{}", e)
} }

File diff suppressed because one or more lines are too long

View File

@@ -144,8 +144,13 @@
{% for metric in metrics %} {% for metric in metrics %}
<div class="gi"> <div class="gi">
<div class="xl:px-8 px-6 py-4 gap-y-2 gap-x-4 justify-between align-baseline flex flex-col h-full"> <div class="xl:px-8 px-6 py-4 gap-y-2 gap-x-4 justify-between align-baseline flex flex-col h-full">
<dt class="text-{{ theme }}-500 dark:text-{{ theme }}-400 leading-6 font-medium flex gap-1 justify-between"> <dt class="text-{{ theme }}-500 dark:text-{{ theme }}-400 leading-6 font-medium">
{{ metric.name }} {{ metric.name }}
</dt>
<div class="flex gap-1 justify-between items-center">
<dd class="text-black dark:text-white tracking-tight leading-10 font-medium text-3xl w-full">
{{ metric.value }}
</dd>
{% if metric.name == 'Monitored images' %} {% if metric.name == 'Monitored images' %}
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -194,10 +199,7 @@
<path d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -19.995 .324l-.005 -.324l.004 -.28c.148 -5.393 4.566 -9.72 9.996 -9.72zm0 13a1 1 0 0 0 -.993 .883l-.007 .117l.007 .127a1 1 0 0 0 1.986 0l.007 -.117l-.007 -.127a1 1 0 0 0 -.993 -.883zm1.368 -6.673a2.98 2.98 0 0 0 -3.631 .728a1 1 0 0 0 1.44 1.383l.171 -.18a.98 .98 0 0 1 1.11 -.15a1 1 0 0 1 -.34 1.886l-.232 .012a1 1 0 0 0 .111 1.994a3 3 0 0 0 1.371 -5.673z" /> <path d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -19.995 .324l-.005 -.324l.004 -.28c.148 -5.393 4.566 -9.72 9.996 -9.72zm0 13a1 1 0 0 0 -.993 .883l-.007 .117l.007 .127a1 1 0 0 0 1.986 0l.007 -.117l-.007 -.127a1 1 0 0 0 -.993 -.883zm1.368 -6.673a2.98 2.98 0 0 0 -3.631 .728a1 1 0 0 0 1.44 1.383l.171 -.18a.98 .98 0 0 1 1.11 -.15a1 1 0 0 1 -.34 1.886l-.232 .012a1 1 0 0 0 .111 1.994a3 3 0 0 0 1.371 -5.673z" />
</svg> </svg>
{% endif %} {% endif %}
</dt> </div>
<dd class="text-black dark:text-white tracking-tight leading-10 font-medium text-3xl flex-none w-full">
{{ metric.value }}
</dd>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}