Skip to content

Commit

Permalink
packet: reports status to packet api
Browse files Browse the repository at this point in the history
Posts state and status of ignition
to metadata.packet.net api, and
engine.Run() now returns an error.
  • Loading branch information
Bubblemelon committed Jun 30, 2018
1 parent 49776fd commit e1b840a
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 89 deletions.
11 changes: 6 additions & 5 deletions config/shared/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ var (
ErrInvalidNetworkdDropinExt = errors.New("invalid networkd drop-in extension")

// Misc errors
ErrInvalidScheme = errors.New("invalid url scheme")
ErrInvalidUrl = errors.New("unable to parse url")
ErrHashMalformed = errors.New("malformed hash specifier")
ErrHashWrongSize = errors.New("incorrect size for hash sum")
ErrHashUnrecognized = errors.New("unrecognized hash function")
ErrInvalidScheme = errors.New("invalid url scheme")
ErrInvalidUrl = errors.New("unable to parse url")
ErrHashMalformed = errors.New("malformed hash specifier")
ErrHashWrongSize = errors.New("incorrect size for hash sum")
ErrHashUnrecognized = errors.New("unrecognized hash function")
ErrEngineConfiguration = errors.New("engine incorrectly configured")
)

// NewNoInstallSectionError produces an error indicating the given unit, named
Expand Down
2 changes: 1 addition & 1 deletion internal/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func DiskByPartUUIDDir() string { return diskByPartUUIDDir }
func OEMDevicePath() string { return fromEnv("OEM_DEVICE", oemDevicePath) }

func KernelCmdlinePath() string { return kernelCmdlinePath }
func SystemConfigDir() string { return fromEnv("SYSTEM_CONFIG_DIR", systemConfigDir) }
func SystemConfigDir() string { return fromEnv("SYSTEM_CONFIG_DIR", "/home/core") }
func OEMLookasideDir() string { return fromEnv("OEM_LOOKASIDE_DIR", oemLookasideDir) }

