Skip to content

Commit

Permalink
MGMT-12329: Implements assisted boot reporter and add to ignition
Browse files Browse the repository at this point in the history
Implements: openshift#4444
  • Loading branch information
Nir Magnezi committed Jan 29, 2023
1 parent 1224cdd commit 6fab269
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 53 deletions.
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func main() {
failOnError(err, "failed to create valid bm config S3 endpoint URL from %s", Options.BMConfig.S3EndpointURL)
Options.BMConfig.S3EndpointURL = newUrl

generator := generator.New(log, objectHandler, Options.GeneratorConfig, Options.WorkDir, operatorsManager, providerRegistry, Options.ClusterTLSCertOverrideDir)
generator := generator.New(log, objectHandler, Options.GeneratorConfig, Options.WorkDir, operatorsManager, providerRegistry, Options.ClusterTLSCertOverrideDir, authHandler)
var crdUtils bminventory.CRDUtils
if ctrlMgr != nil {
crdUtils = controllers.NewCRDUtils(ctrlMgr.GetClient(), hostApi)
Expand Down
1 change: 1 addition & 0 deletions internal/bminventory/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3555,6 +3555,7 @@ func (b *bareMetalInventory) getLogFileForDownload(ctx context.Context, clusterI
if err != nil {
return "", "", err
}
b.log.Debugf("log type to download: %s", logsType)
switch logsType {
case string(models.LogsTypeHost), string(models.LogsTypeNodeBoot):
if hostId == nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/bminventory/inventory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ var (
imageServiceHost = "image-service.example.com:8080"
imageServiceBaseURL = fmt.Sprintf("https://%s%s", imageServiceHost, imageServicePath)
fakePullSecret = `{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"dG9rZW46dGVzdAo=\",\"email\":\"coyote@acme.com\"}}}"` // #nosec
serviceBaseURL = "https://assisted.example.com:6008"
)

func toMac(macStr string) *strfmt.MAC {
Expand Down Expand Up @@ -15211,6 +15212,7 @@ func createInventoryWithEventStream(db *gorm.DB, cfg Config, stream eventstream.
mockStaticNetworkConfig, gcConfig, mockProviderRegistry, true)

bm.ImageServiceBaseURL = imageServiceBaseURL
bm.ServiceBaseURL = serviceBaseURL
return bm
}

Expand Down
6 changes: 3 additions & 3 deletions internal/bminventory/inventory_v2_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,12 +461,12 @@ func (b *bareMetalInventory) v2uploadLogs(ctx context.Context, params installer.
}()

if params.LogsType == string(models.LogsTypeHost) || params.LogsType == string(models.LogsTypeNodeBoot) {
if params.InfraEnvID == nil || params.HostID == nil {
if common.StrFmtUUIDPtr(params.ClusterID) == nil || params.HostID == nil {
return common.NewApiError(http.StatusInternalServerError,
errors.Errorf("infra_env_id and host_id are required for upload %s logs", params.LogsType))
errors.Errorf("cluster_id and host_id are required for upload %s logs", params.LogsType))
}

dbHost, err := common.GetHostFromDB(b.db, params.InfraEnvID.String(), params.HostID.String())
dbHost, err := common.GetClusterHostFromDB(b.db, params.ClusterID.String(), params.HostID.String())
if err != nil {
return err
}
Expand Down
21 changes: 18 additions & 3 deletions internal/cluster/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,27 @@ import (
"github.com/pkg/errors"
)

func AgentToken(infraEnv *common.InfraEnv, authType auth.AuthType) (token string, err error) {
func AgentToken(resource interface{}, authType auth.AuthType) (token string, err error) {
var (
pullSecret string
resId string
)
switch res := resource.(type) {
case *common.InfraEnv:
resId = res.ID.String()
pullSecret = res.PullSecret
case *common.Cluster:
resId = res.ID.String()
pullSecret = res.PullSecret
default:
return "", errors.New("internal error")
}

switch authType {
case auth.TypeRHSSO:
token, err = cloudPullSecretToken(infraEnv.PullSecret)
token, err = cloudPullSecretToken(pullSecret)
case auth.TypeLocal:
token, err = gencrypto.LocalJWT(infraEnv.ID.String(), gencrypto.InfraEnvKey)
token, err = gencrypto.LocalJWT(resId, gencrypto.InfraEnvKey)
case auth.TypeNone:
token = ""
default:
Expand Down
6 changes: 5 additions & 1 deletion internal/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,11 @@ func (m *Manager) PrepareClusterLogFile(ctx context.Context, c *common.Cluster,
if hostObject.Bootstrap {
role = string(models.HostRoleBootstrap)
}
tarredFilename = fmt.Sprintf("%s_%s_%s.tar.gz", sanitize.Name(c.Name), role, sanitize.Name(hostutil.GetHostnameForMsg(hostObject)))
name := sanitize.Name(hostutil.GetHostnameForMsg(hostObject))
if strings.Contains(file, "boot_") {
name = fmt.Sprintf("boot_%s", name)
}
tarredFilename = fmt.Sprintf("%s_%s_%s.tar.gz", sanitize.Name(c.Name), role, name)
}
} else {
tarredFilename = fmt.Sprintf("%s_%s", fileNameSplit[len(fileNameSplit)-2], fileNameSplit[len(fileNameSplit)-1])
Expand Down
106 changes: 106 additions & 0 deletions internal/ignition/boot-reporter/assisted-boot-reporter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bash

export LOG_SEND_FREQUENCY_IN_MINUTES=5
export SERVICE_TIMEOUT_MINUTES=60

function log() {
echo "$(date '+%F %T') ${HOSTNAME} $2[$$]: level=$1 msg=\"$3\""
}

function log_info() {
log "info" "$1" "$2"
}

function log_error() {
log "error" "$1" "$2"
}

function init_variables() {
func_name=${FUNCNAME[0]}
init_failed="false"

if [ "$LOG_SEND_FREQUENCY_IN_MINUTES" == "" ]; then
init_failed="true"
log_error "${func_name}" "LOG_SEND_FREQUENCY_IN_MINUTES is empty."
fi

if [ "$SERVICE_TIMEOUT_MINUTES" == "" ]; then
init_failed="true"
log_error "${func_name}" "SERVICE_TIMEOUT_MINUTES is empty."
fi

if [ "$ASSISTED_SERVICE_URL" == "" ]; then
init_failed="true"
log_error "${func_name}" "ASSISTED_SERVICE_URL is empty."
elif [ "${ASSISTED_SERVICE_URL: -1}" == "/" ]; then
export ASSISTED_SERVICE_URL="${ASSISTED_SERVICE_URL::-1}"
fi

if [ "$CLUSTER_ID" == "" ]; then
init_failed="true"
log_error "${func_name}" "CLUSTER_ID is empty."
fi

if [ "$HOST_ID" == "" ]; then
init_failed="true"
log_error "${func_name}" "HOST_ID is empty."
fi

if [ "$init_failed" == "true" ]; then
log_error "${func_name}" "Failed to initialize variables. Exiting."
exit 1
fi
}

function collect_and_upload_logs() {
func_name=${FUNCNAME[0]}

log_info "${func_name}" "Collecting logs."
logs_dir_name=boot_logs_$HOST_ID
logs_path=/tmp/$logs_dir_name

rm -rf "$logs_path"
mkdir -p "$logs_path"

log_info "${func_name}" "Copying journalctl to $logs_path/"
journalctl > "$logs_path"/journalctl.log
log_info "${func_name}" "Capturing the output of 'ip a' to $logs_path/"
ip a > "$logs_path"/ip_a.log
log_info "${func_name}" "Copying /etc/resolv.conf to $logs_path/"
cp /etc/resolv.conf "$logs_path"
log_info "${func_name}" "Copying /var/log/pods to $logs_path/"
cp -r /var/log/pods "$logs_path"
log_info "${func_name}" "Compressing logs to $logs_path.tar.gz"
tar -czvf "$logs_path".tar.gz -C /tmp "$logs_dir_name"

log_info "${func_name}" "Uploading logs."

if curl -X POST -H "X-Secret-Key: ${PULL_SECRET_TOKEN}" \
-F upfile=@"$logs_path".tar.gz \
"$ASSISTED_SERVICE_URL/api/assisted-install/v2/clusters/$CLUSTER_ID/logs?logs_type=node-boot&host_id=$HOST_ID" ; then
log_info "${func_name}" "Successfully uploaded logs."
else
log_error "${func_name}" "Failed to upload logs."
fi
}

function main() {
func_name=${FUNCNAME[0]}
count=$((SERVICE_TIMEOUT_MINUTES/LOG_SEND_FREQUENCY_IN_MINUTES))

for i in $(seq $count)
do
log_info "${func_name}" "Upload logs attempt ${i}/${count}"
collect_and_upload_logs
if [ "$i" != "$count" ]; then # don't sleep at the last iteration.
log_info "${func_name}" "Sleeping for ${LOG_SEND_FREQUENCY_IN_MINUTES} minutes until the next attempt."
sleep $((LOG_SEND_FREQUENCY_IN_MINUTES*60))
fi
done
}

log_info assisted-boot-reporter "assisted-boot-reporter start"
init_variables
main
log_info assisted-boot-reporter "assisted-boot-reporter end"
exit 0
23 changes: 13 additions & 10 deletions internal/ignition/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,32 @@ import (
"github.com/openshift/assisted-service/internal/common"
"github.com/openshift/assisted-service/internal/host/hostutil"
"github.com/openshift/assisted-service/models"
"github.com/openshift/assisted-service/pkg/auth"
"github.com/openshift/assisted-service/pkg/s3wrapper"
"github.com/sirupsen/logrus"
)

type dummyGenerator struct {
log logrus.FieldLogger
workDir string
cluster *common.Cluster
s3Client s3wrapper.API
log logrus.FieldLogger
serviceBaseURL string
workDir string
cluster *common.Cluster
s3Client s3wrapper.API
}

// NewDummyGenerator returns a Generator that creates the expected files but with nonsense content
func NewDummyGenerator(workDir string, cluster *common.Cluster, s3Client s3wrapper.API, log logrus.FieldLogger) Generator {
func NewDummyGenerator(serviceBaseURL string, workDir string, cluster *common.Cluster, s3Client s3wrapper.API, log logrus.FieldLogger) Generator {
return &dummyGenerator{
workDir: workDir,
log: log,
cluster: cluster,
s3Client: s3Client,
workDir: workDir,
log: log,
serviceBaseURL: serviceBaseURL,
cluster: cluster,
s3Client: s3Client,
}
}

// Generate creates the expected ignition and related files but with nonsense content
func (g *dummyGenerator) Generate(_ context.Context, installConfig []byte, platformType models.PlatformType) error {
func (g *dummyGenerator) Generate(_ context.Context, installConfig []byte, platformType models.PlatformType, authType auth.AuthType) error {
toUpload := fileNames[:]
for _, host := range g.cluster.Hosts {
toUpload = append(toUpload, hostutil.IgnitionFileName(host))
Expand Down

0 comments on commit 6fab269

Please sign in to comment.