Skip to content

Commit 99f4a7c

Browse files
committed
Implement tag rule manipulation in rebuildctl.
1 parent edce598 commit 99f4a7c

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
}
@@ -216,29 +219,107 @@ pub enum WorkerCommand {
216219

217220
#[derive(Debug, Parser)]
218221
pub enum WorkerTagCommand {
222+
/// List tags attached to a worker
219223
List(WorkerTarget),
224+
225+
/// Set the tags attached to a worker
220226
Set(WorkerSetTags),
227+
228+
/// Add a single tag to a worker
221229
Add(WorkerTagTarget),
230+
231+
/// Remove a single tag from a worker
222232
Remove(WorkerTagTarget),
223233
}
224234

225235
#[derive(Debug, Parser)]
226236
pub struct WorkerTarget {
237+
/// The name of the worker
227238
pub name: String,
228239
}
229240

230241
#[derive(Debug, Parser)]
231242
pub struct WorkerTagTarget {
243+
/// The name of the worker
232244
pub name: String,
245+
246+
/// The name of the tag
233247
pub tag: String,
234248
}
235249

236250
#[derive(Debug, Parser)]
237251
pub struct WorkerSetTags {
252+
/// The name of the worker
238253
pub name: String,
254+
255+
/// The tags
239256
pub tags: Vec<String>,
240257
}
241258

259+
#[derive(Debug, Parser)]
260+
pub enum TagCommand {
261+
/// List registered tags
262+
List,
263+
264+
/// Create a new tag
265+
Create(TagTarget),
266+
267+
/// Delete a tag
268+
Delete(TagTarget),
269+
270+
/// Operate on tag rules
271+
#[command(subcommand)]
272+
Rule(TagRuleCommand),
273+
}
274+
275+
#[derive(Debug, Parser)]
276+
pub enum TagRuleCommand {
277+
/// List rules for a tag
278+
List(OptionalTagTarget),
279+
280+
/// Create a new tag rule
281+
Create(CreateTagRuleCommand),
282+
283+
/// Delete a tag rule
284+
Delete(TagRuleTarget),
285+
}
286+
287+
#[derive(Debug, Parser)]
288+
pub struct TagTarget {
289+
/// The name of the tag
290+
pub tag: String,
291+
}
292+
293+
#[derive(Debug, Parser)]
294+
pub struct OptionalTagTarget {
295+
/// The name of the tag
296+
pub tag: Option<String>,
297+
}
298+
299+
#[derive(Debug, Parser)]
300+
pub struct CreateTagRuleCommand {
301+
/// The name of the tag
302+
pub tag: String,
303+
304+
/// The pattern to match source package names against. Must be compatible with SQLite's LIKE syntax.
305+
#[arg(long)]
306+
pub name_pattern: String,
307+
308+
/// The pattern to match source package versions against. Must be compatible with SQLite's LIKE syntax. Any version
309+
/// will match if this pattern is omitted.
310+
#[arg(long, default_missing_value(None))]
311+
pub version_pattern: Option<String>,
312+
}
313+
314+
#[derive(Debug, Parser)]
315+
pub struct TagRuleTarget {
316+
/// The name of the tag
317+
pub tag: String,
318+
319+
/// The ID of the rule
320+
pub rule_id: i32,
321+
}
322+
242323
#[derive(Debug, Parser)]
243324
pub struct Completions {
244325
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, QueueJobRequest, QueueRestApi, Worker, WorkerRestApi,
11+
ArtifactStatus, BinaryPackage, BuildRestApi, CreateTagRequest, CreateTagRuleRequest,
12+
IdentityFilter, OriginFilter, PackageReport, PackageRestApi, Page, QueueJobRequest,
13+
QueueRestApi, TagRestApi, Worker, WorkerRestApi,
1314
};
1415
use rebuilderd_common::api::Client;
1516
use rebuilderd_common::errors::*;
@@ -544,6 +545,81 @@ async fn main() -> Result<()> {
544545
writeln!(io::stderr(), "Worker {} not found", tag_target.name.green())?;
545546
}
546547
}
548+
SubCommand::Tag(TagCommand::List) => {
549+
let tags = client.get_tags().await?;
550+
writeln!(io::stdout(), "{}", tags.join("\n").cyan())?;
551+
}
552+
SubCommand::Tag(TagCommand::Create(tag_target)) => {
553+
let authenticated_client = client.with_auth_cookie()?;
554+
555+
authenticated_client
556+
.create_tag(CreateTagRequest {
557+
tag: tag_target.tag.clone(),
558+
})
559+
.await?;
560+
561+
writeln!(io::stdout(), "Tag {} created", tag_target.tag.cyan())?;
562+
}
563+
SubCommand::Tag(TagCommand::Delete(tag_target)) => {
564+
let authenticated_client = client.with_auth_cookie()?;
565+
566+
authenticated_client
567+
.delete_tag(tag_target.tag.clone())
568+
.await?;
569+
570+
writeln!(io::stdout(), "Tag {} deleted", tag_target.tag.cyan())?;
571+
}
572+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::List(tag_target))) => {
573+
writeln!(io::stdout(), "ID\tTag\tName pattern\tVersion pattern",)?;
574+
575+
let tags = if let Some(tag) = tag_target.tag {
576+
vec![tag]
577+
} else {
578+
client.get_tags().await?
579+
};
580+
581+
for tag in tags {
582+
let tag_rules = client.get_tag_rules(tag.clone()).await?;
583+
for tag_rule in tag_rules {
584+
writeln!(
585+
io::stdout(),
586+
"{}\t{}\t{}\t{}",
587+
tag_rule.id.to_string().yellow(),
588+
tag.cyan(),
589+
tag_rule.name_pattern.green(),
590+
tag_rule.version_pattern.unwrap_or("".to_string()).magenta()
591+
)?;
592+
}
593+
}
594+
}
595+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::Create(create_tag))) => {
596+
let authenticated_client = client.with_auth_cookie()?;
597+
598+
let tag_rule = authenticated_client
599+
.create_tag_rule(
600+
create_tag.tag,
601+
CreateTagRuleRequest {
602+
name_pattern: create_tag.name_pattern,
603+
version_pattern: create_tag.version_pattern,
604+
},
605+
)
606+
.await?;
607+
608+
writeln!(
609+
io::stdout(),
610+
"Rule created (ID {})",
611+
tag_rule.id.to_string().yellow()
612+
)?;
613+
}
614+
SubCommand::Tag(TagCommand::Rule(TagRuleCommand::Delete(tag_rule_target))) => {
615+
let authenticated_client = client.with_auth_cookie()?;
616+
617+
authenticated_client
618+
.delete_tag_rule(tag_rule_target.tag, tag_rule_target.rule_id)
619+
.await?;
620+
621+
writeln!(io::stdout(), "Rule deleted")?;
622+
}
547623
SubCommand::Completions(completions) => args::gen_completions(&completions)?,
548624
}
549625

0 commit comments

Comments
 (0)