Cloud API: expose directory and file customizations

Expose the Directory and File customizations in the Cloud API. Also
validate the provided customizations while processing the compose
request by trying to convert them to internal representations
`fsnode.File` and `fsnode.Directory`.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2023-02-06 13:38:55 +01:00 committed by Sanne Raymaekers
parent 15f1962c34
commit e9af3bda64
4 changed files with 387 additions and 124 deletions

View file

@ -187,6 +187,106 @@ func (h *apiHandlers) PostCompose(ctx echo.Context) error {
}
}
if request.Customizations != nil && request.Customizations.Directories != nil {
var dirCustomizations []blueprint.DirectoryCustomization
for _, d := range *request.Customizations.Directories {
dirCustomization := blueprint.DirectoryCustomization{
Path: d.Path,
}
if d.Mode != nil {
dirCustomization.Mode = *d.Mode
}
if d.User != nil {
dirCustomization.User = *d.User
if uid, ok := dirCustomization.User.(float64); ok {
// check if uid can be converted to int64
if uid != float64(int64(uid)) {
return fmt.Errorf("invalid user %f: must be an integer", uid)
}
dirCustomization.User = int64(uid)
}
}
if d.Group != nil {
dirCustomization.Group = *d.Group
if gid, ok := dirCustomization.Group.(float64); ok {
// check if gid can be converted to int64
if gid != float64(int64(gid)) {
return fmt.Errorf("invalid group %f: must be an integer", gid)
}
dirCustomization.Group = int64(gid)
}
}
if d.EnsureParents != nil {
dirCustomization.EnsureParents = *d.EnsureParents
}
dirCustomizations = append(dirCustomizations, dirCustomization)
}
// Validate the directory customizations, because the Cloud API does not use the custom unmarshaller
_, err := blueprint.DirectoryCustomizationsToFsNodeDirectories(dirCustomizations)
if err != nil {
return HTTPErrorWithInternal(ErrorInvalidCustomization, err)
}
if bp.Customizations == nil {
bp.Customizations = &blueprint.Customizations{
Directories: dirCustomizations,
}
} else {
bp.Customizations.Directories = dirCustomizations
}
}
if request.Customizations != nil && request.Customizations.Files != nil {
var fileCustomizations []blueprint.FileCustomization
for _, f := range *request.Customizations.Files {
fileCustomization := blueprint.FileCustomization{
Path: f.Path,
}
if f.Data != nil {
fileCustomization.Data = *f.Data
}
if f.Mode != nil {
fileCustomization.Mode = *f.Mode
}
if f.User != nil {
fileCustomization.User = *f.User
if uid, ok := fileCustomization.User.(float64); ok {
// check if uid can be converted to int64
if uid != float64(int64(uid)) {
return fmt.Errorf("invalid user %f: must be an integer", uid)
}
fileCustomization.User = int64(uid)
}
}
if f.Group != nil {
fileCustomization.Group = *f.Group
if gid, ok := fileCustomization.Group.(float64); ok {
// check if gid can be converted to int64
if gid != float64(int64(gid)) {
return fmt.Errorf("invalid group %f: must be an integer", gid)
}
fileCustomization.Group = int64(gid)
}
}
fileCustomizations = append(fileCustomizations, fileCustomization)
}
// Validate the file customizations, because the Cloud API does not use the custom unmarshaller
_, err := blueprint.FileCustomizationsToFsNodeFiles(fileCustomizations)
if err != nil {
return HTTPErrorWithInternal(ErrorInvalidCustomization, err)
}
if bp.Customizations == nil {
bp.Customizations = &blueprint.Customizations{
Files: fileCustomizations,
}
} else {
bp.Customizations.Files = fileCustomizations
}
}
if request.Customizations != nil && request.Customizations.Filesystem != nil {
var fsCustomizations []blueprint.FilesystemCustomization
for _, f := range *request.Customizations.Filesystem {

View file

@ -293,9 +293,11 @@ type ContainerUploadStatus struct {
// Customizations defines model for Customizations.
type Customizations struct {
Containers *[]Container `json:"containers,omitempty"`
Filesystem *[]Filesystem `json:"filesystem,omitempty"`
Packages *[]string `json:"packages,omitempty"`
Containers *[]Container `json:"containers,omitempty"`
Directories *[]Directory `json:"directories,omitempty"`
Files *[]File `json:"files,omitempty"`
Filesystem *[]Filesystem `json:"filesystem,omitempty"`
Packages *[]string `json:"packages,omitempty"`
// Extra repositories for packages specified in customizations. These
// repositories will only be used to depsolve and retrieve packages
@ -314,6 +316,24 @@ type Customizations struct {
Users *[]User `json:"users,omitempty"`
}
// A custom directory to create in the final artifact.
type Directory struct {
// Ensure that the parent directories exist
EnsureParents *bool `json:"ensure_parents,omitempty"`
// Group of the directory as a group name or a gid
Group *interface{} `json:"group,omitempty"`
// Permissions string for the directory in octal format
Mode *string `json:"mode,omitempty"`
// Path to the directory
Path string `json:"path"`
// Owner of the directory as a user name or a uid
User *interface{} `json:"user,omitempty"`
}
// Error defines model for Error.
type Error struct {
// Embedded struct due to allOf(#/components/schemas/ObjectReference)
@ -333,6 +353,27 @@ type ErrorList struct {
Items []Error `json:"items"`
}
// A custom file to create in the final artifact.
type File struct {
// Contents of the file as plain text
Data *string `json:"data,omitempty"`
// Ensure that the parent directories exist
EnsureParents *bool `json:"ensure_parents,omitempty"`
// Group of the file as a gid or a group name
Group *interface{} `json:"group,omitempty"`
// Permissions string for the file in octal format
Mode *string `json:"mode,omitempty"`
// Path to the file
Path string `json:"path"`
// Owner of the file as a uid or a user name
User *interface{} `json:"user,omitempty"`
}
// Filesystem defines model for Filesystem.
type Filesystem struct {
MinSize uint64 `json:"min_size"`
@ -809,124 +850,129 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
"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",
"o4hIwguPomH2wfn+4/8HAAD//3wEUOAObwAA",
"H4sIAAAAAAAC/+x9eXPiuLb4V1HxflXdXWFfEpKqqfuAkIQAWYCsQ1eesGVbYEuOJLNkqr/7ryQv2GAS",
"Mrdn7rv39fwxwbZ0dHR0ztHZpP4jo1HHpQQRwTMnf2RcyKCDBGLBk4nkXx1xjWFXYEoyJ5kbaCKAiY6W",
"mWwGLaHj2ijRfA5tD2VOMqXMjx/ZDJZ9Xj3EVplshkBHflEtsxmuWciBsotYufI9FwwTU3Xj+C1l7CvP",
"mSAGqAGwQA4HmAAENQsEAOPYhAAibIrFnfiotu/h8yP8qEA3HobtVrllU4JaknxcDeQy6iImsD88Q6ZC",
"eQtWNsMtyNDLAgvrBWoa9QLaB8hnTn7PlMqVau3wqH5cLJUz37MZNdlUWMELyBhcqekx9OphhnQJJsDh",
"e9SMTqZIE7KfP4U716ZQv1bU5e/NIcItg7zcAnGRK2Wyf+fMshlOoMstKl78NYvj5Kxy4ddtrNJpko7r",
"R5QaCii8FEJBBycxgg7OFbV6pXh0XDk6qtWOa3p1kkaxT5J4YzJy3OwHyzysfLDKrjexsebLmgE9W2RO",
"DGhzlN2QvY4BOBJAUKA+g6/CQiDoApSUfcsCCGxKzCygE8PjGhRIB3eD3phgDhgSHiNIz4OO4AAtXcyg",
"BA0cbFoCTBDglBLEgLAgAQZlgAoLMeAp9MdEQGYiwfNjMiZrXATzkByWW5QJxORoIDYYgEQfE5wcEHMg",
"cefQQQByNZR8jg8H1qOtV2FCqY0g+efXbb8V28VtHrPTdWZ8CNkoFf6bx9AHHIEdaKJIzjY0sCQaNRTB",
"fFIhHagOcl2B43G1lB7Br57cJlRDE88RAQxx6jENAZNRz82rVZSDyPWgDhaSWQxGHdVFzgVxIZeWQaJT",
"B1CCwARypANKAAR3d51TgPmYmIggJjnNX6uEWlCIpcmdTTUoghVMTrAXfAkn6TI6x3KSIfovCv0sWFiI",
"IdVEjSI50LN1NfmQLpDIbibmAjGF3wVdSKa1MRcA2jYI0eAnY2IJ4fKTQkGnGs87WGOUU0PkNeoUEMl5",
"vKDZuADl8hUChfWPOUaL39SrnGbjnA0F4uK/4Fuo0V7kQC/RIF8UySXG4StJekIF4C7SsIGRngVYyJc6",
"0j0tsSA76LBJdCkByJPslK7u4n3f564ku+xB7k1URtTTIBkEYM7ViGmbljeJUHjB+jZSnVOJUrzZn0Cm",
"imp6fVLWcnBSruaq1VIld1zUarnDUrlSPET14jEqp2EnEIFEvIOXRMJvtB9WAQsamOhqrX0JVWoB3FAm",
"oL0PL4Z8KPAc5XTMkCYoWxUMj+jQQURAm299zVl0kRM0J4fO+ShvEKmmHSGjNjnMlbSKkavqsJiDh+Vy",
"rjgpHhbLlWP9SD/6ULmuKba9tlsc+IGK3KWCkxpyH5WzgWQMQBoKcduySfWVHIUSdG1kTn7/I/P/GDIy",
"J5n/KqyN90JgnhZSbNMf3zcgDhB3KfGtVmjbe0C9VpgNkIEYIhrK/MhuUURPUqJUriBp6eVQ/XiSK5X1",
"Sg5Wa4e5avnwsFarVovFYjGTzRiUOVBkTjKep5bnA6rpKdSKZrderD8/qffaJ1jCH9anZ0f/D6KkP6Ue",
"NflPnZTi94mHbd1/3rD7AxSymWXOpLngJSYCMQNq6I8faR7BjE6V2f0eZl06xWou6QIYIPQuKfqQYANx",
"8VPp4cSB/vPE2JjcGvr7M0MC6lDAnzkxygVD6EWjjoNF6p711YLc+hZuXXIFBAiap+x/LtRm0PRhb8Yh",
"1BffmMJEsz0dExNcte8HjUzMs3xvPgGMiBBphN1Nv4Fvo25vD5rHBXXwG4wM7PeQaCVb/8hmdCwJMPHE",
"lo/BLGTn6mmE8hmarVF6b8iObByiv9k5yZOfAfNnJXSLgRMEiFH8Z6j4NMXEI7gfTjfU/9lEV/RJoq2h",
"pNFsT3wk6daA9uuTIOS9io1tEj8AlJzg+5rEB9dmjLJtadCRgNiWPyXR9JiikzrNRMz3DCBPjZdtb1xR",
"4y0E/PlIgSGeo6biaRrici4GxLbHpGHmIiIVhZzQWq7WDbcEq0WJgJiglJm94yILCjyOotiCFgJZO1Q7",
"fVPfQA3grsFGXKzCHgmYggLkTJCeMKZ9x5Ot8sErZb2rQU8ENFN9DZu/zBHDxmp7UpIKjNpg1BsC1QYb",
"OHChY4OqaMxWuGSTv/z5pdq94ZS2IhRQ17F8gPZNbAmCQNXeqxItB0MqNrUmoSLMhjtCubIPUkkFze0h",
"RtD85Ai+x55qrX1Em5gq3J80OjaD3SGJ+al6H+7JofmwFedZT4aSwEf3eSweJVsTKQhUJYc6uz29Sg8g",
"bdDm1YOrPKYFZxVEMwrBepy8Q7XNEFg2nHIqt21t0xvbeDjd/ZX7WlmkqPbQE8af2C1OQ+85DaCB7U+A",
"OsM22gllxQVyPgUq6JICMG6zxWL/LuXCZIh/Lu7vwpVkkheGXMrxmnpJrmovBYMg3kZJYojJOsAFMAFJ",
"8ywPRhbiaEwSvRfYtgEl9kqFTzjSpZLVkcupPUdBYE8wjOYoGmRMQuG/HgIsOLINFSRf+cAIVZFROIfY",
"hhN7rYwUUwNGqQCUjQkkqyAU7UIm4nayDlxG5Tb1TeEcDvzCkeDAwMjWQ5hb08EcYJNQFgam9lrlQQgh",
"lfk4YnOsoc+rIC5nnxLP6mFf5YSAFcX91mCyClMNceTXysLADC2gna6sHUw6fpfS9jQQ+QQ6fuMPsSGG",
"kO34J5FJ0/rxCNZH6zWMt5X6l39Gdd3xNK2VhtNaJ20RrREIF4iifpJs/mYYxhoNTKANIBPYgJrw+THJ",
"I4hwj6EXF7IwMf1+aqqt2gNhQeHHqlVHENO3AC1xfMuIpXJ2hKJVvDiUvvVsIAcwiEir3AVl8hlvmF5U",
"ZSLXEbtNLti2gKUt61A9Ld+OmIM5l6oK+AAizbFGCxNANQFtEISB4tgUj2q1dNdaWGlutbBCCzOCn4BX",
"QEIrOCsds9RNn/uWchLq9YL4efsUasoeMWJ6P4OYG6aAmmqaCRC5LD/Ln9SCNdyiS8ILkj1gLOGQkijZ",
"zx1Sw0XNNwCnu2xqylK57T9t1TrFdw7Vyl76xSf1R6ErH1Q65sqA2a1ypB3zZ7RNGALbdngk/iHTKuiQ",
"A9eGEjJapoar/kLN9YGTtZ8iC2ehdFagvCJl9i/RYQqjd9XXYbX659SXBJ2muYL3f0Z1rennhfSL1Nff",
"p7XOEhb7RmQZk5ew9ilCp1QsV5PhZA8TcVhVBon0rVyKiUgaMYU5ZB/6WLHO2fXQaTift24+KDuYeNoM",
"id1JYUh8WZDcMxw1rk4bg1MwFJRBEwHNhpyDpgKR3ywDCB5ywQg7o6fpkQNpapOUmA52XMpEkOZX5UQ6",
"aFHH9QQCbWJiEsR48mMyinKyCtBGlcQCCyvQVuetG2nkS6JlwcLCmiVNd+l/JL0LBSsoVZHD+7jkQcdI",
"5vOj8okx+aL5oTKWgy7Ojb1isaJ5HtbVL/QllMtgOMnkIoH1Z8or1uUx26SUU/S/xxLW0ZyUqzSJEVfQ",
"OH0NRp2AnqrkKCIllM9YV9DD6oY8GCIEwly2ZlNPz5uUmkEsjPuso5LchahIIqhLSRZFqKiIZwucCzCP",
"Cig0m3LERahy/NjWmHwNahdC9vQZM+r2TZJZsyhHBEBPUAcKrEHbXm0SGXmfqLNL918Cuqh5g7C5xFdB",
"SXJyGvsq9syPSRtqVsgkiupBeATAiFKRmgyGARLzPLhXGPiqnQPI0MmYAJADX6TqPPkDORDbWP/x5QQ0",
"CFBPAOo6Q5z7GyNDLkNcbcbRWJoEATamlQdnlIGAelnwBdpYQ/8di39+yQcjB05dw+/3SRz8oQMQu8Z2",
"Vjnlxeeg6/43dF3uUpE3g05hnzhKah/+LDWC+YelOBKvDRLoDiY8lQY6dSAmJ3/4f+WASjzB0MMCAf8t",
"+Ooy7EC2+rY9uG37A6pInnQ1/dWHIui7SZG16H2RO+eXDZzSpe591gzLl3zlIBkVQLIak5C+SWn6Xe3w",
"J1tckYmCGSE/7Lt4mcDqOtkmcyabCQgcf/mXFPNGW+vPK1dRNrKE/7JZjgC5hogOichNGMR6rlKs1EqV",
"Dw2FGLjsR9UvibTidrEt0ywskCY8tjGdZf3w5bC6e3v3X++RnRutXKRyan42+6M+18ORbKVmnAxS/oQw",
"m7/Jv1B3r1xy0sTaqheOky5BlQ3Uv4ersIujUOg3751rjNy/T+dagyxlRIr9ACSrddJTnBvT/FT6MJtR",
"IVn/p4+Z/zss+AxyjFu8GOOw2FBwIYeBC56zYI5ZHg6eYj85dKPHNx8Zv/Yz/jLeCukmykWlFcFTmJ8I",
"XmDCBbRt9cLUXP//IQBTSmCkItTfRAdMxRq+/7AGL583GzO4iMDNuSvNv1QadYPCgfTE3lriz5BOGcy1",
"pGmXa0K+wxi1EeQbPcvFcrF4XDzKF1MNLMTmvi+47hHakTM6xXlDDRwotTxlpnpteZNEJRbD6blDPttU",
"q9VyNiUpPkeMb5WAVD6uLw/QXw8VnHRZQ1xTJU0BR1VTKTuJ3I6DVD5RFT5bERzis4Pfchf4XYpFCdU+",
"1EkLTIdRrSTIGSbpQbbwwNI24UMHevuLoALaaZ82qKAGzUYnnfwDRn7n7M4gVzYTbCWpqUhERGpGtaEO",
"PShnMQuwOhmRjdw46TQaSGiWNNsDKHnQcVwbo8Cg/B+P2f8jO3AkpNu3QLadHRPf+wz9sQiYE9RKqeRY",
"Pj3x60exUmJqkEhYCKv0FgzKvsDXYKFPQLF8WKxOyjo8RMe16kSvVCf1Sb0M65UaqsGjI708OSwaBvyW",
"9WMvEwaJZuVsPEOARfURa3jMQnahXvANg4JUeN82HKztFukqxNiuw9qjm8Wdj2OAp0gg5mCCuHSIA9L4",
"Xlui6NyBBJqIga8aJLqNXCzdSB0RgcXKP/Pisx8QVFnAvsegPoQGRh60KOGegxjQJHOpGo4w2xmuMuRA",
"szEiYqONhciYRLwU8YH0zkPG2nFaZueJlW3+3wiwbwmCFSzFtomXLuM7hD+tqigQWTVCmmxuFgumWqap",
"SCCX7vgSbmnvbVrbuxM2Hb226xOBoWW8w8FI+RDbaD4orveNxZ27SdYnQoSjtLBi9u2WRlh/kzxkYNPz",
"0xf5MWkIIGEKdfAniCt8mUCOPGZ/kQ42lhaljblQT0hAG5PZF7BeExWmGJMJWjuVKkLmUBZCdABkaNPn",
"pEz3QxkuQxrSlU7BfEzih8bkuFJWJnSO0pIKAaLpJoSmkzxDugX9IxWB9BR0zEVBapb6WrVIOJQXKC/s",
"YVloFtJmL6ZrxhYyniBwzRlKWYTzm3MwQ6uozEEy0bp0QkUmk1okoUFz8r9m+7xzBW7Ob8DNXbPXaYFu",
"+wk0e9etrvo8JmPi3HaumucNbajRZrtx2jPqTxcz9HZ5CHW7/7Q4gufnHfsS2qJ+OS0vC81y98DqGB1v",
"eS7c++kRGpPewDy9OzqcwlHNvT+tOWf9y4o7QwQNCtrIeX29nV2tbrn1WKa3j4v2291wUmpd9VtG69yc",
"PdZvy2Py9jxjHa3Fzoq35QXrTmzo6dbdAb6HpHHKnVL9qf3KJ7XGXeVIF3esX7l90h/M48HBI74x7uuD",
"Mek2p6NiZX7fvNb7Q/5UOe7BFjnsuKXruVvvtGmhg9r3T6VXp3V904Dd4uTyouIZZrXloRk/GA3HZHH7",
"MEKt3tJ77h1e9x/p9U13Me/fGsuJWXo8rc+952JXTAva1UV5Cb3i0uEN7/ji0kWz+fXNYGmPyepVTFfP",
"BqP3GJ2t3MWzOb9dCEL69YI5bHuFy/sReyrWyk77bnTU0iZH1Zl2cTY6M/ozm8zOC2NSNO6qjQGsFasX",
"leW0OBMTVJl3tZtHenPtdZv3/GI4Lxbvzp8aqxvkrQ7qR9pd4alt9Y9mleF9dzomh6jzbK5w/7q4sEtP",
"56eDrubZixk/bhx49sws0dGkyitvzvP8pnh0TkfLh2p5Cru1h+HBlfWM0JjUD4uP9N6aaKWuOzyYGs90",
"yllbPNdvJnfPB0/zs/rAZfpDg00vJpez8qU76DaWI2vJbxu8aZ2XxqTY85blB9hvFs1yp3aj9fXLgvY6",
"pcW6prFp89HDyweGa9g77j+69ddRwRi+XTlc75ikXnh97o4Jrt96tuEdHXmv1kNhIcoTQbAwB/x1ai37",
"3vTprvo8qVozcVa3uneFx8ejavnV6tW6i8agcdtojok4PTt/fhjMNadtdk/7pe6wUX927meTyqXVG/VL",
"vcfmCj6ULI3YjfC9dnE5h879VG/V5mOiOdoBvr28bjb7zVajUT3D7Ta6OHSYdXZx5N3z216/Xy4+1bRn",
"iyyf6mcNR8lQ63xRP2stZp0xaS4652e39LLV4K1m86nVWLRbF2a7dVZtNFrm7Hbd++DqqVE4aj65pr0a",
"Np6fLqzpqmuNSeHAOHy7Me7nk4tysf1amXWOrs+aV0XSezxo3pUcbz48eB15w8pDjzUrTuXcs4XbHbQv",
"uz3h1NqnY1Ji52+PDToqrdzjp0691zjV+63W9WramHL6cFc/errzWgeFCZmyERqUe4PrlrG6aR0dPhzX",
"a/j6fkyc2vBgwm9PF0etco/ZeqNf7Z96dPVcGmJxDp+r3dvevTgYtWGpivnT8Lw1faNHN0/1+8rl9axW",
"HBPz9cGsl68KE6fcfhsejeqVh/bppGTPp9WOPV+andcuMkult8enpcOehs+Xly1j/mYc2FfDQ29pXozJ",
"dFm4LK7s53IPT87Z4Xmjsbo+vntgjefhYtgvtrXpqL5ot8hyNjz1Vq/Ow+J+ftV89Nqd+/o1qjyNSR/f",
"lYzLqzrXj05dfras9Q8eddInt8ODCzYd3XRPK84Dsxs6aY8s/em+Pn2euQ/W6YpXCsfH6HpMrFmR9ciq",
"OL1azKBnFPBd/Vo7fJz3Z9PeoH9p1u6O77urS+/hQbwtHsm0f1V7GJw1X7tV/kydfn9MDDEZXZQOaqvJ",
"4KHQqMybE7gcPJTF0d3b1VR7Q7PhcxvD3tVxr3ChXbY6g9LtWf2wXj7VG3b77Fgfk1nZvMVPw9sGhJfF",
"y8vG28V8MBtc9npmt/x0+4Qvru5XZVG5XJ0ZnEGnthi2Hq4N6wZ1Vr3m6PlyTObMvbJvJsjgo+Pa0cgo",
"N686nvn2zFq1++XpsDt7NgdW6f58PuzcktbqbXa7OmzflV9vXPxQO5Y6yrrpPD6zLtW6lW5veFzAb5e3",
"o4Etpv3Gb2Py240xOhoTtbu0r07f23pSA4KqGO6Fczt9qwzNifT92zc9eEoUIOz3D7lb/uZ/z1XKY69Y",
"LB9K0+i3KEj50Wa+tm+2kYhwkJ/zGiKCcjX+PwJD7Ld6jguGoBMbGcr/H1b9Nwq/JuToergHLvFKw9QE",
"rfQIgkbAL0dU/tnaZgCQS7OCA6xyZes8jqpyHJOvLnaRjQn6llrxuBXJDyuz6SfLSX+uS5b0usAOpyuT",
"WhK/5V8MN0r9NpwLTeC5X9oTGHHJCzCQxpDIyU+x5XQh5wvKUqsipWX5kmqibluoe7AIJhyb1saFH7tK",
"VSgzIQkKcDfjctVipVxN96b3uKXCD31DGxg2NMOMPbM0+TOMzPqZWlU/ESbZoc0pgPYCrnhQ5MlBJ5jR",
"Bu/tmpMfdNumaJxh8pL9YoT9kK4b7leCbtlNnkjgEFvg2OKk+bXbZy3Iau+TxhsJh+yHfTbvI/moy1bd",
"yIdjbN9w8VGXHcdOfnzPbtUvYB4eq2cI2n55uCryARNPgO35SRUBldJAAlBjTFLIlgcKroMgCUJy0LZB",
"SkPgLxofE+m1Kp71ldLWuDBqGzD4HFN1bMJ3cCXCY8I8G/nl7wwZlKEsWCBgwXlU6aIYAagiDTm7CQJw",
"AcNyNXVRBPkixsSlnOOJX3zn4KWKCDlQaJbvaQdUBoKaSpVKeYrYblccOJbv+szB92TWZ39u3LPHZqb1",
"E7y4Z4/0Uz6qtO7zea8oc7ZP5tPvGKQ+dx0JDOI/4ep831jHT2bQmEfIrjRZHJ20PFmeV6KUVZgOW6ef",
"UiHytDN8Kn+fTNaudbf6mHrV1daxzc09mXMrh/RyrVY6Bo1Go9GqXL3BVsl+Pu2UrkbtmnzXuWLn3Tbr",
"P+GDfv9u4V3AQePSGfRo521glF9Py/pp7a3YHC0Lh8s0JLYTYh5H7OP80I7Mu9rENI9hsRpKpvAJ1ESQ",
"+YSbqF9n4YZ1+TAKL01TW6HfLoIqLQn/6jRMDLptNQ6D+hlBA1NP1bH5CUO/vINLy8nGGgruqghua2u4",
"ULMQKKvUndpuI8N8sVjkofqsrOGgLy/0Oq321bCdK+eLeUs4tlpBLBTJrodNNXyQrWZAFYoB6OJYhPMk",
"U874ddtEfjjJVPLFfCnjV6EqMhU0mxLEC39g/Yfiq7RSxnPkl/n68qSKGkEgBIAyIKXSRiI8EOefFVVp",
"EomZqnvDPDjrHjNNKVNVMOtyPVUBLe1TJX5IR3o+Xhve0X1U4rdmZBN3//2eftdMcK2Mj7ygwFTFlOpG",
"PVWrGl2oF5zSDTnON5nW1+v99MstvquLXdSlJmoxysViLGumbBrXtYMDq4VpUFq/RuhdjRyjkmLnJGXi",
"NJEsUv2JQwc1E9uDdoi/7wecAbDuD13664dueKrAeoaU94N9RPzRK3/96HcEesKiDL/5HpeLmOQNEPG2",
"j0n178BkRuiCbCxB7e9Y/TuCli5S13OpOhxANc1jUtLiKlxJcai8f/8uZYR7jgPZKijEjSshpbwiflJw",
"Clrsbkuadmq45R+0gICgRdg1C1wqp46VcaxRwoOKbXWSbo4YDJW70vdBCbO6xNMvocUM6Eh2CcpxtxTX",
"DeUivNrIVzKIi/CSpJ8j8cnrPX4kt0+pzH5s6ZvSzx69o6ctffARWJDL9WMC6f8ypcPWF3/80jy/NM+e",
"midQGmma5mcZT5+wl0IafmAoJW6f2ctUigD/HzOWEpRK4aAkXX4ZTL/U1r+pwbRTf/mOYNxqSrFf4vcz",
"7qVPYsrqf5EW+Qtsr82bL/9u6yvtnswUllKHAtFifQ5lglSFpX/tT7peE2gpCur8cBKflNvm99Ne1Z81",
"QJps/kjs2pIsiROY7wiAHZQO/5ld3MAEcyu2iYN393As1lt3VnkUKiruIAEBJj4PY0oAnFBPhNcKe7Z4",
"b5tXlc+/NvkPN/ngXs1U0ZAsEB2U9a//jhxETAChKu2LNc+GLDgZCL4Ki3qmFaQ0LofXV9/y/3GCdK5O",
"gZphgjzk8jQxStwR+q4sRS33EKeBuhmfq6rK6KIviYzywQN1RuJ3sOeBOvoZNdaoEiweHbP3l09HBlY3",
"7gsQD8cGl3b51RGQhJd45UJw+do7ori+e/WXPH4oj2ti7RDKxHJvCeZ/pqwlxWMPoYtVd78vc9E5CCly",
"W3Lmn1FHS6iJxEYU/cMUOnIR0fn6Jj0la1HoX52cfk8yQjx/CcbHghFd77tDLsKl/Ixc/HJSfzmp/9uc",
"1C3dlKbvFPC4TbGlYtY3RG0pl7SZrZsU1HG3XSUOsXbqPNxfKvrrOaRxu39pODVAQIxfYvavETOf0f/9",
"hAxGDARtG0T1TyE3rcXs44g2JH7RA9GiU04+Zus7fCYroLbOdEHdP36Egub/1K5f+Zv38J1LqT6A+Ltf",
"UvxLij8jxWibg6TkRkU+u3fI66BJOt8nkQ3AKXmWnrWkQXjP3b+hbfHudH5EddBpmqgfXChEdU/zb8GK",
"LipIlnFBF+flONzCwb86BV3s312fU9EDxHLhbWaFeVlZHBvFZQKamJjvDcAFNNE/OYwiIgkvPIqG+QjO",
"9x//PwAA//+8fVvneXUAAA==",
}
// GetSwagger returns the content of the embedded swagger specification file

View file

@ -976,8 +976,18 @@ components:
containers:
type: array
items:
$ref: '#/components/schemas/Container'
description: Container images to embed into the final artfact
$ref: '#/components/schemas/Container'
description: Container images to embed into the final artfact
directories:
type: array
items:
$ref: '#/components/schemas/Directory'
description: Directories to create in the final artifact
files:
type: array
items:
$ref: '#/components/schemas/File'
description: Files to create in the final artifact
subscription:
$ref: '#/components/schemas/Subscription'
packages:
@ -1037,6 +1047,72 @@ components:
type: boolean
description: Control TLS verifification
example: true
Directory:
type: object
description: |
A custom directory to create in the final artifact.
required:
- path
properties:
path:
type: string
description: Path to the directory
example: '/etc/mydir'
mode:
type: string
description: Permissions string for the directory in octal format
example: "0755"
user:
oneOf:
- type: string
- type: integer
description: Owner of the directory as a user name or a uid
example: 'root'
group:
oneOf:
- type: string
- type: integer
description: Group of the directory as a group name or a gid
example: 'root'
ensure_parents:
type: boolean
description: Ensure that the parent directories exist
default: false
File:
type: object
description: |
A custom file to create in the final artifact.
required:
- path
properties:
path:
type: string
description: Path to the file
example: '/etc/myfile'
mode:
type: string
description: Permissions string for the file in octal format
example: "0644"
user:
oneOf:
- type: string
- type: integer
description: Owner of the file as a uid or a user name
example: 'root'
group:
oneOf:
- type: string
- type: integer
description: Group of the file as a gid or a group name
example: 'root'
data:
type: string
description: Contents of the file as plain text
ensure_parents:
type: boolean
description: Ensure that the parent directories exist
example: true
default: false
Filesystem:
type: object
required:

View file

@ -927,7 +927,48 @@ func TestComposeCustomizations(t *testing.T) {
"disabled": [
"firewalld"
]
}
},
"directories": [
{
"path": "/etc/my/dir",
"mode": "0700"
},
{
"path": "/etc/my/dir1",
"mode": "0700",
"user": "user1",
"group": "user1",
"ensure_parents": true
},
{
"path": "/etc/my/dir2",
"mode": "0700",
"user": 1000,
"group": 1000,
"ensure_parents": true
}
],
"files": [
{
"path": "/etc/my/dir/file",
"mode": "0600",
"data": "Hello world!"
},
{
"path": "/etc/my/dir/file2",
"mode": "0600",
"user": "user1",
"group": "user1",
"data": "Hello world!"
},
{
"path": "/etc/my/dir/file3",
"mode": "0600",
"user": 1000,
"group": 1000,
"data": "Hello world!"
}
]
},
"image_request":{
"architecture": "%s",