Skip to content

Commit 9911b41

Browse files
axel7083l0rd
authored andcommitted
feat: update podman quadlet sub-command
Fixes: #28118 Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
1 parent 13bf771 commit 9911b41

15 files changed

Lines changed: 812 additions & 638 deletions

File tree

cmd/podman/quadlet/install.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func installFlags(cmd *cobra.Command) {
3737
flags := cmd.Flags()
3838
flags.BoolVar(&installOptions.ReloadSystemd, "reload-systemd", true, "Reload systemd after installing Quadlets")
3939
flags.BoolVarP(&installOptions.Replace, "replace", "r", false, "Replace the installation even if the quadlet already exists")
40+
flags.StringVar(&installOptions.Application, "application", "", "Group quadlets and associated file in a directory named after the application")
41+
_ = quadletInstallCmd.RegisterFlagCompletionFunc("application", completion.AutocompleteNone)
4042
}
4143

4244
func init() {

cmd/podman/quadlet/remove.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ var (
1515
quadletRmDescription = `Remove one or more installed Quadlets from the current user`
1616

1717
quadletRmCmd = &cobra.Command{
18-
Use: "rm [options] QUADLET [QUADLET...]",
18+
Use: "rm [options] [QUADLET|APPLICATION...]",
1919
Short: "Remove Quadlets",
2020
Long: quadletRmDescription,
2121
RunE: rm,
2222
ValidArgsFunction: common.AutocompleteQuadlets,
2323
Example: `podman quadlet rm test.container
2424
podman quadlet rm --force mysql.container
25-
podman quadlet rm --all --reload-systemd=false`,
25+
podman quadlet rm --all --reload-systemd=false
26+
podman quadlet rm --recursive app`,
2627
}
2728

2829
removeOptions entities.QuadletRemoveOptions
@@ -35,6 +36,7 @@ func rmFlags(cmd *cobra.Command) {
3536
flags.BoolVarP(&removeOptions.All, "all", "a", false, "Remove all Quadlets for the current user")
3637
flags.BoolVarP(&removeOptions.Ignore, "ignore", "i", false, "Do not error for Quadlets that do not exist")
3738
flags.BoolVar(&removeOptions.ReloadSystemd, "reload-systemd", true, "Reload systemd after removal")
39+
flags.BoolVar(&removeOptions.Recursive, "recursive", false, "Remove all Quadlets belonging to the specified application and its directory")
3840
}
3941

4042
func init() {

cmd/quadlet/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ func process() bool {
478478
Debugf("Starting quadlet-generator, output to: %s", outputPath)
479479
}
480480

481-
sourcePathsMap := quadlet.GetUnitDirs(isUserFlag)
481+
sourcePathsMap := quadlet.GetUnitDirs(isUserFlag, true)
482482

483483
var units []*parser.UnitFile
484484
for _, d := range sourcePathsMap {

docs/source/markdown/podman-quadlet-install.1.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,29 @@ This command allows you to:
1414

1515
* Install a single Quadlet file, optionally followed by additional non-Quadlet files.
1616

17-
* Specify a directory containing multiple Quadlet files and other non-Quadlet files for installation ( example a config file for a quadlet container ).
17+
* Specify a directory containing multiple Quadlet files and other non-Quadlet files for installation (for example a config file for a quadlet container).
1818

1919
* Install multiple Quadlets from a single file with the `.quadlets` extension, where each Quadlet is separated by a `---` delimiter. When using multiple quadlets in a single `.quadlets` file, each quadlet section must include a `# FileName=<name>` comment to specify the name for that quadlet.
2020

21-
Note: If a quadlet is part of an application, removing that specific quadlet will remove the entire application. When a quadlet is installed from a directory, all files installed from that directory—including both quadlet and non-quadlet files—are considered part of a single application. Similarly, when multiple quadlets are installed from a single `.quadlets` file, they are all considered part of the same application.
21+
Note: An application is a collection of files, quadlet and non-quadlets, that
22+
need to live together. As such, removing a quadlet that is part of an
23+
application will remove the entire application. When a quadlet is installed
24+
from a directory, all files installed from that directory—including both
25+
quadlet and non-quadlet files—are considered part of a single application.
2226

23-
Note: In case user wants to install Quadlet application then first path should be the path to application directory.
27+
Note: When multiple quadlets are installed from a single `.quadlets` file,
28+
they are all considered part of the same application only when an application
29+
name is provided using the `--application` option.
2430

2531
## OPTIONS
2632

33+
#### **--application**=*string*
34+
35+
You can specify an application name, all files will be installed under a
36+
directory with the application name. The application name is required when
37+
specifying a directory path. An application name can't have a quadlet extension
38+
as suffix. For example `foo.container` isn't a valid application name.
39+
2740
#### **--reload-systemd**
2841

2942
Reload systemd after installing Quadlets (default true).
@@ -48,7 +61,7 @@ $ podman quadlet install test-service-quadlet.container
4861
Install quadlet from a dir.
4962

5063
```
51-
$ podman quadlet install /home/user/work/quadlet-app/
64+
$ podman quadlet install --application=foo /home/user/work/quadlet-app/
5265
/home/user/.config/containers/systemd/myquadlet1.container
5366
/home/user/.config/containers/systemd/myquadlet2.container
5467
/install/path/myquadlet1.container

docs/source/markdown/podman-quadlet-rm.1.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
podman\-quadlet\-rm - Removes an installed quadlet
55

66
## SYNOPSIS
7-
**podman quadlet rm** [*options*] *quadlet* [*quadlet*]...
7+
**podman quadlet rm** [*options*] *quadlet|application* [*quadlet|application*]...
88

99
## DESCRIPTION
1010

@@ -23,12 +23,16 @@ Remove all Quadlets for the current user.
2323

2424
#### **--force**, **-f**
2525

26-
Remove running quadlets.
26+
Remove running Quadlets.
2727

2828
#### **--ignore**, **-i**
2929

3030
Do not error for Quadlets that do not exist.
3131

32+
#### **--recursive**
33+
34+
Required when removing applications (default false).
35+
3236
#### **--reload-systemd**
3337

3438
Reload systemd after removing Quadlets (default true).
@@ -40,6 +44,10 @@ of this flag to `false`.
4044
```
4145
$ podman quadlet rm myquadlet.container
4246
myquadlet.container
47+
$ podman quadlet rm --recursive myapp
48+
web.container
49+
data.container
50+
data.volume
4351
```
4452

4553
## SEE ALSO

pkg/api/handlers/libpod/quadlets.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ func InstallQuadlets(w http.ResponseWriter, r *http.Request) {
180180

181181
// Parse query parameters
182182
query := struct {
183-
Replace bool `schema:"replace"`
184-
ReloadSystemd bool `schema:"reload-systemd"`
183+
Replace bool `schema:"replace"`
184+
ReloadSystemd bool `schema:"reload-systemd"`
185+
Application string `schema:"application"`
185186
}{
186-
Replace: false,
187187
ReloadSystemd: true, // Default to true like CLI
188188
}
189189

@@ -227,18 +227,15 @@ func InstallQuadlets(w http.ResponseWriter, r *http.Request) {
227227
countQuadletFiles++
228228
}
229229
}
230-
switch {
231-
case countQuadletFiles > 1:
232-
utils.Error(w, http.StatusBadRequest, fmt.Errorf("only a single quadlet file is allowed per request"))
233-
return
234-
case countQuadletFiles == 0:
230+
if countQuadletFiles == 0 {
235231
utils.Error(w, http.StatusBadRequest, fmt.Errorf("no quadlet files found in request"))
236232
return
237233
}
238234

239235
containerEngine := abi.ContainerEngine{Libpod: runtime}
240236
installOptions := entities.QuadletInstallOptions{
241237
Replace: query.Replace,
238+
Application: query.Application,
242239
ReloadSystemd: query.ReloadSystemd,
243240
}
244241

@@ -268,6 +265,7 @@ func RemoveQuadlet(w http.ResponseWriter, r *http.Request) {
268265
Force bool `schema:"force"`
269266
Ignore bool `schema:"ignore"`
270267
ReloadSystemd bool `schema:"reload-systemd"`
268+
Recursive bool `schema:"recursive"`
271269
}{
272270
ReloadSystemd: true, // Default to true like CLI
273271
}
@@ -288,6 +286,7 @@ func RemoveQuadlet(w http.ResponseWriter, r *http.Request) {
288286
Force: query.Force,
289287
Ignore: query.Ignore,
290288
ReloadSystemd: query.ReloadSystemd,
289+
Recursive: query.Recursive,
291290
}
292291

293292
removeReport, err := containerEngine.QuadletRemove(r.Context(), []string{name}, removeOptions)
@@ -324,6 +323,7 @@ func RemoveQuadlets(w http.ResponseWriter, r *http.Request) {
324323
Force bool `schema:"force"`
325324
Ignore bool `schema:"ignore"`
326325
ReloadSystemd bool `schema:"reload-systemd"`
326+
Recursive bool `schema:"recursive"`
327327
Quadlets []string `schema:"quadlets"`
328328
}{
329329
ReloadSystemd: true, // Default to true like CLI
@@ -352,6 +352,7 @@ func RemoveQuadlets(w http.ResponseWriter, r *http.Request) {
352352
All: query.All,
353353
Ignore: query.Ignore,
354354
ReloadSystemd: query.ReloadSystemd,
355+
Recursive: query.Recursive,
355356
}
356357

357358
removeReport, err := containerEngine.QuadletRemove(r.Context(), query.Quadlets, removeOptions)

pkg/domain/entities/quadlet.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ type QuadletInstallOptions struct {
66
ReloadSystemd bool
77
// Replace the installation even if the quadlet already exists
88
Replace bool
9+
// The application to install the quadlet to
10+
Application string
911
}
1012

1113
// QuadletInstallReport contains the output of the `quadlet install` command
@@ -56,6 +58,8 @@ type QuadletRemoveOptions struct {
5658
Ignore bool
5759
// ReloadSystemd determines whether systemd will be reloaded after the Quadlet is removed.
5860
ReloadSystemd bool
61+
// You can specify recursive when targeting an application
62+
Recursive bool
5963
}
6064

6165
// QuadletRemoveReport contains the results of an operation to remove obe or more quadlets

0 commit comments

Comments
 (0)