Skip to content

Commit d2db358

Browse files
logonoffclaude
andcommitted
Fix devfile parsing failure for devfiles with parent registry references
When parsing devfiles with parent references (e.g. devfile-sample-go-basic which has parent.id: go from registry.devfile.io), the devfile library resolves the parent by downloading registry resources and copying them to the directory containing the devfile. When raw bytes are passed via the Data field, the parser has no absPath set, so it defaults to the process working directory. In the console container, WORKDIR is / and the process runs as user 1001, so mkdir fails with "permission denied". Fix by writing devfile content to a temp directory and passing the file path to the parser instead of raw bytes. This gives the parser a writable absPath for resolving parent/plugin resources. The temp directory is cleaned up after each request. Also add an early return when devfile content is empty to avoid unnecessary temp directory creation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e6e8b8c commit d2db358

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

pkg/devfile/handler.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"encoding/json"
55
"fmt"
66
"net/http"
7+
"os"
78
"path"
9+
"path/filepath"
810
"strings"
911

1012
"github.com/openshift/console/pkg/serverutils"
@@ -48,11 +50,38 @@ func DevfileHandler(w http.ResponseWriter, r *http.Request) {
4850
return
4951
}
5052

51-
// Get devfile content and parse it using a library call in the future
53+
if data.Devfile.DevfileContent == "" {
54+
errMsg := "Devfile content is empty"
55+
klog.Error(errMsg)
56+
serverutils.SendResponse(w, http.StatusBadRequest, serverutils.ApiError{Err: errMsg})
57+
return
58+
}
59+
60+
// Write devfile content to a temp directory so the parser has a writable
61+
// absPath for resolving parent/plugin registry resources. Without this,
62+
// the parser defaults to the process working directory which is read-only
63+
// in production container images.
5264
devfileContentBytes := []byte(data.Devfile.DevfileContent)
65+
tmpDir, err := os.MkdirTemp("", "console-devfile-*")
66+
if err != nil {
67+
errMsg := fmt.Sprintf("Failed to create temp directory for devfile parsing: %v", err)
68+
klog.Error(errMsg)
69+
serverutils.SendResponse(w, http.StatusInternalServerError, serverutils.ApiError{Err: errMsg})
70+
return
71+
}
72+
defer os.RemoveAll(tmpDir)
73+
74+
tmpDevfilePath := filepath.Join(tmpDir, "devfile.yaml")
75+
if err = os.WriteFile(tmpDevfilePath, devfileContentBytes, 0600); err != nil {
76+
errMsg := fmt.Sprintf("Failed to write temp file for devfile parsing: %v", err)
77+
klog.Error(errMsg)
78+
serverutils.SendResponse(w, http.StatusInternalServerError, serverutils.ApiError{Err: errMsg})
79+
return
80+
}
81+
5382
//reduce the http request and response timeouts on the devfile library parser to 10s
5483
httpTimeout := 10
55-
devfileObj, _, err = devfile.ParseDevfileAndValidate(parser.ParserArgs{Data: devfileContentBytes, HTTPTimeout: &httpTimeout})
84+
devfileObj, _, err = devfile.ParseDevfileAndValidate(parser.ParserArgs{Path: tmpDevfilePath, HTTPTimeout: &httpTimeout})
5685
if err != nil {
5786
errMsg := "Failed to parse devfile:"
5887
if strings.Contains(err.Error(), "schemaVersion not present in devfile") {

0 commit comments

Comments
 (0)