Commit d7e13eb9 authored by songlinfeng's avatar songlinfeng
Browse files

add dtk-container-toolkit

parent fcdba4f3
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package containerd
import (
"github.com/pelletier/go-toml"
"dtk-container-toolkit/internal/logger"
"dtk-container-toolkit/pkg/config/engine"
)
// Config represents the containerd config
type Config struct {
*toml.Tree
RuntimeType string
UseDefaultRuntimeName bool
ContainerAnnotations []string
}
var _ engine.Interface = (*Config)(nil)
// New creates a containerd config with the specified options
func New(opts ...Option) (engine.Interface, error) {
b := &builder{}
for _, opt := range opts {
opt(b)
}
if b.logger == nil {
b.logger = logger.New()
}
return b.build()
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package containerd
import (
"dtk-container-toolkit/internal/logger"
"dtk-container-toolkit/pkg/config/engine"
"fmt"
"os"
"github.com/pelletier/go-toml"
)
const (
defaultRuntimeType = "io.containerd.runc.v2"
)
type builder struct {
logger logger.Interface
path string
runtimeType string
useLegacyConfig bool
containerAnnotations []string
}
// Option defines a function that can be used to configure the config builder
type Option func(*builder)
// WithLogger sets the logger for the config builder
func WithLogger(logger logger.Interface) Option {
return func(b *builder) {
b.logger = logger
}
}
// WithPath sets the path for the config builder
func WithPath(path string) Option {
return func(b *builder) {
b.path = path
}
}
// WithRuntimeType sets the runtime type for the config builder
func WithRuntimeType(runtimeType string) Option {
return func(b *builder) {
b.runtimeType = runtimeType
}
}
// WithUseLegacyConfig sets the useLegacyConfig flag for the config builder
func WithUseLegacyConfig(useLegacyConfig bool) Option {
return func(b *builder) {
b.useLegacyConfig = useLegacyConfig
}
}
// WithContainerAnnotations sets the container annotations for the config builder
func WithContainerAnnotations(containerAnnotations ...string) Option {
return func(b *builder) {
b.containerAnnotations = containerAnnotations
}
}
func (b *builder) build() (engine.Interface, error) {
if b.path == "" {
return nil, fmt.Errorf("config path is empty")
}
if b.runtimeType == "" {
b.runtimeType = defaultRuntimeType
}
config, err := b.loadConfig(b.path)
if err != nil {
return nil, fmt.Errorf("failed to load config: %v", err)
}
config.RuntimeType = b.runtimeType
config.UseDefaultRuntimeName = !b.useLegacyConfig
config.ContainerAnnotations = b.containerAnnotations
version, err := config.parseVersion(b.useLegacyConfig)
if err != nil {
return nil, fmt.Errorf("failed to parse config version: %v", err)
}
switch version {
case 1:
return (*ConfigV1)(config), nil
case 2:
return config, nil
}
return nil, fmt.Errorf("unsupported config version: %v", version)
}
// loadConfig loads the containerd config from disk
func (b *builder) loadConfig(config string) (*Config, error) {
info, err := os.Stat(config)
if os.IsExist(err) && info.IsDir() {
return nil, fmt.Errorf("config file is a directory")
}
if os.IsNotExist(err) {
b.logger.Infof("Config file does not exist; using empty config")
config = "/dev/null"
} else {
b.logger.Infof("Loading config from %v", config)
}
tomlConfig, err := toml.LoadFile(config)
if err != nil {
return nil, err
}
cfg := Config{
Tree: tomlConfig,
}
return &cfg, nil
}
// parseVersion returns the version of the config
func (c *Config) parseVersion(useLegacyConfig bool) (int, error) {
defaultVersion := 2
if useLegacyConfig {
defaultVersion = 1
}
switch v := c.Get("version").(type) {
case nil:
switch len(c.Keys()) {
case 0: // No config exists, or the config file is empty, use version inferred from containerd
return defaultVersion, nil
default: // A config file exists, has content, and no version is set
return 1, nil
}
case int64:
return int(v), nil
default:
return -1, fmt.Errorf("unsupported type for version field: %v", v)
}
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package containerd
import (
"fmt"
"github.com/pelletier/go-toml"
)
// tomlTree is an alias for toml.Tree that allows for extensions.
type tomlTree toml.Tree
func subtreeAtPath(c toml.Tree, path ...string) *tomlTree {
tree := c.GetPath(path).(*toml.Tree)
return (*tomlTree)(tree)
}
func (t *tomlTree) insert(other map[string]interface{}) error {
for key, value := range other {
if insertsubtree, ok := value.(map[string]interface{}); ok {
subtree := (*toml.Tree)(t).Get(key).(*toml.Tree)
return (*tomlTree)(subtree).insert(insertsubtree)
}
(*toml.Tree)(t).Set(key, value)
}
return nil
}
func (t *tomlTree) applyOverrides(overrides ...map[string]interface{}) error {
for _, override := range overrides {
subconfig, err := toml.TreeFromMap(override)
if err != nil {
return fmt.Errorf("invalid toml config: %w", err)
}
if err := t.insert(subconfig.ToMap()); err != nil {
return err
}
}
return nil
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package crio
import (
"dtk-container-toolkit/pkg/config/engine"
"fmt"
"github.com/pelletier/go-toml"
)
// Config represents the cri-o config
type Config toml.Tree
var _ engine.Interface = (*Config)(nil)
// New creates a cri-o config with the specified options
func New(opts ...Option) (engine.Interface, error) {
b := &builder{}
for _, opt := range opts {
opt(b)
}
return b.build()
}
// AddRuntime adds a new runtime to the crio config
func (c *Config) AddRuntime(name string, path string, setAsDefault bool, _ ...map[string]interface{}) error {
if c == nil {
return fmt.Errorf("config is nil")
}
config := (toml.Tree)(*c)
if runc, ok := config.Get("crio.runtime.runtimes.runc").(*toml.Tree); ok {
runc, _ = toml.Load(runc.String())
config.SetPath([]string{"crio", "runtime", "runtimes", name}, runc)
}
config.SetPath([]string{"crio", "runtime", "runtimes", name, "runtime_path"}, path)
config.SetPath([]string{"crio", "runtime", "runtimes", name, "runtime_type"}, "oci")
if setAsDefault {
config.SetPath([]string{"crio", "runtime", "default_runtime"}, name)
}
*c = (Config)(config)
return nil
}
// DefaultRuntime returns the default runtime for the cri-o config
func (c Config) DefaultRuntime() string {
config := (toml.Tree)(c)
if runtime, ok := config.GetPath([]string{"crio", "runtime", "default_runtime"}).(string); ok {
return runtime
}
return ""
}
// RemoveRuntime removes a runtime from the cri-o config
func (c *Config) RemoveRuntime(name string) error {
if c == nil {
return nil
}
config := (toml.Tree)(*c)
if runtime, ok := config.GetPath([]string{"crio", "runtime", "default_runtime"}).(string); ok {
if runtime == name {
config.DeletePath([]string{"crio", "runtime", "default_runtime"})
}
}
runtimeClassPath := []string{"crio", "runtime", "runtimes", name}
config.DeletePath(runtimeClassPath)
for i := 0; i < len(runtimeClassPath); i++ {
remainingPath := runtimeClassPath[:len(runtimeClassPath)-i]
if entry, ok := config.GetPath(remainingPath).(*toml.Tree); ok {
if len(entry.Keys()) != 0 {
break
}
config.DeletePath(remainingPath)
}
}
*c = (Config)(config)
return nil
}
// Set sets the specified cri-o option.
func (c *Config) Set(key string, value interface{}) {
config := (toml.Tree)(*c)
config.Set(key, value)
*c = (Config)(config)
}
// Save writes the config to the specified path
func (c Config) Save(path string) (int64, error) {
config := (toml.Tree)(c)
output, err := config.Marshal()
if err != nil {
return 0, fmt.Errorf("unable to convert to TOML: %v", err)
}
n, err := engine.Config(path).Write(output)
return int64(n), err
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package crio
import (
"dtk-container-toolkit/internal/logger"
"fmt"
"os"
"github.com/pelletier/go-toml"
)
type builder struct {
logger logger.Interface
path string
}
// Option defines a function that can be used to configure the config builder
type Option func(*builder)
// WithLogger sets the logger for the config builder
func WithLogger(logger logger.Interface) Option {
return func(b *builder) {
b.logger = logger
}
}
// WithPath sets the path for the config builder
func WithPath(path string) Option {
return func(b *builder) {
b.path = path
}
}
func (b *builder) build() (*Config, error) {
if b.path == "" {
empty := toml.Tree{}
return (*Config)(&empty), nil
}
if b.logger == nil {
b.logger = logger.New()
}
return b.loadConfig(b.path)
}
// loadConfig loads the cri-o config from disk
func (b *builder) loadConfig(config string) (*Config, error) {
b.logger.Infof("Loading config: %v", config)
info, err := os.Stat(config)
if os.IsExist(err) && info.IsDir() {
return nil, fmt.Errorf("config file is a directory")
}
if os.IsNotExist(err) {
b.logger.Infof("Config file does not exist; using empty config")
config = "/dev/null"
} else {
b.logger.Infof("Loading config from %v", config)
}
cfg, err := toml.LoadFile(config)
if err != nil {
return nil, err
}
b.logger.Infof("Successfully loaded config")
return (*Config)(cfg), nil
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package docker
import (
"dtk-container-toolkit/internal/logger"
"dtk-container-toolkit/pkg/config/engine"
"encoding/json"
"fmt"
)
const (
defaultDockerRuntime = "runc"
)
// Config defines a docker config file.
// TODO: This should not be public, but we need to access it from the tests in tools/container/docker
type Config map[string]interface{}
var _ engine.Interface = (*Config)(nil)
// New creates a docker config with the specified options
func New(opts ...Option) (engine.Interface, error) {
b := &builder{}
for _, opt := range opts {
opt(b)
}
if b.logger == nil {
b.logger = logger.New()
}
return b.build()
}
// AddRuntime adds a new runtime to the docker config
func (c *Config) AddRuntime(name string, path string, setAsDefault bool, _ ...map[string]interface{}) error {
if c == nil {
return fmt.Errorf("config is nil")
}
config := *c
// Read the existing runtimes
runtimes := make(map[string]interface{})
if _, exists := config["runtimes"]; exists {
runtimes = config["runtimes"].(map[string]interface{})
}
// Add / update the runtime definitions
runtimes[name] = map[string]interface{}{
"path": path,
"args": []string{},
}
config["runtimes"] = runtimes
if setAsDefault {
config["default-runtime"] = name
}
*c = config
return nil
}
// DefaultRuntime returns the default runtime for the docker config
func (c Config) DefaultRuntime() string {
r, ok := c["default-runtime"].(string)
if !ok {
return ""
}
return r
}
// RemoveRuntime removes a runtime from the docker config
func (c *Config) RemoveRuntime(name string) error {
if c == nil {
return nil
}
config := *c
if _, exists := config["default-runtime"]; exists {
defaultRuntime := config["default-runtime"].(string)
if defaultRuntime == name {
config["default-runtime"] = defaultDockerRuntime
}
}
if _, exists := config["runtimes"]; exists {
runtimes := config["runtimes"].(map[string]interface{})
delete(runtimes, name)
if len(runtimes) == 0 {
delete(config, "runtimes")
}
}
*c = config
return nil
}
// Set sets the specified docker option
func (c *Config) Set(key string, value interface{}) {
(*c)[key] = value
}
// Save writes the config to the specified path
func (c Config) Save(path string) (int64, error) {
output, err := json.MarshalIndent(c, "", " ")
if err != nil {
return 0, fmt.Errorf("unable to convert to JSON: %v", err)
}
n, err := engine.Config(path).Write(output)
return int64(n), err
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package docker
import (
"bytes"
"dtk-container-toolkit/internal/logger"
"encoding/json"
"fmt"
"os"
)
type builder struct {
logger logger.Interface
path string
}
// Option defines a function that can be used to configure the config builder
type Option func(*builder)
// WithLogger sets the logger for the config builder
func WithLogger(logger logger.Interface) Option {
return func(b *builder) {
b.logger = logger
}
}
// WithPath sets the path for the config builder
func WithPath(path string) Option {
return func(b *builder) {
b.path = path
}
}
func (b *builder) build() (*Config, error) {
if b.path == "" {
empty := make(Config)
return &empty, nil
}
return b.loadConfig(b.path)
}
// loadConfig loads the docker config from disk
func (b *builder) loadConfig(config string) (*Config, error) {
info, err := os.Stat(config)
if os.IsExist(err) && info.IsDir() {
return nil, fmt.Errorf("config file is a directory")
}
cfg := make(Config)
if os.IsNotExist(err) {
b.logger.Infof("Config file does not exist; using empty config")
return &cfg, nil
}
b.logger.Infof("Loading config from %v", config)
readBytes, err := os.ReadFile(config)
if err != nil {
return nil, fmt.Errorf("unable to read config: %v", err)
}
reader := bytes.NewReader(readBytes)
if err := json.NewDecoder(reader).Decode(&cfg); err != nil {
return nil, err
}
return &cfg, nil
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package device
import "dtk-container-toolkit/pkg/go-c3000smi/pkg/c3000smi"
// Interface provides the API to the 'device' package.
type Interface interface {
VisitDevices(func(i string, d Device) error) error
}
type devicelib struct {
c3000smicmd c3000smi.Interface
skippedDevices map[string]struct{}
}
var _ Interface = &devicelib{}
// New creates a new instance of the 'device' interface.
func New(smicmd c3000smi.Interface, opts ...Option) Interface {
d := &devicelib{
c3000smicmd: smicmd,
}
for _, opt := range opts {
opt(d)
}
if d.skippedDevices == nil {
WithSkippedDevices()(d)
}
return d
}
// WithSkippedDevices provides an Option to set devices to be skipped by model name.
func WithSkippedDevices(names ...string) Option {
return func(d *devicelib) {
if d.skippedDevices == nil {
d.skippedDevices = make(map[string]struct{})
}
for _, name := range names {
d.skippedDevices[name] = struct{}{}
}
}
}
// Option defines a function for passing options to the New() call.
type Option func(*devicelib)
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package device
import (
"dtk-container-toolkit/pkg/go-c3000smi/pkg/c3000smi"
"fmt"
)
// Device defines the set of extended functions associated with a device.Device.
type Device interface {
c3000smi.Device
}
type device struct {
c3000smi.Device
lib *devicelib
}
var _ Device = &device{}
// newDevice creates a device from an c3000smi.Device
func (d *devicelib) newDevice(dev c3000smi.Device) (*device, error) {
return &device{dev, d}, nil
}
// isSkipped checks whether the device should be skipped.
func (d *device) isSkipped() (bool, error) {
name := d.GetName()
if _, exists := d.lib.skippedDevices[name]; exists {
return true, nil
}
return false, nil
}
// VisitDevices visits each top-level device and invokes a callback function for it.
func (d *devicelib) VisitDevices(visit func(string, Device) error) error {
indexs := d.c3000smicmd.DeviceGetIndexs()
for _, index := range indexs {
device, err := d.c3000smicmd.DeviceGetHandleByIndex(index)
if err != nil {
return fmt.Errorf("error getting device hanlde for index '%v': %v", index, err)
}
dev, err := d.newDevice(device)
if err != nil {
return fmt.Errorf("error creating new device wrapper: %v", err)
}
isSkipped, err := dev.isSkipped()
if err != nil {
return fmt.Errorf("error checking whether device is skipped: %v", err)
}
if isSkipped {
continue
}
err = visit(index, dev)
if err != nil {
return fmt.Errorf("error visiting device: %v", err)
}
}
return nil
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package device
// Identifier can be used to refer to a GPU or MIG device.
// This includes a device index or UUID.
type Identifier string
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package device
import "dtk-container-toolkit/pkg/go-c3000smi/pkg/c3000smi"
// MigDevice defines the set of extended functions associated with a MIG device.
type MigDevice interface {
c3000smi.Device
GetProfile() (MigProfile, error)
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package device
const (
// AttributeMediaExtensions holds the string representation for the media extension MIG profile attribute.
AttributeMediaExtensions = "me"
)
// MigProfile represents a specific MIG profile.
// Examples include "1g.5gb", "2g.10gb", "1c.2g.10gb", or "1c.1g.5gb+me", etc.
type MigProfile interface {
String() string
GetInfo() MigProfileInfo
Equals(other MigProfile) bool
Matches(profile string) bool
}
// MigProfileInfo holds all info associated with a specific MIG profile.
type MigProfileInfo struct {
C int
G int
GB int
Attributes []string
GIProfileID int
CIProfileID int
CIEngProfileID int
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package c3000smi
import "fmt"
// Interface represents the interface for the library type.
type Interface interface {
IsValid() bool
DeviceGetCount() int
DeviceGetIndexs() []string
DeviceGetHandleByIndex(string) (Device, error)
}
// Device represents the interface for the c3000Device type.
type Device interface {
GetUUID() string
GetName() string
GetPCIBusID() string
}
type DeviceInfo struct {
uniqueId string
pciBusId string
serialNumber string
cardSeries string
cardVendor string
}
type Devices map[string]*DeviceInfo
var _ Device = (*DeviceInfo)(nil)
func (d *DeviceInfo) GetName() string {
return fmt.Sprintf("%s %s", d.cardSeries, d.cardVendor)
}
func (d *DeviceInfo) GetUUID() string {
return d.uniqueId
}
func (d *DeviceInfo) GetPCIBusID() string {
return d.pciBusId
}
/**
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
**/
package c3000smi
import (
"bytes"
"dtk-container-toolkit/internal/logger"
"dtk-container-toolkit/internal/lookup"
"fmt"
"os"
"os/exec"
"regexp"
"strings"
)
type runCmd func(cmd *exec.Cmd) error
const (
DefaultHySmiCommand = "hy-smi"
)
var (
defaultRunCmd = func(cmd *exec.Cmd) error {
err := cmd.Run()
if err != nil {
return fmt.Errorf("error running command: %w", err)
}
return nil
}
serialNumberRe = regexp.MustCompile(`[D|H]CU\[(\d+)\].*Serial Number:\s*(\w+)`)
cardSeriesRe = regexp.MustCompile(`[D|H]CU\[(\d+)\].*Card Series:\s*([\w].*)`)
cardVendorRe = regexp.MustCompile(`[D|H]CU\[(\d+)\].*Card Vendor:\s*([\w].*)`)
uniqueIdRe = regexp.MustCompile(`[D|H]CU\[(\d+)\].*Unique ID:\s*([\w]+)`)
pciBusIdRe = regexp.MustCompile(`[D|H]CU\[(\d+)\].*PCI Bus:\s*([\w:.]+)`)
)
type smiCommand struct {
logger logger.Interface
path string
Command runCmd
devices Devices
}
var _ Interface = (*smiCommand)(nil)
// NewSmiCommand creates a Command for the specified logger and path
func NewSmiCommand(logger logger.Interface) (Interface, error) {
path, err := findSmiBinary(logger)
if err != nil {
return nil, fmt.Errorf("error locating binary: %v", err)
}
info, err := os.Stat(path)
if err != nil {
return nil, fmt.Errorf("invalid path '%v': %v", path, err)
}
if info.IsDir() || info.Mode()&0111 == 0 {
return nil, fmt.Errorf("specified path '%v' is not an executable file", path)
}
smi := smiCommand{
logger: logger,
path: path,
Command: defaultRunCmd,
}
err = smi.buildDevices()
if err != nil {
return nil, fmt.Errorf("failed to get devices: %w", err)
}
return &smi, nil
}
func (s *smiCommand) IsValid() bool {
_, err := os.Stat(s.path)
if err != nil {
s.logger.Errorf("invalid path: '%v': %v", s.path, err)
return false
}
return true
}
func (s *smiCommand) DeviceGetCount() int {
return len(s.devices)
}
func (s *smiCommand) DeviceGetIndexs() []string {
indexs := make([]string, 0, s.DeviceGetCount())
for index := range s.devices {
indexs = append(indexs, index)
}
return indexs
}
func (s *smiCommand) DeviceGetHandleByIndex(index string) (Device, error) {
if s.devices[index] == nil {
return nil, fmt.Errorf("%s device not exist", index)
}
return s.devices[index], nil
}
func (s *smiCommand) buildDevices() error {
s.devices = make(Devices)
cmdArgs := strings.Fields(s.path)
cmdArgs = append(cmdArgs, "--showuniqueid")
cmdArgs = append(cmdArgs, "--showbus")
cmdArgs = append(cmdArgs, "--showproductname")
cmdArgs = append(cmdArgs, "--showserial")
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := s.Command(cmd)
if err != nil {
rerr := fmt.Errorf(
"exec failed: %s | stdout: %s | stderr: %s: %w",
strings.Join(cmdArgs, " "),
stdout.String(),
stderr.String(),
err,
)
s.logger.Errorf("%w", rerr)
return rerr
}
text := stdout.String()
serialNumbers := parse(text, serialNumberRe)
for index, serialNumber := range serialNumbers {
if s.devices[index] == nil {
s.devices[index] = &DeviceInfo{}
}
s.devices[index].serialNumber = serialNumber
}
cardSeriess := parse(text, cardSeriesRe)
for index, cardSeries := range cardSeriess {
if s.devices[index] == nil {
s.devices[index] = &DeviceInfo{}
}
s.devices[index].cardSeries = cardSeries
}
cardVendors := parse(text, cardVendorRe)
for index, cardVendor := range cardVendors {
if s.devices[index] == nil {
s.devices[index] = &DeviceInfo{}
}
s.devices[index].cardVendor = cardVendor
}
uniqueIds := parse(text, uniqueIdRe)
for index, uniqueId := range uniqueIds {
if s.devices[index] == nil {
s.devices[index] = &DeviceInfo{}
}
s.devices[index].uniqueId = uniqueId
}
pciBusIds := parse(text, pciBusIdRe)
for index, pciBusId := range pciBusIds {
if s.devices[index] == nil {
s.devices[index] = &DeviceInfo{}
}
s.devices[index].pciBusId = pciBusId
}
return nil
}
func parse(text string, re *regexp.Regexp) map[string]string {
matches := make(map[string]string)
for _, match := range re.FindAllStringSubmatch(text, -1) {
matches[match[1]] = match[2]
}
return matches
}
func findSmiBinary(logger logger.Interface) (string, error) {
locator := lookup.NewExecutableLocator(logger, "", "/usr/local/hyhal/bin", "/opt/hyhal/bin")
targets, err := locator.Locate(DefaultHySmiCommand)
if err == nil && len(targets) > 0 {
logger.Debugf("Found binary '%v'", targets)
return targets[0], err
}
return "", fmt.Errorf("no binary found from %s", DefaultHySmiCommand)
}
#
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
#
# This script is used to build the packages for the components of the C-3000 Container Stack.
set -e
SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../scripts && pwd )"
PROJECT_ROOT="$( cd "${SCRIPTS_DIR}"/.. && pwd )"
function assert_usage() {
echo "Missing argument $1"
echo "$(basename "${BASH_SOURCE[0]}") TARGET"
exit 1
}
if [[ $# -le 1 ]]; then
assert_usage "TARGET"
fi
TARGET=$1
BASEIMAGE=$2
source "${SCRIPTS_DIR}"/utils.sh
: "${DIST_DIR:=${PROJECT_ROOT}/dist}"
export DIST_DIR
echo "Building ${TARGET} for all packages to ${DIST_DIR}"
: "${DTK_CONTAINER_TOOLKIT_ROOT:=${PROJECT_ROOT}}"
"${SCRIPTS_DIR}/get-component-versions.sh"
if [[ -z "${DTK_CONTAINER_TOOLKIT_VERSION}" ]]; then
eval $(${SCRIPTS_DIR}/get-component-versions.sh)
fi
make -C "${DTK_CONTAINER_TOOLKIT_ROOT}" "${TARGET}" "${BASEIMAGE}"
\ No newline at end of file
#
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
#
set -e
export DOCKER_IMAGE_REGISTRY=10.65.42.71:9092
SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../scripts && pwd )"
source "${SCRIPTS_DIR}"/utils.sh
if [[ $# -gt 0 ]]; then
targets=($*)
else
targets=${all[@]}
fi
eval $(${SCRIPTS_DIR}/get-component-versions.sh)
export DTK_CONTAINER_TOOLKIT_VERSION
export DTK_CONTAINER_TOOLKIT_TAG
for target in ${targets[@]}; do
if [[ -z "${DOCKER_IMAGE_REGISTRY}" ]]; then
image_args=
else
baseimage=$(get_base_image ${target} ${DOCKER_IMAGE_REGISTRY})
image_args="BASEIMAGE=${baseimage}"
fi
"${SCRIPTS_DIR}/build-all-components.sh" "${target}" "${image_args}"
done
#
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
#
function assert_usage() {
exit 1
}
set -e
SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../scripts && pwd )"
PROJECT_ROOT="$( cd ${SCRIPTS_DIR}/.. && pwd )"
DTK_CONTAINER_TOOLKIT_ROOT=${PROJECT_ROOT}
versions_makefile=${DTK_CONTAINER_TOOLKIT_ROOT}/versions.mk
dtk_container_toolkit_version=$(grep -m 1 "^LIB_VERSION := " ${versions_makefile} | sed -e 's/LIB_VERSION :=[[:space:]]\(.*\)[[:space:]]*/\1/')
dtk_container_toolkit_tag=$(grep -m 1 "^LIB_TAG .= " ${versions_makefile} | sed -e 's/LIB_TAG .=[[:space:]]\(.*\)[[:space:]]*/\1/')
dtk_container_toolkit_version_tag="${dtk_container_toolkit_version}${dtk_container_toolkit_tag}:+~${dtk_container_toolkit_tag}"
echo "DTK_CONTAINER_TOOLKIT_VERSION=${dtk_container_toolkit_version}"
echo "DTK_CONTAINER_TOOLKIT_TAG=${dtk_container_toolkit_tag}"
echo "DTK_CONTAINER_TOOLKIT_PACKAGE_VERSION=${dtk_container_toolkit_version_tag//\~/-}"
#
# Copyright (c) 2024, HCUOpt CORPORATION. All rights reserved.
#
# This list represents the distribution-architecture pairs that are actually published
# to the relevant repositories. This targets forwarded to the build-all-components script
# can be overridden by specifying command line arguments.
all=(
ubuntu18.04-amd64
ubuntu20.04-amd64
ubuntu22.04-amd64
centos7-x86_64
centos8-x86_64
rocky8-x86_64
rocky9-x86_64
kylin10-x86_64
)
function get_base_image() {
local baseimage
case ${1} in
ubuntu18.04-amd64)
baseimage=${2}/ubuntu:18.04
;;
ubuntu20.04-amd64)
baseimage=${2}/ubuntu:20.04
;;
ubuntu22.04-amd64)
baseimage=${2}/ubuntu:22.04
;;
centos7-x86_64)
baseimage=${2}/centos:7
;;
centos8-x86_64)
baseimage=${2}/centos:8.4.2105
;;
rocky8-x86_64)
baseimage=${2}/rockylinux:8.6
;;
rocky9-x86_64)
baseimage=${2}/rockylinux:9.2
;;
kylin10-x86_64)
baseimage=${2}/kylin:v10-sp2
;;
esac
echo "${baseimage}"
}
The MIT License (MIT)
Copyright (c) 2014 Brian Goff
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
package md2man
import (
"fmt"
"io"
"os"
"strings"
"github.com/russross/blackfriday/v2"
)
func fmtListFlags(flags blackfriday.ListType) string {
knownFlags := []struct {
name string
flag blackfriday.ListType
}{
{"ListTypeOrdered", blackfriday.ListTypeOrdered},
{"ListTypeDefinition", blackfriday.ListTypeDefinition},
{"ListTypeTerm", blackfriday.ListTypeTerm},
{"ListItemContainsBlock", blackfriday.ListItemContainsBlock},
{"ListItemBeginningOfList", blackfriday.ListItemBeginningOfList},
{"ListItemEndOfList", blackfriday.ListItemEndOfList},
}
var f []string
for _, kf := range knownFlags {
if flags&kf.flag != 0 {
f = append(f, kf.name)
flags &^= kf.flag
}
}
if flags != 0 {
f = append(f, fmt.Sprintf("Unknown(%#x)", flags))
}
return strings.Join(f, "|")
}
type debugDecorator struct {
blackfriday.Renderer
}
func depth(node *blackfriday.Node) int {
d := 0
for n := node.Parent; n != nil; n = n.Parent {
d++
}
return d
}
func (d *debugDecorator) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
fmt.Fprintf(os.Stderr, "%s%s %v %v\n",
strings.Repeat(" ", depth(node)),
map[bool]string{true: "+", false: "-"}[entering],
node,
fmtListFlags(node.ListFlags))
var b strings.Builder
status := d.Renderer.RenderNode(io.MultiWriter(&b, w), node, entering)
if b.Len() > 0 {
fmt.Fprintf(os.Stderr, ">> %q\n", b.String())
}
return status
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment