add builtin docker-hub support

This commit is contained in:
Robin Appelman 2022-07-17 13:32:27 +02:00
commit 334806c5b7
5 changed files with 90 additions and 0 deletions

22
Cargo.lock generated
View file

@ -566,6 +566,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.29.0" version = "0.29.0"
@ -727,6 +736,7 @@ dependencies = [
"rss", "rss",
"serde", "serde",
"serde_json", "serde_json",
"time",
"tokio", "tokio",
"toml", "toml",
] ]
@ -892,6 +902,18 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "time"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
dependencies = [
"itoa",
"libc",
"num_threads",
"serde",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"

View file

@ -14,3 +14,4 @@ toml = "0.5.9"
color-eyre = "0.6.2" color-eyre = "0.6.2"
env_logger = "0.9.0" env_logger = "0.9.0"
log = "0.4.17" log = "0.4.17"
time = { version = "0.3.11", features = ["serde", "serde-well-known"] }

View file

@ -21,4 +21,9 @@ feed = "https://example.com/feed2.xml"
hook = "https://hook.example.com/hook2/call" hook = "https://hook.example.com/hook2/call"
headers = { authorization = "...." } headers = { authorization = "...." }
body = { event_type = "build" } body = { event_type = "build" }
# trigger on docker hub updates instead of rss feed update
[[feed]]
feed = "docker-hub://matrixdotorg/synapse"
hook = "https://hook.example.com/hook2/call"
``` ```

42
src/hub.rs Normal file
View file

@ -0,0 +1,42 @@
use color_eyre::eyre::WrapErr;
use color_eyre::{eyre::ensure, Result};
use reqwest::Client;
use serde::Deserialize;
use time::OffsetDateTime;
pub async fn tags(client: &Client, user: &str, repo: &str) -> Result<Vec<HubTag>> {
let result = client
.get(format!(
"https://hub.docker.com/v2/repositories/{}/{}/tags",
user, repo
))
.send()
.await
.wrap_err("error with sending docker hub request")?;
ensure!(
!result.status().is_client_error(),
"error with sending docker hub request"
);
ensure!(
!result.status().is_server_error(),
"docker hub request returned an error"
);
Ok(result
.json::<HubTagResponse>()
.await
.wrap_err("failed to parse hub response")?
.results)
}
#[derive(Debug, Deserialize)]
pub struct HubTagResponse {
results: Vec<HubTag>,
}
#[derive(Debug, Deserialize)]
pub struct HubTag {
pub id: u64,
#[serde(with = "time::serde::rfc3339")]
pub last_updated: OffsetDateTime,
pub name: String,
}

View file

@ -1,4 +1,5 @@
mod config; mod config;
mod hub;
use crate::config::{Config, FeedConfig}; use crate::config::{Config, FeedConfig};
use color_eyre::{ use color_eyre::{
@ -107,6 +108,25 @@ impl FeedFetcher {
} }
async fn get_feed_key(&self, feed: &str) -> Result<u64> { async fn get_feed_key(&self, feed: &str) -> Result<u64> {
if let Some(hub) = feed.strip_prefix("docker-hub://") {
if let Some((user, repo)) = hub.split_once('/') {
let tags = hub::tags(&self.client, user, repo).await?;
let mut hasher = DefaultHasher::new();
for tag in tags {
tag.id.hash(&mut hasher);
tag.last_updated.hash(&mut hasher);
}
Ok(hasher.finish())
} else {
return Err(eyre!("Invalid hub format {}", feed))
}
} else {
self.get_rss_feed_key(feed).await
}
}
async fn get_rss_feed_key(&self, feed: &str) -> Result<u64> {
let content = self let content = self
.client .client
.get(feed) .get(feed)