func ChrootCmd() string { return chrootCmd }
Expand Down
13 changes: 7 additions & 6 deletions internal/exec/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ type Engine struct {

// Run executes the stage of the given name. It returns true if the stage
// successfully ran and false if there were any errors.
func (e Engine) Run(stageName string) (bool, string) {
func (e Engine) Run(stageName string) (bool, error) {
if e.Fetcher == nil || e.Logger == nil {
fmt.Fprintf(os.Stderr, "engine incorrectly configured\n")
return false, "engine incorrectly configured"
err := errors.ErrEngineConfiguration
return false, err
}
baseConfig := types.Config{
Ignition: types.Ignition{Version: types.MaxVersion.String()},
Expand All @@ -72,7 +73,7 @@ func (e Engine) Run(stageName string) (bool, string) {
e.logReport(r)
if err != nil && err != providers.ErrNoProvider {
e.Logger.Crit("failed to acquire system base config: %v", err)
return false, "failed to acquire system base config: " + err.Error()
return false, err
}

cfg, err := e.acquireConfig()
Expand All @@ -84,17 +85,17 @@ func (e Engine) Run(stageName string) (bool, string) {
e.logReport(r)
if err != nil && err != providers.ErrNoProvider {
e.Logger.Crit("failed to acquire default config: %v", err)
return false, "failed to acquire default config: " + err.Error()
return false, err
}
default:
e.Logger.Crit("failed to acquire config: %v", err)
return false, "failed to acquire config: " + err.Error()
return false, err
}

e.Logger.PushPrefix(stageName)
defer e.Logger.PopPrefix()

return stages.Get(stageName).Create(e.Logger, e.Root, *e.Fetcher).Run(config.Append(baseConfig, config.Append(systemBaseConfig, cfg))), "Valid Ignition Config"
return stages.Get(stageName).Create(e.Logger, e.Root, *e.Fetcher).Run(config.Append(baseConfig, config.Append(systemBaseConfig, cfg))), err
}

// acquireConfig returns the configuration, first checking a local cache
Expand Down
20 changes: 14 additions & 6 deletions internal/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,23 @@ func main() {
OEMConfig: oemConfig,
Fetcher: &fetcher,
}
ignSuccess, message := engine.Run(flags.stage.String())
ignSuccess, err := engine.Run(flags.stage.String())

if !ignSuccess {
// ignition fails
logger.Info("Ignition Fails")
oemConfig.Status(ignSuccess, message)
logger.Warning("Ignition failed")
logger.Err(err.Error())
statusErr := engine.OEMConfig.Status(*engine.Fetcher, err)
if statusErr != nil {
logger.Err("Status error: ", statusErr.Error())
}
os.Exit(1)

} else {
logger.Info("Ignition Passes")
oemConfig.Status(ignSuccess, message)
logger.Info("Ignition finished successfully")
// err should be nil
statusErr := engine.OEMConfig.Status(*engine.Fetcher, err)
if statusErr != nil {
logger.Err("Status error: ", statusErr.Error())
}
}
}
24 changes: 13 additions & 11 deletions internal/oem/oem.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Config struct {
name string
fetch providers.FuncFetchConfig
newFetcher providers.FuncNewFetcher
status providers.FuncStatusFetcher
status providers.FuncPostStatus
}

func (c Config) Name() string {
Expand All @@ -64,16 +64,17 @@ func (c Config) NewFetcherFunc() providers.FuncNewFetcher {

// Status takes b as whether ignition passes (true) or fails
// msg is the error or success message
func (c Config) Status(b bool, msg string) providers.FuncStatusFetcher {
rf := resource.Fetcher{}
if !b {
packet.FetchStatus(rf, msg)
func (c Config) Status(f resource.Fetcher, status error) error {

return c.status
}
packet.FetchStatus(rf, msg)
if c.status != nil {

return c.status
err := c.status(f, status)
if err != nil {
f.Logger.Err("Error: ", err)
}
return err
}
return nil

}

Expand Down Expand Up @@ -126,8 +127,9 @@ func init() {
fetch: noop.FetchConfig,
})
configs.Register(Config{
name: "packet",
fetch: packet.FetchConfig,
name: "packet",
fetch: packet.FetchConfig,
status: packet.PostStatus,
})
configs.Register(Config{
name: "pxe",
Expand Down
106 changes: 53 additions & 53 deletions internal/providers/packet/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ package packet
import (
"bytes"
"encoding/json"
"fmt"
"log"

"net/http"
"net/url"
"strings"
Expand All @@ -41,7 +40,7 @@ var (
)

var (
MetadataUrl = url.URL{
metadataUrl = url.URL{
Scheme: "https",
Host: "metadata.packet.net",
Path: "metadata",
Expand All @@ -52,6 +51,7 @@ func FetchConfig(f resource.Fetcher) (types.Config, report.Report, error) {
// Packet's metadata service returns "Not Acceptable" when queried
// with the default Accept header.
headers := resource.ConfigHeaders
f.Logger.Info("FETCH CONFIG")
headers.Set("Accept", "*/*")
data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
Headers: headers,
Expand All @@ -63,101 +63,101 @@ func FetchConfig(f resource.Fetcher) (types.Config, report.Report, error) {
return util.ParseConfig(f.Logger, data)
}

// FetchStatus is invoked by oem.Status() when igintion fails
// POSTS if s==fail, a message to Packet's provision setup Timeline
func FetchStatus(f resource.Fetcher, s string) error {

type Message struct {
Message string `json:"message"`
}
// PostStatus posts a message that will show on the Packet Instance Timeline
func PostStatus(f resource.Fetcher, errMsg error) error {

f.Logger.Info("POST message to Packet Timeline")
// fetch JSON from https://metadata.packet.net/metadata
data, err := f.FetchToBuffer(MetadataUrl, resource.FetchOptions{
data, err := f.FetchToBuffer(metadataUrl, resource.FetchOptions{
Headers: nil,
})
if data == nil {
log.Fatalf("data is nil")
return err
}

if err != nil {
fmt.Println("Error: ", err)
return err
}

type Metadata struct {
metadata := struct {
PhoneHomeURL string `json:"phone_home_url"`
}

metadata := Metadata{}
}{}

err = json.Unmarshal(data, &metadata)
if err != nil {
fmt.Println("Error: ", err)
return err

}

phonehomeURL := metadata.PhoneHomeURL
// to get phonehome IP
// to get phonehome IPv4
phonehomeURL = strings.TrimSuffix(phonehomeURL, "/phone-home")

// POST Message to phonehome IP
postMessageURL := phonehomeURL + "/events"

// Place message into report struct
if s != "Valid Ignition Config" {
m := Message{
Message: "Ignition error: " + s,
}
// Marshall Message
messageJSON, err := json.Marshal(m)
if errMsg != nil {

err = postMessage(errMsg, f, "Ignition error: "+errMsg.Error(), postMessageURL)
if err != nil {
fmt.Println("Error: ", err)
return err
}
// POST Message
err = postMessage(messageJSON, postMessageURL)

} else {

err = postMessage(errMsg, f, "Ignition: valid config", postMessageURL)
if err != nil {
fmt.Println("Error: ", err)
return err
}

} else {
}
return err
}

fmt.Println("IGNTION STATUS PASS")
// postMessage makes a post request with the supplied message to the url
func postMessage(e error, f resource.Fetcher, message string, url string) error {

m := Message{
Message: "Ignition: valid config",
}
type mStruct struct {
State string `json:"state"`
Message string `json:"message"`
}

// Marshall Message
messageJSON, err := json.Marshal(m)
if err != nil {
fmt.Println("Error: ", err)
m := mStruct{}

if e != nil {

m = mStruct{
State: "succeeded",
Message: message,
}
// POST Message
err = postMessage(messageJSON, postMessageURL)
if err != nil {
fmt.Println("Error: ", err)

} else {

m = mStruct{
State: "succeeded",
Message: message,
}

}

return err
}

// postMessage(): POST message in JSON to API URL
func postMessage(message []byte, url string) error {
// Marshall Message
messageJSON, err := json.Marshal(m)
if err != nil {
return err
}

postReq, err := http.NewRequest("POST", url, bytes.NewBuffer(message))
postReq, err := http.NewRequest("POST", url, bytes.NewBuffer(messageJSON))
if err != nil {
fmt.Println("Error: ", err)
return err
}
postReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}

respPost, err := client.Do(postReq)
if err != nil {
fmt.Println("Error: ", err)
panic(err)
return err
}
defer respPost.Body.Close()

return err

}
2 changes: 1 addition & 1 deletion internal/providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ var (

type FuncFetchConfig func(f resource.Fetcher) (types.Config, report.Report, error)
type FuncNewFetcher func(logger *log.Logger) (resource.Fetcher, error)
type FuncStatusFetcher func(f resource.Fetcher, s string) (report.Report, error)
type FuncPostStatus func(f resource.Fetcher, e error) error
1 change: 0 additions & 1 deletion internal/resource/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ func (f *Fetcher) newHttpClient() {
// code, a cancel function for the result's context, and error (if any). By
// default, User-Agent is added to the header but this can be overridden.
func (c HttpClient) getReaderWithHeader(url string, header http.Header) (io.ReadCloser, int, context.CancelFunc, error) {

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, 0, nil, err
Expand Down
14 changes: 9 additions & 5 deletions internal/resource/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,16 @@ func (f *Fetcher) FetchFromTFTP(u url.URL, dest *os.File, opts FetchOptions) err
// FetchFromHTTP fetches a resource from u via HTTP(S) into dest, returning an
// error if one is encountered.
func (f *Fetcher) FetchFromHTTP(u url.URL, dest *os.File, opts FetchOptions) error {
// loging := log.New(true)
// loging.Info("%+v", f)

if f.client == nil {
logger := log.New(true)
f.Logger = &logger
f.newHttpClient()
}
// if f.client == nil {
// logger := log.New(true)
// f.Logger = &logger
// f.newHttpClient()
// }

// loging.Info("%+v", f)

dataReader, status, ctxCancel, err := f.client.getReaderWithHeader(u.String(), opts.Headers)
if ctxCancel != nil {
Expand Down

0 comments on commit e1b840a

Please sign in to comment.