mirror of
https://github.com/hanzoai/container.git
synced 2026-10-30 15:06:01 +00:00
* core: begin migration to ubuntu * core: update cloud image link * k3s: update version * core: fix boot for ubuntu * vm: add ability to set custom hostname * core: checkpoint: remove qemu wrapper * core: checkpoint: remove qemu wrapper * cli: minor bug fix for terminal output * cli: fix broken terminal output for deb download * cli: improve terminal output for deb download * vm: fix docker permission on initial create * net: remove gvproxy, migrate to user-v2 * docker: fix host-gateway address * vm: avoid re-installing packages * k3s: fix broken coredns * core: improve downloader * vm: add binfmt for cross-platform containers * containerd: fix for ubuntu * containerd: fix broken working directory detection * chore: remove obsolete env var * chore: minor refactor for binfmt * cli: fix ip address for colima list * docker: add daemon support for proxy env vars * vm: add more utilities * ci: remove obsolete ubuntu layer * ci: move to gh from hub * core: use custom directory for Lima * chore: minor factor, remove obsolete variable * docker: workaround initial user permission issue * chore: remove obsolete code * vm: fix binfmt cache * core: enforce Lima version requirement * docker: workaround permission issue * vm: enable inotify by default * core: enable binfmt only on host arch * docs: prepare for v0.6.0 * nix: update Go version in shell * nix: update build * build: add integration test script * ci: remove aarch64, defer until proper m1 support * build: fix colima path in integration test script
171 lines
5.1 KiB
Go
171 lines
5.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/abiosoft/colima/cli"
|
|
"github.com/abiosoft/colima/cmd/root"
|
|
"github.com/abiosoft/colima/config"
|
|
"github.com/abiosoft/colima/environment/container/containerd"
|
|
"github.com/abiosoft/colima/util/fsutil"
|
|
"github.com/abiosoft/colima/util/osutil"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var nerdctlCmdArgs struct {
|
|
force bool
|
|
path string
|
|
usrBinWriteable bool
|
|
isColimaScript bool
|
|
}
|
|
|
|
// nerdctlCmd represents the nerdctl command
|
|
var nerdctlCmd = &cobra.Command{
|
|
Use: "nerdctl",
|
|
Aliases: []string{"nerd", "n"},
|
|
Short: "run nerdctl (requires containerd runtime)",
|
|
Long: `Run nerdctl to interact with containerd.
|
|
This requires containerd runtime.
|
|
|
|
It is recommended to specify '--' to differentiate from Colima flags.
|
|
`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
app := newApp()
|
|
r, err := app.Runtime()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if r != containerd.Name {
|
|
return fmt.Errorf("nerdctl only supports %s runtime", containerd.Name)
|
|
}
|
|
|
|
nerdctlArgs := append([]string{"sudo", "nerdctl"}, args...)
|
|
return app.SSH(nerdctlArgs...)
|
|
},
|
|
}
|
|
|
|
// nerdctlLinkFunc represents the nerdctl command
|
|
var nerdctlLinkFunc = func() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "install",
|
|
Short: "install nerdctl alias script on the host",
|
|
Long: `Install nerdctl alias script on the host. The script will be installed at ` + nerdctlDefaultInstallPath + `.`,
|
|
Args: cobra.NoArgs,
|
|
PreRun: func(cmd *cobra.Command, args []string) {
|
|
// check if /usr/local/bin is writeable and no need for sudo
|
|
|
|
// if the path is user-specified, ignore.
|
|
if nerdctlCmdArgs.path != nerdctlDefaultInstallPath {
|
|
return
|
|
}
|
|
|
|
// attempt writing to the /usr/local/bin
|
|
tmpFile := filepath.Join(filepath.Dir(nerdctlDefaultInstallPath), "colima.tmp")
|
|
if err := os.WriteFile(tmpFile, []byte("tmp"), 0777); err == nil {
|
|
nerdctlCmdArgs.usrBinWriteable = true
|
|
_ = os.Remove(tmpFile)
|
|
}
|
|
|
|
// check if the current file (if exists) is generated by colima
|
|
// in such case no need for confirmation before overwrite
|
|
// TODO: this is too basic, should be better
|
|
if b, err := os.ReadFile(nerdctlCmdArgs.path); err == nil {
|
|
if strings.Contains(string(b), "colima nerdctl ") {
|
|
nerdctlCmdArgs.isColimaScript = true
|
|
}
|
|
}
|
|
},
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
exists := false
|
|
if _, err := os.Stat(nerdctlCmdArgs.path); err == nil && !nerdctlCmdArgs.force && !nerdctlCmdArgs.isColimaScript {
|
|
return fmt.Errorf("%s exists, use --force to replace", nerdctlCmdArgs.path)
|
|
} else if err == nil {
|
|
exists = true
|
|
}
|
|
|
|
t, err := template.New("").Parse(nerdctlScript)
|
|
if err != nil {
|
|
return fmt.Errorf("error parsing nerdctl script template: %w", err)
|
|
}
|
|
var values = struct {
|
|
ColimaApp string
|
|
Profile string
|
|
}{
|
|
ColimaApp: osutil.Executable(),
|
|
Profile: config.CurrentProfile().ShortName,
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := t.Execute(&buf, values); err != nil {
|
|
return fmt.Errorf("error applying nerdctl script template: %w", err)
|
|
}
|
|
|
|
// /usr/local/bin writeable i.e. sudo not needed
|
|
// or user-specified install path, we assume user specified path is writeable
|
|
if nerdctlCmdArgs.usrBinWriteable || nerdctlCmdArgs.path != nerdctlDefaultInstallPath {
|
|
if exists {
|
|
if err := os.Rename(nerdctlCmdArgs.path, nerdctlCmdArgs.path+".moved"); err != nil {
|
|
return fmt.Errorf("error backing up existing file: %w", err)
|
|
}
|
|
}
|
|
if err := fsutil.MkdirAll("/usr/local/bin", 0755); err != nil {
|
|
return nil
|
|
}
|
|
return os.WriteFile(nerdctlCmdArgs.path, buf.Bytes(), 0755)
|
|
}
|
|
|
|
// sudo is needed for the default path
|
|
log.Println("/usr/local/bin not writable, sudo password required to install nerdctl binary")
|
|
if exists && !nerdctlCmdArgs.isColimaScript {
|
|
c := cli.CommandInteractive("sudo", "mv", nerdctlCmdArgs.path, nerdctlCmdArgs.path+".moved")
|
|
if err := c.Run(); err != nil {
|
|
return fmt.Errorf("error backing up existing file: %w", err)
|
|
}
|
|
}
|
|
// prepare dir
|
|
{
|
|
c := cli.CommandInteractive("sudo", "mkdir", "-p", "/usr/local/bin")
|
|
if err := c.Run(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// install script
|
|
{
|
|
c := cli.CommandInteractive("sudo", "sh", "-c", "cat > "+nerdctlCmdArgs.path)
|
|
c.Stdin = &buf
|
|
if err := c.Run(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// ensure it is executable
|
|
if err := cli.Command("sudo", "chmod", "+x", nerdctlCmdArgs.path).Run(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
const nerdctlDefaultInstallPath = "/usr/local/bin/nerdctl"
|
|
|
|
const nerdctlScript = `#!/usr/bin/env sh
|
|
|
|
{{.ColimaApp}} nerdctl --profile {{.Profile}} -- "$@"
|
|
`
|
|
|
|
func init() {
|
|
root.Cmd().AddCommand(nerdctlCmd)
|
|
|
|
nerdctlLink := nerdctlLinkFunc()
|
|
nerdctlCmd.AddCommand(nerdctlLink)
|
|
nerdctlLink.Flags().BoolVarP(&nerdctlCmdArgs.force, "force", "f", false, "replace "+nerdctlDefaultInstallPath+" (if exists)")
|
|
nerdctlLink.Flags().StringVar(&nerdctlCmdArgs.path, "path", nerdctlDefaultInstallPath, "path to install nerdctl binary")
|
|
}
|