Blame tools/extra/packager/gbs.py

Packit 534379
# Copyright(c) 2017, Intel Corporation
Packit 534379
#
Packit 534379
# Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
# modification, are permitted provided that the following conditions are met:
Packit 534379
#
Packit 534379
# * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
#  this list of conditions and the following disclaimer.
Packit 534379
# * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
#  this list of conditions and the following disclaimer in the documentation
Packit 534379
#   and/or other materials provided with the distribution.
Packit 534379
# * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
#   may be used to  endorse or promote  products derived  from this  software
Packit 534379
#   without specific prior written permission.
Packit 534379
#
Packit 534379
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
# IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
# ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
# LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
# CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
# SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
# INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
# CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
# POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
import os
Packit 534379
import json
Packit 534379
import struct
Packit 534379
from metadata import constants
Packit 534379
from metadata import metadata
Packit 534379
Packit 534379
RBF_EXT = ".rbf"
Packit 534379
GBS_EXT = ".gbs"
Packit 534379
Packit 534379
"""
Packit 534379
Class GBS for operations related to GBS files
Packit 534379
"""
Packit 534379
Packit 534379
Packit 534379
class GBS:
Packit 534379
    def __init__(self, gbs_file=None):
Packit 534379
        self.guid = ''
Packit 534379
        self.metadata_len = 0
Packit 534379
        self.gbs_info = ''
Packit 534379
        self.rbf = ''
Packit 534379
        self.metadata = []
Packit 534379
Packit 534379
        if gbs_file:
Packit 534379
            self.filename = os.path.splitext(os.path.basename(gbs_file))[0]
Packit 534379
            self.validate_gbs_file(gbs_file)
Packit 534379
Packit 534379
    """
Packit 534379
    classmethod to create a gbs instance from json and
Packit 534379
    rbf file. Used to create a new gbs file
Packit 534379
Packit 534379
    @return instance of the new GBS object
Packit 534379
    """
Packit 534379
    @classmethod
Packit 534379
    def create_gbs_from_afu_info(cls, rbf_file, afu_json):
Packit 534379
        gbs = cls()
Packit 534379
Packit 534379
        rbf = open(rbf_file, 'rb')
Packit 534379
        rbf_content = rbf.read()
Packit 534379
Packit 534379
        gbs.guid = constants.METADATA_GUID
Packit 534379
        gbs.metadata_len = len(afu_json)
Packit 534379
        gbs.gbs_info = afu_json
Packit 534379
        gbs.rbf = rbf_content
Packit 534379
        gbs.metadata = metadata.get_metadata(afu_json)
Packit 534379
        gbs.filename = os.path.splitext(os.path.basename(rbf_file))[0]
Packit 534379
Packit 534379
        return gbs
Packit 534379
Packit 534379
    """
Packit 534379
    Set of get methods to retrieve gbs attributes
Packit 534379
    """
Packit 534379
Packit 534379
    def get_gbs_guid(self):
Packit 534379
        return self.guid
Packit 534379
Packit 534379
    def get_gbs_meta_len(self):
Packit 534379
        return self.metadata_len
Packit 534379
Packit 534379
    def get_gbs_info(self):
Packit 534379
        return self.gbs_info
Packit 534379
Packit 534379
    def get_rbf_val(self):
Packit 534379
        return self.rbf
Packit 534379
Packit 534379
    def get_gbs_metadata(self):
Packit 534379
        return self.metadata
Packit 534379
Packit 534379
    """
Packit 534379
    Function to print GBS info to the console
Packit 534379
    """
Packit 534379
Packit 534379
    def print_gbs_info(self):
Packit 534379
        if self.gbs_info == '':
Packit 534379
            raise Exception("No metadata in GBS file")
Packit 534379
Packit 534379
        print(json.dumps(self.gbs_info, indent=4))
Packit 534379
Packit 534379
    """
Packit 534379
    Function to write a new rbf file to the filesystem
Packit 534379
    """
Packit 534379
Packit 534379
    def write_rbf(self, rbf_file):
Packit 534379
        if not rbf_file:
Packit 534379
            rbf_file = self.filename + RBF_EXT
Packit 534379
Packit 534379
        with open(rbf_file, 'wb') as rbf:
Packit 534379
            rbf.write(self.rbf)
Packit 534379
Packit 534379
        return rbf_file
Packit 534379
Packit 534379
    """
Packit 534379
    Function to write a new gbs file to the filesystem
Packit 534379
    """
Packit 534379
Packit 534379
    def write_gbs(self, gbs_file):
Packit 534379
        if not gbs_file:
Packit 534379
            gbs_file = self.filename + GBS_EXT
Packit 534379
Packit 534379
        decoded_bytes = [c if isinstance(c, int) else ord(c)
Packit 534379
                         for c in self.get_gbs_metadata()]
Packit 534379
        gbs_file_header = bytearray(decoded_bytes)
Packit 534379
Packit 534379
        with open(gbs_file, 'wb') as gbs:
Packit 534379
            gbs.write(gbs_file_header + self.rbf)
Packit 534379
Packit 534379
        return gbs_file
Packit 534379
Packit 534379
    """
Packit 534379
    Function to update gbs info in an object with input info
Packit 534379
    """
Packit 534379
Packit 534379
    def update_gbs_info(self, gbs_info):
Packit 534379
        self.gbs_info = gbs_info
Packit 534379
        self.metadata = metadata.get_metadata(self.gbs_info)
Packit 534379
Packit 534379
    """
Packit 534379
    Function to make make sure GBS file conforms to standard
Packit 534379
    and polpulate the GBS object with appropriate values
Packit 534379
    """
Packit 534379
Packit 534379
    def validate_gbs_file(self, gbs_file):
Packit 534379
        file = open(gbs_file, 'rb')
Packit 534379
        gbs = file.read()
Packit 534379
Packit 534379
        if len(constants.METADATA_GUID) >= len(gbs):
Packit 534379
            raise Exception("Invalid GBS file")
Packit 534379
Packit 534379
        self.guid = gbs[:constants.GUID_LEN]
Packit 534379
        if self.guid != constants.METADATA_GUID:
Packit 534379
            raise Exception("Unsupported GBS format")
Packit 534379
Packit 534379
        metadata_index = constants.GUID_LEN + constants.SIZEOF_LEN_FIELD
Packit 534379
Packit 534379
        metadata_len = struct.unpack(
Packit 534379
            "
Packit 534379
        self.metadata_len = metadata_len[0]
Packit 534379
Packit 534379
        if self.metadata_len != 0:
Packit 534379
            self.gbs_info = json.loads(
Packit 534379
                gbs[metadata_index:(metadata_index + self.metadata_len)])
Packit 534379
Packit 534379
        rbf_index = metadata_index + metadata_len[0]
Packit 534379
Packit 534379
        if rbf_index == len(gbs):
Packit 534379
            raise Exception("No RBF in GBS file!")
Packit 534379
Packit 534379
        self.rbf = gbs[rbf_index:]
Packit 534379
Packit 534379
        self.metadata = metadata.get_metadata(self.gbs_info)