Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to detect if pkg file needs to be updated thro IMC reboot. #257

Merged
merged 2 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ipu-plugin/images/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2024 Intel Corporation
FROM golang:1.22.5-alpine@sha256:0d3653dd6f35159ec6e3d10263a42372f6f194c3dea0b35235d72aabde86486e as builder
FROM golang:1.22.5-alpine@sha256:0d3653dd6f35159ec6e3d10263a42372f6f194c3dea0b35235d72aabde86486e AS builder
RUN apk add --no-cache git
ARG TARGETOS
ARG TARGETARCH
Expand All @@ -13,7 +13,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o bi

FROM alpine:3@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
ARG P4_NAME
ENV P4_NAME $P4_NAME
ENV P4_NAME=$P4_NAME

COPY --from=builder /usr/src/ipu-opi-plugin/bin/ipuplugin /usr/bin/
COPY ${P4_NAME}/${P4_NAME}.pkg /
Expand Down
184 changes: 144 additions & 40 deletions ipu-plugin/pkg/ipuplugin/lifecycleservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ package ipuplugin
import (
"bytes"
"context"
"crypto/md5"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
math_rand "math/rand"
Expand Down Expand Up @@ -513,8 +515,6 @@ func setBaseMacAddr() (string, error) {
return macAddress, nil
}

// TODO: Replace pkg name->fxp-net_linux-networking.pkg, using
// a const variable in this function.
func (s *SSHHandlerImpl) sshFunc() error {
config := &ssh.ClientConfig{
User: "root",
Expand All @@ -539,15 +539,16 @@ func (s *SSHHandlerImpl) sshFunc() error {
defer sftpClient.Close()

// Open the source file.
localFilePath := "/fxp-net_linux-networking.pkg"
p4PkgName := os.Getenv("P4_NAME") + ".pkg"
localFilePath := "/" + p4PkgName
srcFile, err := os.Open(localFilePath)
if err != nil {
return fmt.Errorf("failed to open local file: %s", err)
}
defer srcFile.Close()

// Create the destination file on the remote server.
remoteFilePath := "/work/scripts/fxp-net_linux-networking.pkg"
remoteFilePath := "/work/scripts/" + p4PkgName
dstFile, err := sftpClient.Create(remoteFilePath)
if err != nil {
return fmt.Errorf("failed to create remote file: %s", err)
Expand Down Expand Up @@ -585,31 +586,7 @@ func (s *SSHHandlerImpl) sshFunc() error {
return fmt.Errorf("error from setBaseMacAddr()->%v", err)
}

//Note: Ensure pacakge name here matches with Makefile/Dockerfile in VSP similar to P4SDK
//Note: Ensure configureChannel/setIP according to host<->ACC comm_vports.
shellScript := fmt.Sprintf(`#!/bin/sh
CP_INIT_CFG=/etc/dpcp/cfg/cp_init.cfg
cd /work/scripts
echo "Checking for custom package..."
if [ -e fxp-net_linux-networking.pkg ]; then
echo "Custom package fxp-net_linux-networking.pkg found. Overriding default package"
cp fxp-net_linux-networking.pkg /etc/dpcp/package/
rm -rf /etc/dpcp/package/default_pkg.pkg
ln -s /etc/dpcp/package/fxp-net_linux-networking.pkg /etc/dpcp/package/default_pkg.pkg
sed -i 's/sem_num_pages = 1;/sem_num_pages = 256;/g' $CP_INIT_CFG
sed -i 's/lem_num_pages = 6;/lem_num_pages = 32;/g' $CP_INIT_CFG
sed -i 's/mod_num_pages = 1;/mod_num_pages = 2;/g' $CP_INIT_CFG
sed -i 's/cxp_num_pages = 1;/cxp_num_pages = 6;/g' $CP_INIT_CFG
sed -i 's/pf_mac_address = "00:00:00:00:03:14";/pf_mac_address = "%s";/g' $CP_INIT_CFG
sed -i 's/acc_apf = 4;/acc_apf = 16;/g' $CP_INIT_CFG
sed -i 's/comm_vports = .*/comm_vports = (([5,0],[4,0]),([0,3],[5,3]),([0,2],[4,3]));/g' $CP_INIT_CFG
sed -i 's/uplink_vports = .*/uplink_vports = ([0,0,0],[0,1,1],[4,1,0],[4,5,1],[5,1,0],[5,2,1]);/g' $CP_INIT_CFG
sed -i 's/rep_vports = .*/rep_vports = ([0,0,0],[4,5,1]);/g' $CP_INIT_CFG
sed -i 's/exception_vports = .*/exception_vports = ([0,0,0],[4,5,1]); /g' $CP_INIT_CFG
else
echo "No custom package found. Continuing with default package"
fi
`, macAddress) // Insert the MAC address variable into the script.
shellScript := genLoadCustomPkgFile(macAddress)

loadCustomPkgFilePath := "/work/scripts/load_custom_pkg.sh"
loadCustomPkgFile, err := sftpClient.Create(loadCustomPkgFilePath)
Expand Down Expand Up @@ -685,7 +662,46 @@ func countAPFDevices() int {
return len(pfList)
}

func checkIfMACIsSet() (bool, string) {
func genLoadCustomPkgFile(macAddress string) string {

p4PkgName := os.Getenv("P4_NAME") + ".pkg"
shellScript := fmt.Sprintf(`#!/bin/sh
CP_INIT_CFG=/etc/dpcp/cfg/cp_init.cfg
cd /work/scripts
echo "Checking for custom package..."
if [ -e %s ]; then
echo "Custom package %s found. Overriding default package"
cp %s /etc/dpcp/package/
rm -rf /etc/dpcp/package/default_pkg.pkg
ln -s /etc/dpcp/package/%s /etc/dpcp/package/default_pkg.pkg
sed -i 's/sem_num_pages = 1;/sem_num_pages = 256;/g' $CP_INIT_CFG
sed -i 's/lem_num_pages = 6;/lem_num_pages = 32;/g' $CP_INIT_CFG
sed -i 's/mod_num_pages = 1;/mod_num_pages = 2;/g' $CP_INIT_CFG
sed -i 's/cxp_num_pages = 1;/cxp_num_pages = 6;/g' $CP_INIT_CFG
sed -i 's/pf_mac_address = "00:00:00:00:03:14";/pf_mac_address = "%s";/g' $CP_INIT_CFG
sed -i 's/acc_apf = 4;/acc_apf = 16;/g' $CP_INIT_CFG
sed -i 's/comm_vports = .*/comm_vports = (([5,0],[4,0]),([0,3],[5,3]),([0,2],[4,3]));/g' $CP_INIT_CFG
sed -i 's/uplink_vports = .*/uplink_vports = ([0,0,0],[0,1,1],[4,1,0],[4,5,1],[5,1,0],[5,2,1]);/g' $CP_INIT_CFG
sed -i 's/rep_vports = .*/rep_vports = ([0,0,0],[4,5,1]);/g' $CP_INIT_CFG
sed -i 's/exception_vports = .*/exception_vports = ([0,0,0],[4,5,1]); /g' $CP_INIT_CFG
else
echo "No custom package found. Continuing with default package"
fi
`, p4PkgName, p4PkgName, p4PkgName, p4PkgName, macAddress)

return shellScript

}

/*
IMC reboot needed for following cases:

1. First time provisioning of IPU system(where MAC gets set in node policy)
2. Upgrade-for any update to P4 package.
3. Upgrade-for node policy. Other changes in node policy thro load_custom_pkg.sh.
Returns-> bool(returns false, if IMC reboot is required), string->for any error or success string.
*/
func skipIMCReboot() (bool, string) {
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
Expand All @@ -708,22 +724,110 @@ func checkIfMACIsSet() (bool, string) {
}
defer session.Close()

commands := "if [ -f /work/uuid ]; then echo 'File exists'; else echo 'File does not exist'; fi"
commands := "if [ -f /work/uuid ]; then cat /work/uuid; else echo 'File does not exist'; fi"

// Run a command on the remote server and capture the output.
var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf
err = session.Run(commands)
outputBytes, err := session.CombinedOutput(commands)
if err != nil {
return false, fmt.Sprintf("mac not found: %s", err)
}

output := stdoutBuf.String()
if output == "File exists\n" {
return true, "File exists"
p4pkgMatch := false
uuidFileExists := false
lcpkgFileMatch := false

outputStr := strings.TrimSuffix(string(outputBytes), "\n")

if outputStr == "File does not exist" {
log.Infof("UUID File does not exist")
} else {
log.Infof("UUID File exists, uuid->%v", outputStr)
uuidFileExists = true
}
if !uuidFileExists {
return false, "UUID File does not exist"
}

session, err = client.NewSession()
if err != nil {
log.Errorf("failed to create session: %v", err)
return false, fmt.Sprintf("failed to create session: %v", err)
}
defer session.Close()

//compute md5sum of pkg file on IMC
p4PkgName := os.Getenv("P4_NAME") + ".pkg"
commands = "cd /work/scripts; md5sum " + p4PkgName + " | awk '{print $1}'"
imcOutput, err := session.CombinedOutput(commands)
if err != nil {
log.Errorf("Error->%v, running command->%s:", err, commands)
return false, fmt.Sprintf("Error->%v, running command->%s:", err, commands)
}

//compute md5sum of pkg file in ipu-plugin container
commands = "md5sum /" + p4PkgName + " | awk '{print $1}'"
pluginOutput, err := utils.ExecuteScript(commands)
if err != nil {
log.Errorf("Error->%v, for md5sum command->%v", err, commands)
return false, fmt.Sprintf("Error->%v, for md5sum command->%v", err, commands)
}

if pluginOutput != string(imcOutput) {
log.Infof("md5sum mismatch, in ipu-plugin->%v, on IMC->%v", pluginOutput, string(imcOutput))
} else {
log.Infof("md5sum match, in ipu-plugin->%v, on IMC->%v", pluginOutput, string(imcOutput))
p4pkgMatch = true
}

if !p4pkgMatch {
return false, "md5sum mismatch"
}

genLcpkgFileStr := genLoadCustomPkgFile(outputStr)
log.Infof("loadCustomPkgFileStr->%v", genLcpkgFileStr)
genLcpkgFileHash := md5.Sum([]byte(genLcpkgFileStr))
genLcpkgFileHashStr := hex.EncodeToString(genLcpkgFileHash[:])

// Create an SFTP client.
sftpClient, err := sftp.NewClient(client)
if err != nil {
log.Errorf("failed to create SFTP client: %s", err)
return false, fmt.Sprintf("failed to create SFTP client: %s", err)
}
defer sftpClient.Close()

// destination file on IMC.
remoteFilePath := "/work/scripts/load_custom_pkg.sh"
dstFile, err := sftpClient.Open(remoteFilePath)
if err != nil {
log.Errorf("failed to create remote file: %s", err)
return false, fmt.Sprintf("failed to create remote file: %s", err)
}
defer dstFile.Close()

imcLcpkgFileBytes, err := io.ReadAll(dstFile)
if err != nil {
log.Errorf("failed to read load_custom_pkg.sh: %s", err)
return false, fmt.Sprintf("failed to read load_custom_pkg.sh: %s", err)
}

imcLcpkgFileHash := md5.Sum(imcLcpkgFileBytes)
imcLcpkgFileHashStr := hex.EncodeToString(imcLcpkgFileHash[:])

if genLcpkgFileHashStr != imcLcpkgFileHashStr {
log.Infof("load_custom md5 mismatch, generated->%v, on IMC->%v", genLcpkgFileHashStr, imcLcpkgFileHashStr)
} else {
return false, "File does not exist"
log.Infof("load_custom md5 match, generated->%v, on IMC->%v", genLcpkgFileHashStr, imcLcpkgFileHashStr)
lcpkgFileMatch = true
}

if !lcpkgFileMatch {
return false, "lcpkgFileMatch mismatch"
}

log.Infof("uuidFileExists->%v, p4pkgMatch->%v, lcpkgFileMatch->%v", uuidFileExists, p4pkgMatch, lcpkgFileMatch)
return true, fmt.Sprintf("checks pass, imc reboot not required")

}

func (e *ExecutableHandlerImpl) validate() bool {
Expand All @@ -732,8 +836,8 @@ func (e *ExecutableHandlerImpl) validate() bool {
in SetupAccApfs, prior to 1 interface(for Phy Port),
getting moved to p4 container in configureFxp */

if macPreFix, mac := checkIfMACIsSet(); !macPreFix {
fmt.Printf("incorrect Mac assigned : %v\n", mac)
if noReboot, infoStr := skipIMCReboot(); !noReboot {
fmt.Printf("IMC reboot required : %v\n", infoStr)
return false
}

Expand Down
Loading