Merge pull request #2063 from cclerget/overlay-conflict-response
Return HTTP 409 status when creating an existing overlay
This commit is contained in:
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
### Fixed
|
||||
|
||||
- Remove requisite dependency between ignition disk target and ignition service. #2083
|
||||
- Return HTTP 409 status when creating an existing overlay
|
||||
|
||||
## v4.6.5, 2026-01-12
|
||||
|
||||
@@ -156,7 +157,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
### Removed
|
||||
|
||||
- Removed the gRPC API servers and client. #1876
|
||||
- Removed ``wwctl node import --csv``. #1862
|
||||
- Removed `wwctl node import --csv`. #1862
|
||||
|
||||
## v4.6.1, 2025-04-04
|
||||
|
||||
@@ -165,7 +166,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Added `wwctl overlay import --overwrite` to overwrite existing overlay file.
|
||||
- wwclient uses `WW_IPADDR`, if set, to contact the Warewulf server. #1788
|
||||
- Add `wwctl node import --yes` to assume yes to confirmations.
|
||||
- Set an IPMI tag ``vlan`` to configure the vlan during ``ipmiwrite``. #1031
|
||||
- Set an IPMI tag `vlan` to configure the vlan during `ipmiwrite`. #1031
|
||||
- Added net.ifnames=1 to default kernel argument list. #1820
|
||||
- Add a new OpenAPI v3 REST API to warewulfd at /api. #1588
|
||||
- New sos plugin in `warewulf-sos` subpackage. #1822
|
||||
@@ -528,7 +529,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Fix dhcpd.conf static template to include next-server and dhcp-range #1536
|
||||
- Fix panic when adding tag with existing netdev #1546
|
||||
|
||||
|
||||
## v4.5.7, 2024-09-11
|
||||
|
||||
### Added
|
||||
@@ -559,6 +559,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- `wwctl conatiner list --kernel` shows the kernel detected for each container. #1283
|
||||
- `wwctl container list --size` shows the uncompressed size of each container. `--compressed` shows the compressed size, and `--chroot` shows the size of the container source on the server. #954, #1117
|
||||
- Add a logrotate config for `warewulfd.log`. #1311
|
||||
|
||||
### Changed
|
||||
|
||||
- Refactor URL handling in wwclient to consistently escape arguments.
|
||||
@@ -653,7 +654,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
### Added
|
||||
|
||||
- Document warewulf.conf:paths. #635
|
||||
- New "Overlay" template variable contains the name of the overlay being built. #1052
|
||||
- New "Overlay" template variable contains the name of the overlay being built. #1052
|
||||
- Documented HTTP proxy environment variables for `wwctl container import`. #1214
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -213,12 +213,13 @@ func createOverlay() usecase.Interactor {
|
||||
|
||||
u := usecase.NewInteractor(func(ctx context.Context, input createOverlayInput, output *OverlayResponse) error {
|
||||
wwlog.Debug("api.createOverlay(Name:%v)", input.Name)
|
||||
newOverlay, err := overlay.Get(input.Name)
|
||||
if _, err := overlay.Get(input.Name); err == nil {
|
||||
// existing overlay, return a conflict error
|
||||
return status.Wrap(fmt.Errorf("%s overlay already exists", input.Name), status.AlreadyExists)
|
||||
}
|
||||
newOverlay, err := overlay.Create(input.Name)
|
||||
if err != nil {
|
||||
newOverlay, err = overlay.Create(input.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
*output = *NewOverlayResponse(newOverlay.Name())
|
||||
return nil
|
||||
|
||||
@@ -18,7 +18,8 @@ import (
|
||||
const sampleTemplate = `{{ if .Tags.email }}eMail: {{ .Tags.email }}{{else}} noMail{{- end }}
|
||||
`
|
||||
|
||||
var overlayTests = map[string]struct {
|
||||
var overlayTests = []struct {
|
||||
name string
|
||||
initFiles map[string]string
|
||||
request func(serverURL string) (*http.Request, error)
|
||||
response string
|
||||
@@ -26,7 +27,8 @@ var overlayTests = map[string]struct {
|
||||
resultFiles []string
|
||||
validateFiles map[string]string // file path -> expected content
|
||||
}{
|
||||
"get all overlays": {
|
||||
{
|
||||
name: "get all overlays",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -35,8 +37,8 @@ var overlayTests = map[string]struct {
|
||||
},
|
||||
response: `{"testoverlay":{"files":["/email.ww"], "site":false}}`,
|
||||
},
|
||||
|
||||
"get one specific overlay": {
|
||||
{
|
||||
name: "get one specific overlay",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -45,8 +47,8 @@ var overlayTests = map[string]struct {
|
||||
},
|
||||
response: `{"files":["/email.ww"], "site":false}`,
|
||||
},
|
||||
|
||||
"get overlay file": {
|
||||
{
|
||||
name: "get overlay file",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -62,8 +64,8 @@ var overlayTests = map[string]struct {
|
||||
"gid": "<<PRESENCE>>"
|
||||
}`,
|
||||
},
|
||||
|
||||
"update overlay file": {
|
||||
{
|
||||
name: "update overlay file",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -75,8 +77,8 @@ var overlayTests = map[string]struct {
|
||||
"/var/lib/warewulf/overlays/testoverlay/email.ww": "hello world",
|
||||
},
|
||||
},
|
||||
|
||||
"create an overlay": {
|
||||
{
|
||||
name: "create an overlay",
|
||||
request: func(serverURL string) (*http.Request, error) {
|
||||
return http.NewRequest(http.MethodPut, serverURL+"/api/overlays/test", nil)
|
||||
},
|
||||
@@ -85,8 +87,15 @@ var overlayTests = map[string]struct {
|
||||
"/var/lib/warewulf/overlays/test",
|
||||
},
|
||||
},
|
||||
|
||||
"get all overlays after creation": {
|
||||
{
|
||||
name: "create an overlay conflict",
|
||||
request: func(serverURL string) (*http.Request, error) {
|
||||
return http.NewRequest(http.MethodPut, serverURL+"/api/overlays/test", nil)
|
||||
},
|
||||
status: 409,
|
||||
},
|
||||
{
|
||||
name: "get all overlays after creation",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
"/var/lib/warewulf/overlays/test/rootfs/": "",
|
||||
@@ -97,8 +106,8 @@ var overlayTests = map[string]struct {
|
||||
},
|
||||
response: `{"test":{"files":null, "site":true},"testoverlay":{"files":["/email.ww"], "site":true}}`,
|
||||
},
|
||||
|
||||
"delete overlay file": {
|
||||
{
|
||||
name: "delete overlay file",
|
||||
initFiles: map[string]string{
|
||||
"/var/lib/warewulf/overlays/testoverlay/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -107,8 +116,8 @@ var overlayTests = map[string]struct {
|
||||
},
|
||||
response: `{"files":null, "site":true}`,
|
||||
},
|
||||
|
||||
"force delete site overlay": {
|
||||
{
|
||||
name: "force delete site overlay",
|
||||
initFiles: map[string]string{
|
||||
"/var/lib/warewulf/overlays/test/": "",
|
||||
},
|
||||
@@ -117,8 +126,8 @@ var overlayTests = map[string]struct {
|
||||
},
|
||||
response: `{"files":[], "site":true}`,
|
||||
},
|
||||
|
||||
"force delete distribution overlay": {
|
||||
{
|
||||
name: "force delete distribution overlay",
|
||||
initFiles: map[string]string{
|
||||
"/usr/share/warewulf/overlays/test/email.ww": sampleTemplate,
|
||||
},
|
||||
@@ -130,12 +139,12 @@ var overlayTests = map[string]struct {
|
||||
}
|
||||
|
||||
func TestOverlayAPI(t *testing.T) {
|
||||
for name, tt := range overlayTests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
warewulfd.SetNoDaemon()
|
||||
env := testenv.New(t)
|
||||
defer env.RemoveAll()
|
||||
warewulfd.SetNoDaemon()
|
||||
env := testenv.New(t)
|
||||
defer env.RemoveAll()
|
||||
|
||||
for _, tt := range overlayTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create test files
|
||||
for fileName, fileContent := range tt.initFiles {
|
||||
if strings.HasSuffix(fileName, "/") {
|
||||
|
||||
Reference in New Issue
Block a user