From bf25b5c5607af1ff9e4d64aed91142bb9db1b166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sat, 14 Feb 2026 20:35:02 +0200 Subject: [PATCH] working commit --- Makefile.am | 24 +++++++ Makefile.in | 48 ++++++++++---- app/config/variant.go | 19 ++---- attic/{test => }/account_test.go | 0 attic/{test => }/file_test.go | 0 cmd/mstorectl/imagecmd.go | 104 +++++++++++++++++++++++-------- configure | 4 +- configure.ac | 2 + initrc/.gitignore | 3 + initrc/mstored.in | 24 +++++++ initrc/mstored.service | 12 ++++ initrc/mstored.service.in | 12 ++++ pkg/client/imagedelete.go | 69 ++++++++++++++++++++ test/image_test.go | 13 +++- 14 files changed, 280 insertions(+), 54 deletions(-) rename attic/{test => }/account_test.go (100%) rename attic/{test => }/file_test.go (100%) create mode 100644 initrc/.gitignore create mode 100644 initrc/mstored.in create mode 100644 initrc/mstored.service create mode 100644 initrc/mstored.service.in create mode 100644 pkg/client/imagedelete.go diff --git a/Makefile.am b/Makefile.am index 09bafd0..44a036d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.in b/Makefile.in index 2fafdd2..a3a224f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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. diff --git a/app/config/variant.go b/app/config/variant.go index 3c25d6d..bebba17 100644 --- a/app/config/variant.go +++ b/app/config/variant.go @@ -1,19 +1,10 @@ -/* - * Copyright 2026 Oleg Borodin - * - * 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" + srvname = "mstored" ) diff --git a/attic/test/account_test.go b/attic/account_test.go similarity index 100% rename from attic/test/account_test.go rename to attic/account_test.go diff --git a/attic/test/file_test.go b/attic/file_test.go similarity index 100% rename from attic/test/file_test.go rename to attic/file_test.go diff --git a/cmd/mstorectl/imagecmd.go b/cmd/mstorectl/imagecmd.go index 3173b37..1a3d20d 100644 --- a/cmd/mstorectl/imagecmd.go +++ b/cmd/mstorectl/imagecmd.go @@ -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,30 +96,64 @@ 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 } type ImageUtil struct { - imageInfoParams ImageInfoParams - pullImageParams PullImageParams - pushImageParams PushImageParams + 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 } diff --git a/configure b/configure index 7422bfe..bdcffb6 100755 --- a/configure +++ b/configure @@ -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 diff --git a/configure.ac b/configure.ac index 034c3c3..7515d03 100644 --- a/configure.ac +++ b/configure.ac @@ -236,5 +236,7 @@ dnl ---------------------------------------------------------------------------- AC_CONFIG_FILES([ Makefile app/config/variant.go +initrc/mstored.service +initrc/mstored ]) AC_OUTPUT diff --git a/initrc/.gitignore b/initrc/.gitignore new file mode 100644 index 0000000..dba3372 --- /dev/null +++ b/initrc/.gitignore @@ -0,0 +1,3 @@ +*~ +istored +istored.service diff --git a/initrc/mstored.in b/initrc/mstored.in new file mode 100644 index 0000000..494f348 --- /dev/null +++ b/initrc/mstored.in @@ -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 + diff --git a/initrc/mstored.service b/initrc/mstored.service new file mode 100644 index 0000000..4469bed --- /dev/null +++ b/initrc/mstored.service @@ -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 + diff --git a/initrc/mstored.service.in b/initrc/mstored.service.in new file mode 100644 index 0000000..d119d24 --- /dev/null +++ b/initrc/mstored.service.in @@ -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 + diff --git a/pkg/client/imagedelete.go b/pkg/client/imagedelete.go new file mode 100644 index 0000000..ef44356 --- /dev/null +++ b/pkg/client/imagedelete.go @@ -0,0 +1,69 @@ +/* + * Copyright 2026 Oleg Borodin + * + * 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 +} diff --git a/test/image_test.go b/test/image_test.go index 4c10e90..6833f51 100644 --- a/test/image_test.go +++ b/test/image_test.go @@ -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)) + } }