Skip to content

Commit a22d3d5

Browse files
committed
Implement tag rule manipulation in rebuildctl.
1 parent e23ea77 commit a22d3d5

File tree

3 files changed

+169
-4
lines changed

3 files changed

+169
-4
lines changed

daemon/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,15 @@ pub async fn run_config(pool: db::Pool, config: Config, privkey: PrivateKey) ->
110110
.service(api::v1::create_worker_tag)
111111
.service(api::v1::delete_worker_tag),
112112
)
113-
.service(scope("/tags").service(api::v1::get_tags)),
113+
.service(
114+
scope("/tags")
115+
.service(api::v1::get_tags)
116+
.service(api::v1::create_tag)
117+
.service(api::v1::delete_tag)
118+
.service(api::v1::get_tag_rules)
119+
.service(api::v1::create_tag_rule)
120+
.service(api::v1::delete_tag_rule),
121+
),
114122
),
115123
)
116124
})

tools/src/args.rs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ pub enum SubCommand {
3535
/// Queue related subcommands
3636
#[command(subcommand)]
3737
Queue(Queue),
38-
// Worker related subcommands
38+
/// Worker related subcommands
3939
#[command(subcommand)]
4040
Worker(WorkerCommand),
41+
/// Tag related subcommands
42+
#[command(subcommand)]
43+
Tag(TagCommand),
4144
/// Generate shell completions
4245
Completions(Completions),
4346
}
@@ -213,29 +216,107 @@ pub enum WorkerCommand {
213216

214217
#[derive(Debug, Parser)]
215218
pub enum WorkerTagCommand {
219+
/// List tags attached to a worker
216220
List(WorkerTarget),
221+
222+
/// Set the tags attached to a worker
217223
Set(WorkerSetTags),
224+
225+
/// Add a single tag to a worker
218226
Add(WorkerTagTarget),
227+
228+
/// Remove a single tag from a worker
219229
Remove(WorkerTagTarget),
220230
}
221231

222232
#[derive(Debug, Parser)]
223233
pub struct WorkerTarget {
234+
/// The name of the worker
224235
pub name: String,
225236
}
226237

227238
#[derive(Debug, Parser)]
228239
pub struct WorkerTagTarget {
240+
/// The name of the worker
229241
pub name: String,
242+
243+
/// The name of the tag
230244
pub tag: String,
231245
}
232246

233247
#[derive(Debug, Parser)]
234248
pub struct WorkerSetTags {
249+
/// The name of the worker
235250
pub name: String,
251+
252+
/// The tags
236253
pub tags: Vec<String>,
237254
}
238255

256+
#[derive(Debug, Parser)]
257+
pub enum TagCommand {
258+
/// List registered tags
259+
List,
260+
261+
/// Create a new tag
262+
Create(TagTarget),
263+
264+
/// Delete a tag
265+
Delete(TagTarget),
266+
267+
/// Operate on tag rules
268+
#[command(subcommand)]
269+
Rule(TagRuleCommand),
270+
}
271+
272+
#[derive(Debug, Parser)]
273+
pub enum TagRuleCommand {
274+
/// List rules for a tag
275+
List(OptionalTagTarget),
276+
277+
/// Create a new tag rule
278+
Create(CreateTagRuleCommand),
279+
280+
/// Delete a tag rule
281+
Delete(TagRuleTarget),
282+
}
283+
284+
#[derive(Debug, Parser)]
285+
pub struct TagTarget {
286+
/// The name of the tag
287+
pub tag: String,
288+
}
289+
290+
#[derive(Debug, Parser)]
291+
pub struct OptionalTagTarget {
292+
/// The name of the tag
293+
pub tag: Option<String>,
294+
}
295+
296+
#[derive(Debug, Parser)]
297+
pub struct CreateTagRuleCommand {
298+
/// The name of the tag
299+
pub tag: String,
300+
301+
/// The pattern to match source package names against. Must be compatible with SQLite's LIKE syntax.
302+
#[arg(long)]
303+
pub name_pattern: String,
304+
305+
/// The pattern to match source package versions against. Must be compatible with SQLite's LIKE syntax. Any version
306+
/// will match if this pattern is omitted.
307+
#[arg(long, default_missing_value(None))]
308+
pub version_pattern: Option<String>,
309+
}
310+
311+
#[derive(Debug, Parser)]
312+
pub struct TagRuleTarget {
313+
/// The name of the tag
314+
pub tag: String,
315+
316+
/// The ID of the rule
317+
pub rule_id: i32,
318+
}
319+
239320
#[derive(Debug, Parser)]
240321
pub struct Completions {
241322
pub shell: Shell,

tools/src/main.rs

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use env_logger::Env;
88
use glob::Pattern;
99
use nom::AsBytes;
1010
use rebuilderd_common::api::v1::{
11-
ArtifactStatus, BinaryPackage, BuildRestApi, IdentityFilter, OriginFilter, PackageReport,
12-
PackageRestApi, Page, Priority, QueueJobRequest, QueueRestApi, Worker, WorkerRestApi,
11+
ArtifactStatus, BinaryPackage, BuildRestApi, CreateTagRequest, CreateTagRuleRequest,
12+
IdentityFilter, OriginFilter, PackageReport, PackageRestApi, Page, Priority, QueueJobRequest,
13+
QueueRestApi, TagRestApi, Worker, WorkerRestApi,
1314
};
1415
use rebuilderd_common::api::Client;
1516
use rebuilderd_common::errors::*;
@@ -553,6 +554,81 @@ async fn main() -> Result<()> {
553554
writeln!(io::stderr(), "Worker {} not found", tag_target.name.green())?;
554555
}
555556
}
557+
SubCommand::Tag(TagCommand::List) => {
558+
let tags = client.get_tags().await?;
559+
writeln!(io::stdout(), "{}", tags.join("\n").cyan())?;
560+
}
561+
SubCommand::Tag(TagCommand::Create(tag_target)) => {
562+
let authenticated_client = client.with_auth_cookie()?;
563+
564+
authenticated_client
565+
.create_tag(CreateTagRequest {
566+
tag: tag_target.tag.clone(),
567+
})
568+
.await?;
569+
570+
writeln!(io::stdout(), "Tag {} created", tag_target.tag.cyan())?;
571+
}
572+
SubCommand::Tag(TagCommand::Delete(tag_target)) => {
573+
let authenticated_client = client.with_auth_cookie()?;
574+
575+
authenticated_client
576+
.delete_tag(tag_target.tag.clone())
577+
.await?;
578+
579+
writeln!(io::stdout(), "Tag {} deleted", tag_target.tag.cyan())?;
580+
}
581+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::List(tag_target))) => {
582+
writeln!(io::stdout(), "ID\tTag\tName pattern\tVersion pattern",)?;
583+
584+
let tags = if let Some(tag) = tag_target.tag {
585+
vec![tag]
586+
} else {
587+
client.get_tags().await?
588+
};
589+
590+
for tag in tags {
591+
let tag_rules = client.get_tag_rules(tag.clone()).await?;
592+
for tag_rule in tag_rules {
593+
writeln!(
594+
io::stdout(),
595+
"{}\t{}\t{}\t{}",
596+
tag_rule.id.to_string().yellow(),
597+
tag.cyan(),
598+
tag_rule.name_pattern.green(),
599+
tag_rule.version_pattern.unwrap_or("".to_string()).magenta()
600+
)?;
601+
}
602+
}
603+
}
604+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::Create(create_tag))) => {
605+
let authenticated_client = client.with_auth_cookie()?;
606+
607+
let tag_rule = authenticated_client
608+
.create_tag_rule(
609+
create_tag.tag,
610+
CreateTagRuleRequest {
611+
name_pattern: create_tag.name_pattern,
612+
version_pattern: create_tag.version_pattern,
613+
},
614+
)
615+
.await?;
616+
617+
writeln!(
618+
io::stdout(),
619+
"Rule created (ID {})",
620+
tag_rule.id.to_string().yellow()
621+
)?;
622+
}
623+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::Delete(tag_rule_target))) => {
624+
let authenticated_client = client.with_auth_cookie()?;
625+
626+
authenticated_client
627+
.delete_tag_rule(tag_rule_target.tag, tag_rule_target.rule_id)
628+
.await?;
629+
630+
writeln!(io::stdout(), "Rule deleted")?;
631+
}
556632
SubCommand::Completions(completions) => args::gen_completions(&completions)?,
557633
}
558634

0 commit comments

Comments
 (0)