working commit
This commit is contained in:
+24
@@ -40,3 +40,27 @@ test:
|
||||
clean-local:
|
||||
$(FIND) $(CWD) -name '*~' | $(XARGS) rm -f
|
||||
rm -rf autom4te.cache
|
||||
rm -f cmd/mstored/istored
|
||||
rm -f cmd/mstorectl/mstorectl
|
||||
rm -rf tmp/
|
||||
|
||||
FREEBSD_LOCALBASE = /usr/local
|
||||
FREEBSD_RCDIR = $(FREEBSD_LOCALBASE)/etc/rc.d
|
||||
LINUX_SYSTEMDDIR = /lib/systemd/system
|
||||
|
||||
install-data-local:
|
||||
test -z $(DESTDIR)$(srv_confdir) || $(MKDIR_P) $(DESTDIR)$(srv_confdir)
|
||||
test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir)
|
||||
test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir)
|
||||
test -z $(DESTDIR)$(srv_datadir) || $(MKDIR_P) $(DESTDIR)$(srv_datadir)
|
||||
if FREEBSD_OS
|
||||
test -z $(DESTDIR)$(FREEBSD_RCDIR) || $(MKDIR_P) $(DESTDIR)$(FREEBSD_RCDIR)
|
||||
$(INSTALL_DATA) initrc/mstored $(DESTDIR)$(FREEBSD_RCDIR)
|
||||
chmod a+x $(DESTDIR)$(FREEBSD_RCDIR)/mstored
|
||||
endif
|
||||
if LINUX_OS
|
||||
if SYSTEMD
|
||||
test -z $(DESTDIR)$(LINUX_SYSTEMDDIR) || $(MKDIR_P) $(DESTDIR)$(LINUX_SYSTEMDDIR)
|
||||
$(INSTALL_DATA) initrc/mstored.service $(DESTDIR)$(LINUX_SYSTEMDDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
+36
-12
@@ -100,7 +100,8 @@ DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_CLEAN_FILES = app/config/variant.go
|
||||
CONFIG_CLEAN_FILES = app/config/variant.go initrc/mstored.service \
|
||||
initrc/mstored
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
|
||||
@@ -163,7 +164,9 @@ am__define_uniq_tagged_files = \
|
||||
done | $(am__uniquify_input)`
|
||||
AM_RECURSIVE_TARGETS = cscope
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/app/config/variant.go.in README.md config.guess \
|
||||
$(top_srcdir)/app/config/variant.go.in \
|
||||
$(top_srcdir)/initrc/mstored.in \
|
||||
$(top_srcdir)/initrc/mstored.service.in README.md config.guess \
|
||||
config.sub install-sh missing
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
@@ -297,6 +300,9 @@ mstored_SOURCES = \
|
||||
cmd/mstored/main.go
|
||||
|
||||
CWD = $(shell pwd)
|
||||
FREEBSD_LOCALBASE = /usr/local
|
||||
FREEBSD_RCDIR = $(FREEBSD_LOCALBASE)/etc/rc.d
|
||||
LINUX_SYSTEMDDIR = /lib/systemd/system
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -335,6 +341,10 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
$(am__aclocal_m4_deps):
|
||||
app/config/variant.go: $(top_builddir)/config.status $(top_srcdir)/app/config/variant.go.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
initrc/mstored.service: $(top_builddir)/config.status $(top_srcdir)/initrc/mstored.service.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
initrc/mstored: $(top_builddir)/config.status $(top_srcdir)/initrc/mstored.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
|
||||
@@ -716,7 +726,7 @@ info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
install-data-am: install-data-local
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
@@ -774,15 +784,15 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
|
||||
distclean-compile distclean-generic distclean-tags \
|
||||
distcleancheck distdir distuninstallcheck dvi dvi-am html \
|
||||
html-am info info-am install install-am install-binPROGRAMS \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
|
||||
uninstall-sbinPROGRAMS
|
||||
install-data install-data-am install-data-local install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-sbinPROGRAMS install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
|
||||
uninstall-am uninstall-binPROGRAMS uninstall-sbinPROGRAMS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
@@ -810,6 +820,20 @@ test:
|
||||
clean-local:
|
||||
$(FIND) $(CWD) -name '*~' | $(XARGS) rm -f
|
||||
rm -rf autom4te.cache
|
||||
rm -f cmd/mstored/istored
|
||||
rm -f cmd/mstorectl/mstorectl
|
||||
rm -rf tmp/
|
||||
|
||||
install-data-local:
|
||||
test -z $(DESTDIR)$(srv_confdir) || $(MKDIR_P) $(DESTDIR)$(srv_confdir)
|
||||
test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir)
|
||||
test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir)
|
||||
test -z $(DESTDIR)$(srv_datadir) || $(MKDIR_P) $(DESTDIR)$(srv_datadir)
|
||||
@FREEBSD_OS_TRUE@ test -z $(DESTDIR)$(FREEBSD_RCDIR) || $(MKDIR_P) $(DESTDIR)$(FREEBSD_RCDIR)
|
||||
@FREEBSD_OS_TRUE@ $(INSTALL_DATA) initrc/mstored $(DESTDIR)$(FREEBSD_RCDIR)
|
||||
@FREEBSD_OS_TRUE@ chmod a+x $(DESTDIR)$(FREEBSD_RCDIR)/mstored
|
||||
@LINUX_OS_TRUE@@SYSTEMD_TRUE@ test -z $(DESTDIR)$(LINUX_SYSTEMDDIR) || $(MKDIR_P) $(DESTDIR)$(LINUX_SYSTEMDDIR)
|
||||
@LINUX_OS_TRUE@@SYSTEMD_TRUE@ $(INSTALL_DATA) initrc/mstored.service $(DESTDIR)$(LINUX_SYSTEMDDIR)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
|
||||
+4
-13
@@ -1,19 +1,10 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package config
|
||||
|
||||
const (
|
||||
confdir = "/home/ziggi/Projects/mstore/etc/mstore"
|
||||
rundir = "/home/ziggi/Projects/mstore/tmp/run"
|
||||
logdir = "/home/ziggi/Projects/mstore/tmp/log"
|
||||
datadir = "/home/ziggi/Projects/mstore/tmp/data"
|
||||
confdir = "/usr/local/etc/mstore"
|
||||
rundir = "/var/run/mstore"
|
||||
logdir = "/var/log/mstore"
|
||||
datadir = "/var/data/mstore"
|
||||
version = "0.1.0"
|
||||
srvname = "mstored"
|
||||
)
|
||||
|
||||
+75
-23
@@ -47,6 +47,23 @@ func (util *ImageUtil) CreateImageCmds() *cobra.Command {
|
||||
Short: "Image operation",
|
||||
}
|
||||
|
||||
// PushImage
|
||||
var pushImageCmd = &cobra.Command{
|
||||
Use: "push",
|
||||
Short: "Pull container image into local file",
|
||||
Run: util.PushImage,
|
||||
}
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Username, "user", "u", "", "Username")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Password, "pass", "p", "", "Password")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Imagepath, "image", "i", "", "Remote image path")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Filepath, "file", "f", "", "Local file path")
|
||||
pushImageCmd.Flags().Uint64VarP(&util.pushImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout")
|
||||
pushImageCmd.MarkFlagRequired("image")
|
||||
pushImageCmd.MarkFlagRequired("file")
|
||||
pushImageCmd.MarkFlagsRequiredTogether("user", "pass")
|
||||
|
||||
subCmd.AddCommand(pushImageCmd)
|
||||
|
||||
// ImageInfo
|
||||
var imageInfoCmd = &cobra.Command{
|
||||
Use: "info",
|
||||
@@ -79,22 +96,20 @@ func (util *ImageUtil) CreateImageCmds() *cobra.Command {
|
||||
|
||||
subCmd.AddCommand(pullImageCmd)
|
||||
|
||||
// PushImage
|
||||
var pushImageCmd = &cobra.Command{
|
||||
Use: "push",
|
||||
Short: "Pull container image into local file",
|
||||
Run: util.PushImage,
|
||||
// DeleteImage
|
||||
var deleteImageCmd = &cobra.Command{
|
||||
Use: "info",
|
||||
Short: "Show container image info",
|
||||
Run: util.DeleteImage,
|
||||
}
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Username, "user", "u", "", "Username")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Password, "pass", "p", "", "Password")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Imagepath, "image", "i", "", "Remote image path")
|
||||
pushImageCmd.Flags().StringVarP(&util.pushImageParams.Filepath, "file", "f", "", "Local file path")
|
||||
pushImageCmd.Flags().Uint64VarP(&util.pushImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout")
|
||||
pushImageCmd.MarkFlagRequired("image")
|
||||
pushImageCmd.MarkFlagRequired("file")
|
||||
pushImageCmd.MarkFlagsRequiredTogether("user", "pass")
|
||||
deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Username, "user", "u", "", "Username")
|
||||
deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Password, "pass", "p", "", "Password")
|
||||
deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Imagepath, "image", "i", "", "Remote image path")
|
||||
deleteImageCmd.Flags().Uint64VarP(&util.deleteImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout")
|
||||
deleteImageCmd.MarkFlagRequired("image")
|
||||
deleteImageCmd.MarkFlagsRequiredTogether("user", "pass")
|
||||
|
||||
subCmd.AddCommand(pushImageCmd)
|
||||
subCmd.AddCommand(imageInfoCmd)
|
||||
|
||||
return subCmd
|
||||
}
|
||||
@@ -103,6 +118,42 @@ type ImageUtil struct {
|
||||
imageInfoParams ImageInfoParams
|
||||
pullImageParams PullImageParams
|
||||
pushImageParams PushImageParams
|
||||
deleteImageParams DeleteImageParams
|
||||
}
|
||||
|
||||
// PushImage
|
||||
type PushImageParams struct {
|
||||
Imagepath string
|
||||
Filepath string
|
||||
Timeout uint64
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type PushImageResult struct{}
|
||||
|
||||
func (util *ImageUtil) PushImage(cmd *cobra.Command, args []string) {
|
||||
res, err := util.pushImage(&util.pushImageParams)
|
||||
printResponse(res, err)
|
||||
}
|
||||
|
||||
func (util *ImageUtil) pushImage(params *PushImageParams) (*PushImageResult, error) {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
res := &PushImageResult{}
|
||||
|
||||
cli := client.NewClient()
|
||||
timeout := time.Duration(params.Timeout) * time.Second
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
err = cli.PushImage(ctx, params.Filepath, params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
// ImageInfo
|
||||
@@ -179,35 +230,36 @@ func (util *ImageUtil) pullImage(params *PullImageParams) (*PullImageResult, err
|
||||
return res, err
|
||||
}
|
||||
|
||||
// PushImage
|
||||
type PushImageParams struct {
|
||||
// DeleteImage
|
||||
type DeleteImageParams struct {
|
||||
Imagepath string
|
||||
Filepath string
|
||||
Timeout uint64
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type PushImageResult struct{}
|
||||
type DeleteImageResult struct {
|
||||
}
|
||||
|
||||
func (util *ImageUtil) PushImage(cmd *cobra.Command, args []string) {
|
||||
res, err := util.pushImage(&util.pushImageParams)
|
||||
func (util *ImageUtil) DeleteImage(cmd *cobra.Command, args []string) {
|
||||
res, err := util.deleteImage(&util.deleteImageParams)
|
||||
printResponse(res, err)
|
||||
}
|
||||
|
||||
func (util *ImageUtil) pushImage(params *PushImageParams) (*PushImageResult, error) {
|
||||
func (util *ImageUtil) deleteImage(params *DeleteImageParams) (*DeleteImageResult, error) {
|
||||
var err error
|
||||
res := &DeleteImageResult{}
|
||||
ctx := context.Background()
|
||||
res := &PushImageResult{}
|
||||
|
||||
cli := client.NewClient()
|
||||
timeout := time.Duration(params.Timeout) * time.Second
|
||||
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
err = cli.PushImage(ctx, params.Filepath, params.Imagepath)
|
||||
err = cli.DeleteImage(ctx, params.Imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -3344,7 +3344,7 @@ printf "%s\n" "$as_me: srv_datadir set as ${SRV_DATADIR}" >&6;}
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile app/config/variant.go"
|
||||
ac_config_files="$ac_config_files Makefile app/config/variant.go initrc/mstored.service initrc/mstored"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
@@ -4084,6 +4084,8 @@ do
|
||||
case $ac_config_target in
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"app/config/variant.go") CONFIG_FILES="$CONFIG_FILES app/config/variant.go" ;;
|
||||
"initrc/mstored.service") CONFIG_FILES="$CONFIG_FILES initrc/mstored.service" ;;
|
||||
"initrc/mstored") CONFIG_FILES="$CONFIG_FILES initrc/mstored" ;;
|
||||
|
||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
esac
|
||||
|
||||
@@ -236,5 +236,7 @@ dnl ----------------------------------------------------------------------------
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
app/config/variant.go
|
||||
initrc/mstored.service
|
||||
initrc/mstored
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
*~
|
||||
istored
|
||||
istored.service
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# PROVIDE: mstored
|
||||
# REQUIRE: DAEMON
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="mstored"
|
||||
rcvar="mstored_enable"
|
||||
|
||||
pidfile="@srv_rundir@/mstored.pid"
|
||||
command="@prefix@/sbin/${name}"
|
||||
command_args="-daemon"
|
||||
procname="@prefix@/sbin/${name}"
|
||||
|
||||
load_rc_config ${name}
|
||||
|
||||
: ${mstored_enable:="NO"}
|
||||
|
||||
run_rc_command "$1"
|
||||
#EOF
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=mstored
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/var/run/mstore/mstored.pid
|
||||
ExecStart=/usr/local/sbin/mstored -daemon=true
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=mstored
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=@srv_rundir@/mstored.pid
|
||||
ExecStart=@prefix@/sbin/mstored -daemon=true
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/crane"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
|
||||
)
|
||||
|
||||
|
||||
func (cli *Client) DeleteImage(ctx context.Context, imagepath string) error {
|
||||
var err error
|
||||
|
||||
imagepath, username, password, err := repackReference(imagepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options := make([]crane.Option, 0)
|
||||
options = append(options, crane.WithContext(ctx))
|
||||
|
||||
ref, err := name.ParseReference(imagepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repo := ref.Context()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if username != "" && password != "" {
|
||||
defaultTransport := &roundTripper{}
|
||||
scopes := []string{repo.Scope(transport.PullScope)}
|
||||
|
||||
regName := repo.RegistryStr()
|
||||
reg, err := name.NewRegistry(regName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
basicAuth := &authn.Basic{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options = append(options, crane.WithTransport(authTransport))
|
||||
} else {
|
||||
transport := &roundTripper{}
|
||||
options = append(options, crane.WithTransport(transport))
|
||||
}
|
||||
|
||||
err = crane.Delete(imagepath, options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
+12
-1
@@ -23,7 +23,7 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func xxxTestImageLife(t *testing.T) {
|
||||
func TestImageLife(t *testing.T) {
|
||||
var srvport int64 = 10250
|
||||
srvdir := t.TempDir()
|
||||
srvaddr := fmt.Sprintf("mstore:mstore@127.0.0.1:%d", srvport)
|
||||
@@ -93,5 +93,16 @@ func xxxTestImageLife(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("imageInfo:\n%s\n", string(infoYaml))
|
||||
}
|
||||
{
|
||||
// DeleteImage
|
||||
fmt.Printf("=== DeleteImage ===\n")
|
||||
cli := client.NewClient()
|
||||
ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
info, err := cli.DeleteImage(ctx, srvaddr+"/foo/test:123")
|
||||
require.NoError(t, err)
|
||||
infoYaml, err := yaml.Marshal(info)
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("deleteImage:\n%s\n", string(infoYaml))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user