lib.minio

local MinIO arrays for integration and benchmark environments

Start and stop coordinated MinIO instances and inspect the ports allocated to the running array.

1    Overview

The namespace exposes the public lifecycle functions from lib.minio.bench. It is intended for local integration, distributed-storage experiments, and repeatable benchmark environments rather than as a general object-storage client.

2    Walkthrough

2.1    Start an array

(require '[lib.minio :as minio])

(def array
  (minio/start-minio-array
   {:count 4}))

(minio/all-minio-ports)

2.2    Stop the environment

Retain the returned array value and stop it during test teardown. Port discovery is useful when constructing clients after the processes have started.

(try
  (run-storage-tests array)
  (finally
    (minio/stop-minio-array array)))

3    API



all-minio-ports ^

[]
Added 4.0

gets all active minio ports

v 4.0
(defn all-minio-ports
  ([]
   (->> (os/sh "lsof" "-i" "-P" "-n" {:wrap false})
        (clojure.string/split-lines)
        (drop 1)
        (filter #(clojure.string/starts-with? % "minio"))
        (keep #(re-find #"^minios*(d+).*:(d+) (LISTEN)$" %))
        (map (fn [arr]
               (mapv f/parse-long (drop 1 arr))))
        (group-by second)
        (collection/map-vals (comp set (partial map first))))))
link
(with-redefs [os/sh (fn [& _] "COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEnminio 101 user 1u IPv4 0 0 TCP *:9000 (LISTEN)nminio 102 user 1u IPv4 0 0 TCP *:9000 (LISTEN)nminio 103 user 1u IPv4 0 0 TCP *:9001 (LISTEN)")] (all-minio-ports)) => {9000 #{101 102} 9001 #{103}}

start-minio-array ^

[ports]
Added 4.0

starts a minio array

v 4.0
(defn start-minio-array
  [ports]
  (mapv (fn [port]
          (let [m (if (number? port)
                    {:port port}
                    port)
                out (start-minio-server m :array (str +bench-path+ "/" (:port m)))
                _   (network/wait-for-port "127.0.0.1" (:port m))]
            out))
        ports))
link
(with-redefs [start-minio-server (fn [m type root-dir] (assoc m :type type :root root-dir)) network/wait-for-port (fn [& _] true)] (start-minio-array [9000 {:port 9001}])) => [{:port 9000 :type :array :root (str +bench-path+ "/9000")} {:port 9001 :type :array :root (str +bench-path+ "/9001")}]

stop-minio-array ^

[ports]
Added 4.0

stops a minio array

v 4.0
(defn stop-minio-array
  [ports]
  (map (fn [port]
         (stop-minio-server port :array))
       ports))
link
(with-redefs [stop-minio-server (fn [port type] [port type])] (doall (stop-minio-array [9000 9001]))) => [[9000 :array] [9001 :array]]


*active* ^

NONE
(defonce ^:dynamic *active* (atom {}))
link

+bench-path+ ^

NONE
(def +bench-path+)
link

all-minio-ports ^

[]
Added 4.0

gets all active minio ports

v 4.0
(defn all-minio-ports
  ([]
   (->> (os/sh "lsof" "-i" "-P" "-n" {:wrap false})
        (clojure.string/split-lines)
        (drop 1)
        (filter #(clojure.string/starts-with? % "minio"))
        (keep #(re-find #"^minios*(d+).*:(d+) (LISTEN)$" %))
        (map (fn [arr]
               (mapv f/parse-long (drop 1 arr))))
        (group-by second)
        (collection/map-vals (comp set (partial map first))))))
link
(with-redefs [os/sh (fn [& _] "COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEnminio 101 user 1u IPv4 0 0 TCP *:9000 (LISTEN)nminio 102 user 1u IPv4 0 0 TCP *:9000 (LISTEN)nminio 103 user 1u IPv4 0 0 TCP *:9001 (LISTEN)")] (all-minio-ports)) => {9000 #{101 102} 9001 #{103}}

bench-start ^

[{:keys [port], :as minio} type]
Added 4.0

starts the bench

v 4.0
(defn bench-start
  [{:keys [port] :as minio} type]
  (let [root-dir (case type
                   :scratch (str (fs/create-tmpdir))
                   (str +bench-path+ "/" port))
        entry  (start-minio-server minio type root-dir)]
    (assoc minio :port (:port entry))))
link
(with-redefs [fs/create-tmpdir (fn [] "/tmp/minio-scratch") start-minio-server (fn [minio type root-dir] {:port 9010 :type type :root root-dir})] (bench-start {} :scratch)) => {:port 9010}

bench-stop ^

[{:keys [port bench], :as minio} _]
Added 4.0

stops the bench

v 4.0
(defn bench-stop
  [{:keys [port bench] :as minio} _]
  (let [{:keys [type process]} (get @*active* port)]
    (stop-minio-server port bench)
    minio))
link
(binding [*active* (atom {9010 {:type :scratch :process :process}})] (with-redefs [stop-minio-server (fn [port bench] [port bench])] (bench-stop {:port 9010 :bench :scratch} nil))) => {:port 9010 :bench :scratch}

start-minio-array ^

[ports]
Added 4.0

starts a minio array

v 4.0
(defn start-minio-array
  [ports]
  (mapv (fn [port]
          (let [m (if (number? port)
                    {:port port}
                    port)
                out (start-minio-server m :array (str +bench-path+ "/" (:port m)))
                _   (network/wait-for-port "127.0.0.1" (:port m))]
            out))
        ports))
link
(with-redefs [start-minio-server (fn [m type root-dir] (assoc m :type type :root root-dir)) network/wait-for-port (fn [& _] true)] (start-minio-array [9000 {:port 9001}])) => [{:port 9000 :type :array :root (str +bench-path+ "/9000")} {:port 9001 :type :array :root (str +bench-path+ "/9001")}]

start-minio-server ^

[{:keys [port console init]} type root-dir]
Added 4.0

starts the minio server in a given directory

v 4.0
(defn start-minio-server
  [{:keys [port console init]} type root-dir]
  (let [port (or port (network/port:check-available 0))
        console-port (or console (network/port:check-available 0))
        _ (fs/create-directory root-dir)]
    (-> (if (not (get @*active* port))
          (swap! *active*
                 (fn [m]
                   (let [process (os/sh {:args [#_#_#_
                                               "MINIO_ROOT_USER=admin"
                                               "MINIO_ROOT_PASSWORD=password"
                                               "MINIO_BROWSER=off" 
                                               "minio" "server" "./data"
                                               "--address" (str ":" port)
                                               "--console-address" (str ":" console-port)]
                                        #_#_
                                        :env  {"MINIO_ROOT_USER" "admin"
                                               "MINIO_ROOT_PASSWORD" "password"
                                               "MINIO_BROWSER" "off"}
                                        :wait false
                                        :root root-dir})
                         thread  (-> (future/future (os/sh-wait process))
                                     (future/on:complete (fn [_ _]
                                                      (let [out (os/sh-output process)]
                                                        (when (not= 0 (:exit out))
                                                          (env/prn out)))
                                                      (swap! *active* dissoc port))))]
                     (network/wait-for-port "localhost" port
                                      {:timeout 3000})
                     (assoc m port {:type type
                                    :port port
                                    :root root-dir
                                    :process process
                                    :thread thread}))))
          @*active*)
        (get port))))
link
(binding [*active* (atom {})] (with-redefs [network/port:check-available (constantly 9000) fs/create-directory (fn [_] nil) os/sh (fn [& _] :process) os/sh-wait (fn [_] nil) future/future:run (fn [& _] :thread) future/on:complete (fn [thread _] thread) network/wait-for-port (fn [& _] true)] (start-minio-server {} :bench "/tmp/minio-root"))) => (contains {:type :bench :port 9000 :root "/tmp/minio-root" :process :process :thread some?})

stop-minio-array ^

[ports]
Added 4.0

stops a minio array

v 4.0
(defn stop-minio-array
  [ports]
  (map (fn [port]
         (stop-minio-server port :array))
       ports))
link
(with-redefs [stop-minio-server (fn [port type] [port type])] (doall (stop-minio-array [9000 9001]))) => [[9000 :array] [9001 :array]]

stop-minio-server ^

[port stop-type]
Added 4.0

stop the minio server

v 4.0
(defn stop-minio-server
  [port stop-type]
  (let [{:keys [type process] :as entry} (get @*active* port)]
    (if (= type stop-type)
      (doto process
        (os/sh-close)
        (os/sh-exit)
        (os/sh-wait)))
    entry))
link
(binding [*active* (atom {9000 {:type :bench :process :process}})] (with-redefs [os/sh-close identity os/sh-exit identity os/sh-wait identity] (stop-minio-server 9000 :bench))) => {:type :bench :process :process}