skopedate (empty) → 0.1
raw patch · 6 files changed
+264/−0 lines, 6 filesdep +aesondep +basedep +bytestring
Dependencies added: aeson, base, bytestring, extra, http-query, simple-cmd, simple-cmd-args, time, typed-process
Files
- CHANGELOG.md +6/−0
- LICENSE +21/−0
- README.md +51/−0
- skopedate.cabal +66/−0
- src/Main.hs +97/−0
- test/tests.hs +23/−0
+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Changelog++## 0.1+- initial release+- uses aeson, ansi-terminal, time, typed-process+- reads image json from remote registry with skopeo and extracts creation time
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2018-2021,2023 Jens Petersen++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.
+ README.md view
@@ -0,0 +1,51 @@+# skopedate++[](LICENSE)++Check/compares dates of container images for Fedora, Centos, etc, using skopeo.+Currently the list of predefined registries is hardcoded.++## Usage+```+$ skopedate --version+0.1+$ skopedate --help+Checks dates of latest container images++Usage: skopedate [--version] [-d|--debug] IMAGE++ A tool for seeing the dates of latest container images in registries++Available options:+ -h,--help Show this help text+ --version Show version+ -d,--debug show debug output+```++```+$ skopedate fedora:39+registry.fedoraproject.org 2023-08-11 17:33:49 +0800+candidate-registry.fedoraproject.org 2023-08-11 17:33:49 +0800+quay.io/fedora 2023-08-11 17:33:49 +0800+docker.io 2023-08-05 02:23:06 +0800+```++```+$ skopedate centos/centos:stream9+quay.io 2023-08-08 11:39:14 +0800+```++```+$ skopedate fedora-toolbox:39+registry.fedoraproject.org 2023-08-11 17:33:52 +0800+candidate-registry.fedoraproject.org 2023-08-11 17:33:52 +0800+```++## Installation++`stack install` or `cabal install`++## Contribute+skopedate is distributed under the MIT license.++See https://github.com/juhp/skopedate
+ skopedate.cabal view
@@ -0,0 +1,66 @@+name: skopedate+version: 0.1+synopsis: Check dates of container images+description: This tool checks the dates of a container image in+ registries.+license: MIT+license-file: LICENSE+author: Jens Petersen <juhpetersen@gmail.com>+maintainer: Jens Petersen <juhpetersen@gmail.com>+copyright: 2018-2021,2023 Jens Petersen+category: Utility+homepage: https://github.com/juhp/skopedate+bug-reports: https://github.com/juhp/skopedate/issues+build-type: Simple+extra-doc-files: README.md+ CHANGELOG.md+cabal-version: 2.0+tested-with: GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7,+ GHC == 9.0.2, GHC == 9.2.8, GHC == 9.4.5, GHC == 9.6.2++source-repository head+ type: git+ location: https://github.com/juhp/skopedate.git++executable skopedate+ main-is: src/Main.hs+ autogen-modules: Paths_skopedate+ other-modules: Paths_skopedate++ build-depends: aeson+ , base < 5+ , bytestring+ , extra+ , http-query+ , simple-cmd >= 0.2.1+ , simple-cmd-args+ , time+ , typed-process+ default-language: Haskell2010++ ghc-options: -Wall+ if impl(ghc >= 8.0)+ ghc-options: -Wcompat+ -Widentities+ -Wincomplete-uni-patterns+ -Wincomplete-record-updates+ -Wredundant-constraints+ if impl(ghc >= 8.2)+ ghc-options: -fhide-source-paths+ if impl(ghc >= 8.4)+ ghc-options: -Wmissing-export-lists+ -Wpartial-fields+ if impl(ghc >= 8.10)+ ghc-options: -Wunused-packages++test-suite test+ main-is: tests.hs+ type: exitcode-stdio-1.0+ hs-source-dirs: test++ default-language: Haskell2010++ ghc-options: -Wall+ build-depends: base >= 4 && < 5,+ simple-cmd+ build-tool-depends: skopedate:skopedate
+ src/Main.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE CPP, OverloadedStrings #-}++module Main (main) where++import Control.Monad.Extra (when)+import Data.Aeson (decode)+import qualified Data.ByteString.Lazy.Char8 as B+import Data.List.Extra (breakOn, isPrefixOf)+import Data.Time.Clock (UTCTime)+import Data.Time.Format (defaultTimeLocale, formatTime)+import Data.Time.LocalTime (utcToLocalZonedTime)+import Network.HTTP.Query (lookupKey, (+/+))+import SimpleCmd (needProgram, warning)+import SimpleCmdArgs (simpleCmdArgs, switchWith, strArg)+import System.IO (hFlush, stdout)+import System.Process.Typed (proc, readProcessStdout,+#if MIN_VERSION_typed_process(0,2,8)+ ExitCode(ExitSuccess)+#endif+ )+#if !MIN_VERSION_typed_process(0,2,8)+import System.Exit (ExitCode(ExitSuccess))+#endif++import Paths_skopedate++main :: IO ()+main = do+ simpleCmdArgs (Just version) "Checks dates of latest container images"+ "A tool for seeing the dates of latest container images in registries" $+ checkRegistries+ <$> switchWith 'd' "debug" "show debug output"+ <*> strArg "IMAGE"++imageRegistries :: String -> [String]+imageRegistries image =+ let (untagged,_tag) = breakOn ":" image+ in+ case filter (\(i,_) -> i `isPrefixOf` untagged) matchOS of+ (_,rs):_ -> rs+ [] ->+ case breakOn "/" untagged of+ (_, "") -> ["docker.io"]+ (before,_after) ->+ ["docker.io" | '.' `notElem` before]+ where+ matchOS :: [(String,[String])]+ matchOS = [("fedora-toolbox",["registry.fedoraproject.org",+ "candidate-registry.fedoraproject.org"]),+ ("fedora",["registry.fedoraproject.org",+ "candidate-registry.fedoraproject.org",+ "quay.io/fedora",+ "docker.io"]),+ ("centos", ["quay.io"]),+ ("ubi", ["registry.access.redhat.com"]),+ ("opensuse", ["registry.opensuse.org", "docker.io"])]++checkRegistries :: Bool -> String -> IO ()+checkRegistries debug image = do+ needProgram "skopeo"+ case imageRegistries image of+ [] -> skopeoInspectTimeRel "" (length image) image+ regs ->+ let width = maximum $ map length regs+ in mapM_ (skopeoInspectTimeRel image width) regs+ where+ skopeoInspectTimeRel :: String -> Int -> String -> IO ()+ skopeoInspectTimeRel img width reg = do+ let ref = "docker://" ++ reg +/+ img+ putStr $ if debug+ then ref+ else reg ++ replicate (width - length reg + 1) ' '+ hFlush stdout+ (ok,out) <- readProcessStdout $ proc "skopeo" ["inspect", ref]+ when (ok == ExitSuccess) $ do+ when debug $ do+ putChar '\n'+ B.putStrLn out+ case parseTimeRel out of+ Just res -> printTime res+ Nothing -> warning "image not found"+ where+ parseTimeRel :: B.ByteString -> Maybe (UTCTime, Maybe String)+ parseTimeRel bs = do+ obj <- decode bs+ utc <- lookupKey "Created" obj+ let mlabels = lookupKey "Labels" obj+ return (utc, mlabels >>= lookupKey "release")++ printTime (u,mr) = do+ t <- utcToLocalZonedTime u+ putStrLn $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S %z" t ++ maybeRel mr++ maybeRel :: Maybe String -> String+ maybeRel Nothing = ""+ maybeRel (Just r) =+ " rel:" ++ (if length r < 2 then " " else "") ++ r
+ test/tests.hs view
@@ -0,0 +1,23 @@+import SimpleCmd+import System.IO++program :: String -> IO ()+program image =+ putStrLn ("\n# " ++ image) >>+ cmd_ "skopedate" [image]++images :: [String]+images =+ [ "fedora:39"+ , "centos/centos:stream9"+ , "fedora-toolbox:39"+ , "ubi9"+ , "opensuse/tumbleweed"+ , "docker.io/library/alpine"+ ]++main :: IO ()+main = do+ hSetBuffering stdout NoBuffering+ mapM_ program images+ putStrLn $ "\n" ++ show (length images) ++ " command tests run"