Ajout mise à jour des ACL, du propriétaire du template et suppression de l'image si elle existe
This commit is contained in:
parent
eba2e447e6
commit
c315bcf66b
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Cadoles/goca"
|
"github.com/Cadoles/goca"
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/common"
|
||||||
|
@ -17,11 +18,17 @@ type Config struct {
|
||||||
User string
|
User string
|
||||||
Password string
|
Password string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
ImageName string `mapstructure:"image_name"`
|
ImageName string `mapstructure:"image_name"`
|
||||||
ImageTemplate []string `mapstructure:"image_template"`
|
ImageTemplate []string `mapstructure:"image_template"`
|
||||||
DatastoreName string `mapstructure:"datastore_name"`
|
DatastoreName string `mapstructure:"datastore_name"`
|
||||||
MergeTemplate bool `mapstructure:"merge_template"`
|
MergeTemplate int `mapstructure:"merge_template"`
|
||||||
ctx interpolate.Context
|
DeleteIfExists bool `mapstructure:"delete_if_exists"`
|
||||||
|
ACL map[string]int `mapstructure:"acl"`
|
||||||
|
Owner *struct {
|
||||||
|
User string
|
||||||
|
Group string
|
||||||
|
} `mapstructure:"owner"`
|
||||||
|
ctx interpolate.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostProcessor is an OpenNebula post processor for packer
|
// PostProcessor is an OpenNebula post processor for packer
|
||||||
|
@ -52,21 +59,53 @@ func (pp *PostProcessor) PostProcess(ui packer.Ui, a packer.Artifact) (packer.Ar
|
||||||
return a, true, err
|
return a, true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.Say(fmt.Sprintf("Connecting to OpenNebula RPC endpoint '%s' with provided credentials...", pp.Conf.Endpoint))
|
||||||
|
|
||||||
// Search image template by its name
|
// Search image template by its name
|
||||||
img, err := goca.NewImageFromName(pp.Conf.ImageName)
|
img, err := goca.NewImageFromName(pp.Conf.ImageName)
|
||||||
if err != nil && err.Error() != "resource not found" {
|
if err != nil && err.Error() != "resource not found" {
|
||||||
return a, true, err
|
return a, true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("Connecting to OpenNebula RPC endpoint '%s' with provided credentials...", pp.Conf.Endpoint))
|
if img != nil {
|
||||||
|
|
||||||
|
// Retreive info about the template
|
||||||
|
if err := img.Info(); err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
state, err := img.State()
|
||||||
|
if err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
inUse := state == goca.ImageUsed || state == goca.ImageLockUsed
|
||||||
|
|
||||||
|
if inUse {
|
||||||
|
ui.Say(fmt.Sprintf("Template '%s' is in use. Cannot delete it.", pp.Conf.ImageName))
|
||||||
|
}
|
||||||
|
|
||||||
|
if pp.Conf.DeleteIfExists && !inUse {
|
||||||
|
|
||||||
|
ui.Say(fmt.Sprintf("Deleting template '%s'...", pp.Conf.ImageName))
|
||||||
|
|
||||||
|
if err := img.Delete(); err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
img = nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Generate image template
|
// Generate image template
|
||||||
tmplStr := serializeImageTemplate(pp.Conf.ImageTemplate)
|
tmplStr := serializeImageTemplate(pp.Conf.ImageTemplate)
|
||||||
|
|
||||||
// Fi the image template can not be found, we create it
|
// If the image template can not be found, we create it
|
||||||
if img == nil {
|
if img == nil {
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("The OpenNebula image template '%s' could not be found. Creating it...", pp.Conf.ImageName))
|
ui.Say(fmt.Sprintf("Creating template '%s'...", pp.Conf.ImageName))
|
||||||
|
|
||||||
// Search image datastore's ID
|
// Search image datastore's ID
|
||||||
datastore, err := goca.NewDatastoreFromName(pp.Conf.DatastoreName)
|
datastore, err := goca.NewDatastoreFromName(pp.Conf.DatastoreName)
|
||||||
|
@ -75,13 +114,21 @@ func (pp *PostProcessor) PostProcess(ui packer.Ui, a packer.Artifact) (packer.Ar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create image template
|
// Create image template
|
||||||
if _, err = goca.CreateImage(tmplStr, datastore.ID); err != nil {
|
imageID, err := goca.CreateImage(tmplStr, datastore.ID)
|
||||||
|
if err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
img = goca.NewImage(imageID)
|
||||||
|
|
||||||
|
// Retreive info about the template
|
||||||
|
if err := img.Info(); err != nil {
|
||||||
return a, true, err
|
return a, true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("The OpenNebula image template '%s' has been found. Updating it...", pp.Conf.ImageName))
|
ui.Say(fmt.Sprintf("Updating template '%s'...", pp.Conf.ImageName))
|
||||||
|
|
||||||
// Update image template
|
// Update image template
|
||||||
if err := img.Update(tmplStr, pp.Conf.MergeTemplate); err != nil {
|
if err := img.Update(tmplStr, pp.Conf.MergeTemplate); err != nil {
|
||||||
|
@ -90,6 +137,48 @@ func (pp *PostProcessor) PostProcess(ui packer.Ui, a packer.Artifact) (packer.Ar
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pp.Conf.Owner != nil {
|
||||||
|
|
||||||
|
currentUserName, userFound := img.XPath("/IMAGE/UNAME")
|
||||||
|
currentGroupName, groupFound := img.XPath("/IMAGE/GNAME")
|
||||||
|
|
||||||
|
isSameUser := userFound && currentUserName == pp.Conf.Owner.User
|
||||||
|
isSameGroup := groupFound && currentGroupName == pp.Conf.Owner.Group
|
||||||
|
|
||||||
|
userID := -1
|
||||||
|
groupID := -1
|
||||||
|
|
||||||
|
if pp.Conf.Owner.User != "" && !isSameUser {
|
||||||
|
user, err := goca.NewUserFromName(pp.Conf.Owner.User)
|
||||||
|
if err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
userID = int(user.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pp.Conf.Owner.Group != "" && !isSameGroup {
|
||||||
|
group, err := goca.NewGroupFromName(pp.Conf.Owner.Group)
|
||||||
|
if err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
groupID = int(group.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Say(fmt.Sprintf("Updating template '%s' owner...", pp.Conf.ImageName))
|
||||||
|
if err := img.Chown(userID, groupID); err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if pp.Conf.ACL != nil {
|
||||||
|
ui.Say(fmt.Sprintf("Updating template '%s' ACL...", pp.Conf.ImageName))
|
||||||
|
chmodOptions := aclToChmodOptions(pp.Conf.ACL)
|
||||||
|
if err := img.Chmod(chmodOptions); err != nil {
|
||||||
|
return a, true, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui.Say("Operation completed.")
|
ui.Say("Operation completed.")
|
||||||
|
|
||||||
return a, true, nil
|
return a, true, nil
|
||||||
|
@ -99,3 +188,30 @@ func (pp *PostProcessor) PostProcess(ui packer.Ui, a packer.Artifact) (packer.Ar
|
||||||
func serializeImageTemplate(tmpl []string) string {
|
func serializeImageTemplate(tmpl []string) string {
|
||||||
return strings.Join(tmpl, "\n")
|
return strings.Join(tmpl, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func aclToChmodOptions(acl map[string]int) goca.ImageChmodOptions {
|
||||||
|
chmodOptions := goca.NewImageChmodOptions()
|
||||||
|
for key, val := range acl {
|
||||||
|
switch key {
|
||||||
|
case "user_use":
|
||||||
|
chmodOptions.UserUse = val
|
||||||
|
case "user_manage":
|
||||||
|
chmodOptions.UserManage = val
|
||||||
|
case "user_admin":
|
||||||
|
chmodOptions.UserAdmin = val
|
||||||
|
case "group_use":
|
||||||
|
chmodOptions.GroupUse = val
|
||||||
|
case "group_manage":
|
||||||
|
chmodOptions.GroupManage = val
|
||||||
|
case "group_admin":
|
||||||
|
chmodOptions.GroupAdmin = val
|
||||||
|
case "other_use":
|
||||||
|
chmodOptions.OtherUse = val
|
||||||
|
case "other_manage":
|
||||||
|
chmodOptions.OtherManage = val
|
||||||
|
case "other_admin":
|
||||||
|
chmodOptions.OtherAdmin = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chmodOptions
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue