detached 396cee3

Manager WIP on listing all containers images from the specified .sock. Also catch response errors and display it in the DOM

commit
396cee3c997144314c62c6dc4f9f93f7c2f2ac51
author
bnema · · 2023-09-20 13:33 UTC
parent
64163ef
signature
unsigned
12 files · +227 -97
M go.mod +6 -6
@@ -5,6 +5,7 @@ go 1.21.1
55 require (
66 github.com/PuerkitoBio/goquery v1.8.1
77 github.com/docker/docker v24.0.6+incompatible
8+ github.com/google/safehtml v0.1.0
89 github.com/gorilla/sessions v1.2.1
910 github.com/joho/godotenv v1.5.1
1011 github.com/labstack/echo-contrib v0.15.0
@@ -17,30 +18,29 @@ require (
1718 require (
1819 github.com/Microsoft/go-winio v0.6.1 // indirect
1920 github.com/andybalholm/cascadia v1.3.1 // indirect
20- github.com/containerd/containerd v1.7.6 // indirect
21+ github.com/aymerick/douceur v0.2.0 // indirect
2122 github.com/docker/distribution v2.8.2+incompatible // indirect
2223 github.com/docker/go-connections v0.4.0 // indirect
2324 github.com/docker/go-units v0.5.0 // indirect
2425 github.com/gogo/protobuf v1.3.2 // indirect
2526 github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
2627 github.com/golang/protobuf v1.5.3 // indirect
28+ github.com/google/go-cmp v0.5.9 // indirect
2729 github.com/gorilla/context v1.1.1 // indirect
30+ github.com/gorilla/css v1.0.0 // indirect
2831 github.com/gorilla/mux v1.6.2 // indirect
2932 github.com/gorilla/securecookie v1.1.1 // indirect
30- github.com/klauspost/compress v1.16.7 // indirect
3133 github.com/labstack/gommon v0.4.0 // indirect
3234 github.com/mattn/go-colorable v0.1.13 // indirect
3335 github.com/mattn/go-isatty v0.0.19 // indirect
34- github.com/moby/patternmatcher v0.6.0 // indirect
35- github.com/moby/sys/sequential v0.5.0 // indirect
36+ github.com/microcosm-cc/bluemonday v1.0.25 // indirect
3637 github.com/moby/term v0.5.0 // indirect
3738 github.com/morikuni/aec v1.0.0 // indirect
3839 github.com/opencontainers/go-digest v1.0.0 // indirect
3940 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
40- github.com/opencontainers/runc v1.1.9 // indirect
4141 github.com/pkg/errors v0.9.1 // indirect
4242 github.com/rogpeppe/go-internal v1.11.0 // indirect
43- github.com/sirupsen/logrus v1.9.3 // indirect
43+ github.com/stretchr/testify v1.8.2 // indirect
4444 github.com/valyala/bytebufferpool v1.0.0 // indirect
4545 github.com/valyala/fasttemplate v1.2.2 // indirect
4646 golang.org/x/crypto v0.11.0 // indirect
@@ -5,6 +5,7 @@ go 1.21.1
5 require (5 require (
6 github.com/PuerkitoBio/goquery v1.8.16 github.com/PuerkitoBio/goquery v1.8.1
7 github.com/docker/docker v24.0.6+incompatible7 github.com/docker/docker v24.0.6+incompatible
8+ github.com/google/safehtml v0.1.0
8 github.com/gorilla/sessions v1.2.19 github.com/gorilla/sessions v1.2.1
9 github.com/joho/godotenv v1.5.110 github.com/joho/godotenv v1.5.1
10 github.com/labstack/echo-contrib v0.15.011 github.com/labstack/echo-contrib v0.15.0
@@ -17,30 +18,29 @@ require (
17 require (18 require (
18 github.com/Microsoft/go-winio v0.6.1 // indirect19 github.com/Microsoft/go-winio v0.6.1 // indirect
19 github.com/andybalholm/cascadia v1.3.1 // indirect20 github.com/andybalholm/cascadia v1.3.1 // indirect
20- github.com/containerd/containerd v1.7.6 // indirect21+ github.com/aymerick/douceur v0.2.0 // indirect
21 github.com/docker/distribution v2.8.2+incompatible // indirect22 github.com/docker/distribution v2.8.2+incompatible // indirect
22 github.com/docker/go-connections v0.4.0 // indirect23 github.com/docker/go-connections v0.4.0 // indirect
23 github.com/docker/go-units v0.5.0 // indirect24 github.com/docker/go-units v0.5.0 // indirect
24 github.com/gogo/protobuf v1.3.2 // indirect25 github.com/gogo/protobuf v1.3.2 // indirect
25 github.com/golang-jwt/jwt v3.2.2+incompatible // indirect26 github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
26 github.com/golang/protobuf v1.5.3 // indirect27 github.com/golang/protobuf v1.5.3 // indirect
28+ github.com/google/go-cmp v0.5.9 // indirect
27 github.com/gorilla/context v1.1.1 // indirect29 github.com/gorilla/context v1.1.1 // indirect
30+ github.com/gorilla/css v1.0.0 // indirect
28 github.com/gorilla/mux v1.6.2 // indirect31 github.com/gorilla/mux v1.6.2 // indirect
29 github.com/gorilla/securecookie v1.1.1 // indirect32 github.com/gorilla/securecookie v1.1.1 // indirect
30- github.com/klauspost/compress v1.16.7 // indirect
31 github.com/labstack/gommon v0.4.0 // indirect33 github.com/labstack/gommon v0.4.0 // indirect
32 github.com/mattn/go-colorable v0.1.13 // indirect34 github.com/mattn/go-colorable v0.1.13 // indirect
33 github.com/mattn/go-isatty v0.0.19 // indirect35 github.com/mattn/go-isatty v0.0.19 // indirect
34- github.com/moby/patternmatcher v0.6.0 // indirect36+ github.com/microcosm-cc/bluemonday v1.0.25 // indirect
35- github.com/moby/sys/sequential v0.5.0 // indirect
36 github.com/moby/term v0.5.0 // indirect37 github.com/moby/term v0.5.0 // indirect
37 github.com/morikuni/aec v1.0.0 // indirect38 github.com/morikuni/aec v1.0.0 // indirect
38 github.com/opencontainers/go-digest v1.0.0 // indirect39 github.com/opencontainers/go-digest v1.0.0 // indirect
39 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect40 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
40- github.com/opencontainers/runc v1.1.9 // indirect
41 github.com/pkg/errors v0.9.1 // indirect41 github.com/pkg/errors v0.9.1 // indirect
42 github.com/rogpeppe/go-internal v1.11.0 // indirect42 github.com/rogpeppe/go-internal v1.11.0 // indirect
43- github.com/sirupsen/logrus v1.9.3 // indirect43+ github.com/stretchr/testify v1.8.2 // indirect
44 github.com/valyala/bytebufferpool v1.0.0 // indirect44 github.com/valyala/bytebufferpool v1.0.0 // indirect
45 github.com/valyala/fasttemplate v1.2.2 // indirect45 github.com/valyala/fasttemplate v1.2.2 // indirect
46 golang.org/x/crypto v0.11.0 // indirect46 golang.org/x/crypto v0.11.0 // indirect
M go.sum +11 -17
@@ -32,28 +32,24 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
3232 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
3333 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
3434 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
35-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
36-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
3735 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
3836 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
3937 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4038 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
4139 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
4240 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
43-github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM=
44-github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
4541 github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
4642 github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
4743 github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
4844 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
45+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
46+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
4947 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
5048 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
5149 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
5250 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
5351 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
5452 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
55-github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
56-github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
5753 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5854 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5955 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -131,10 +127,14 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
131127 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
132128 github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
133129 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
130+github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8=
131+github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
134132 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
135133 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
136134 github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
137135 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
136+github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
137+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
138138 github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
139139 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
140140 github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
@@ -153,8 +153,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
153153 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
154154 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
155155 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
156-github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
157-github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
158156 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
159157 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
160158 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -185,10 +183,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
185183 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
186184 github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
187185 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
188-github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
189-github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
190-github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
191-github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
186+github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
187+github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
192188 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
193189 github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
194190 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -198,8 +194,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
198194 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
199195 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
200196 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
201-github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM=
202-github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
203197 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
204198 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
205199 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -208,14 +202,15 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
208202 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
209203 github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
210204 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
211-github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
212-github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
213205 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
206+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
207+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
214208 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
215209 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
216210 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
217211 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
218212 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
213+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
219214 github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
220215 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
221216 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -364,7 +359,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
364359 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
365360 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
366361 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
367-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
368362 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
369363 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
370364 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -32,28 +32,24 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
32 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=32 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
33 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=33 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
34 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=34 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
35-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
36-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
37 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=35 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
38 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=36 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
39 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=37 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
40 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=38 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
41 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=39 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
42 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=40 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
43-github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM=
44-github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
45 github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=41 github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
46 github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=42 github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
47 github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=43 github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
48 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=44 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
45+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
46+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
49 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=47 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
50 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=48 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
51 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=49 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
52 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=50 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
53 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=51 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
54 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=52 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
55-github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
56-github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
57 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=53 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
58 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=54 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
59 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=55 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -131,10 +127,14 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
131 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=127 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
132 github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=128 github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
133 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=129 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
130+github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8=
131+github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
134 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=132 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
135 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=133 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
136 github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=134 github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
137 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=135 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
136+github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
137+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
138 github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=138 github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
139 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=139 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
140 github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=140 github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
@@ -153,8 +153,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
153 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=153 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
154 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=154 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
155 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=155 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
156-github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
157-github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
158 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=156 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
159 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=157 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
160 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=158 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -185,10 +183,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
185 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=183 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
186 github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=184 github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
187 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=185 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
188-github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=186+github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
189-github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=187+github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
190-github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
191-github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
192 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=188 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
193 github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=189 github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
194 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=190 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -198,8 +194,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
198 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=194 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
199 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=195 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
200 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=196 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
201-github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM=
202-github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
203 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=197 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
204 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=198 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
205 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=199 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -208,14 +202,15 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
208 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=202 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
209 github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=203 github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
210 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=204 github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
211-github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
212-github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
213 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=205 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
206+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
207+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
214 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=208 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
215 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=209 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
216 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=210 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
217 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=211 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
218 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=212 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
213+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
219 github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=214 github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
220 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=215 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
221 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=216 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -364,7 +359,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
364 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=359 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
365 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=360 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
366 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=361 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
367-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
368 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=362 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
369 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=363 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
370 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=364 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
M internal/gotemplate/models/html/admin/index.gohtml +6 -44
@@ -1,52 +1,11 @@
11 <!DOCTYPE html>
22 <html lang="en">
33
4-<head>
5- <meta charset="UTF-8" />
6- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7- <title>{{ .header.meta.title }}</title>
8- <link rel="stylesheet" href="/assets/css/tailwind.css" />
9- <link rel="stylesheet" href="/libs/iconoir.css" />
10- <script src="/libs/alpine.min.js"></script>
11- <script src="/libs/htmx.min.js"></script>
12- <script src="/libs/htmx-sse.js"></script>
13- <script src="assets/js/custom.js"></script>
14-</head>
4+{{template "header.gohtml" .}}
155
166 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">
17- <div class="w-full md:w-1/5 flex flex-col space-evenly p-4 md:p-0">
18- <div class="hidden md:flex justify-center p-4">
19- <img src="/assets/imgs/gordon-mascot-hq-trsp.png" alt="logo" class="h-32" />
20- </div>
21- <div class="p-4 flex flex-col bg-gordonmascot-lblue rounded-lg shadow space-y-4">
22- <div class="w-full flex justify-center">
23- <h1 class="gordon-title text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter">Gordon</h1>
24- <span class="text-gordonmascot-mblue text-sm">{{ .BuildVersion }}</span>
25- </div>
26- <div class="w-full">
27- <ul
28- class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit">
29- <li class="flex items-center w-1/2 md:w-full">
30- <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i>
31- <a href="#">Dashboard</a>
32- </li>
33- <li class="flex items-center w-1/2 md:w-full">
34- <i class="iconoir-server mr-2 md:text-3xl"></i>
35- <a href="#manager">Manager</a>
36- </li>
37- <li class="flex items-center w-1/2 md:w-full">
38- <i class="iconoir-community mr-2 md:text-3xl"></i>
39- <a href="#users">Users</a>
40- </li>
41- <li class="flex items-center w-1/2 md:w-full">
42- <i class="iconoir-database-settings mr-2 md:text-3xl"></i>
43- <a href="#gordon-settings">Settings</a>
44- </li>
45- </ul>
46- </div>
47- </div>
48- </div>
497
8+ {{template "leftmenu.gohtml" .}}
509 <div class="flex-1 flex flex-col md:pt-10 space-y-4 p-4 md:ml-4">
5110 <div class="hidden md:flex mb-4 justify-end">
5211 <div class="w-72 h-10 bg-gray-300 rounded-lg">
@@ -58,7 +17,7 @@
5817 </div>
5918 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">
6019 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">
61- <div class="w-full rounded-sm bg-gray-300"></div>
20+ <h2>Dashboard</h2>
6221 </div>
6322 <div class="w-full md:w-2/6 flex flex-col space-y-4">
6423 <div class="bg-white p-4 rounded-md shadow mb-4">
@@ -73,6 +32,9 @@
7332 </div>
7433 </div>
7534 </div>
35+ <!-- footer -->
36+ {{template "footer.gohtml" .}}
37+
7638 </body>
7739
7840 </html>⏎̸
@@ -1,52 +1,11 @@
1 <!DOCTYPE html>1 <!DOCTYPE html>
2 <html lang="en">2 <html lang="en">
3 3
4-<head>4+{{template "header.gohtml" .}}
5- <meta charset="UTF-8" />
6- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7- <title>{{ .header.meta.title }}</title>
8- <link rel="stylesheet" href="/assets/css/tailwind.css" />
9- <link rel="stylesheet" href="/libs/iconoir.css" />
10- <script src="/libs/alpine.min.js"></script>
11- <script src="/libs/htmx.min.js"></script>
12- <script src="/libs/htmx-sse.js"></script>
13- <script src="assets/js/custom.js"></script>
14-</head>
15 5
16 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">6 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">
17- <div class="w-full md:w-1/5 flex flex-col space-evenly p-4 md:p-0">
18- <div class="hidden md:flex justify-center p-4">
19- <img src="/assets/imgs/gordon-mascot-hq-trsp.png" alt="logo" class="h-32" />
20- </div>
21- <div class="p-4 flex flex-col bg-gordonmascot-lblue rounded-lg shadow space-y-4">
22- <div class="w-full flex justify-center">
23- <h1 class="gordon-title text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter">Gordon</h1>
24- <span class="text-gordonmascot-mblue text-sm">{{ .BuildVersion }}</span>
25- </div>
26- <div class="w-full">
27- <ul
28- class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit">
29- <li class="flex items-center w-1/2 md:w-full">
30- <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i>
31- <a href="#">Dashboard</a>
32- </li>
33- <li class="flex items-center w-1/2 md:w-full">
34- <i class="iconoir-server mr-2 md:text-3xl"></i>
35- <a href="#manager">Manager</a>
36- </li>
37- <li class="flex items-center w-1/2 md:w-full">
38- <i class="iconoir-community mr-2 md:text-3xl"></i>
39- <a href="#users">Users</a>
40- </li>
41- <li class="flex items-center w-1/2 md:w-full">
42- <i class="iconoir-database-settings mr-2 md:text-3xl"></i>
43- <a href="#gordon-settings">Settings</a>
44- </li>
45- </ul>
46- </div>
47- </div>
48- </div>
49 7
8+ {{template "leftmenu.gohtml" .}}
50 <div class="flex-1 flex flex-col md:pt-10 space-y-4 p-4 md:ml-4">9 <div class="flex-1 flex flex-col md:pt-10 space-y-4 p-4 md:ml-4">
51 <div class="hidden md:flex mb-4 justify-end">10 <div class="hidden md:flex mb-4 justify-end">
52 <div class="w-72 h-10 bg-gray-300 rounded-lg">11 <div class="w-72 h-10 bg-gray-300 rounded-lg">
@@ -58,7 +17,7 @@
58 </div>17 </div>
59 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">18 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">
60 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">19 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">
61- <div class="w-full rounded-sm bg-gray-300"></div>20+ <h2>Dashboard</h2>
62 </div>21 </div>
63 <div class="w-full md:w-2/6 flex flex-col space-y-4">22 <div class="w-full md:w-2/6 flex flex-col space-y-4">
64 <div class="bg-white p-4 rounded-md shadow mb-4">23 <div class="bg-white p-4 rounded-md shadow mb-4">
@@ -73,6 +32,9 @@
73 </div>32 </div>
74 </div>33 </div>
75 </div>34 </div>
35+ <!-- footer -->
36+ {{template "footer.gohtml" .}}
37+
76 </body>38 </body>
77 39
78 </html>⏎̸40 </html>⏎̸
M internal/gotemplate/models/html/admin/manager.gohtml +28 -6
@@ -1,20 +1,42 @@
11 <!-- manager.gohtml -->
2-{{template "header.gohtml" .}}
32 <!DOCTYPE html>
43 <html lang="en">
54
5+{{template "header.gohtml" .}}
6+
67 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">
78 {{template "leftmenu.gohtml" .}}
89 <!-- Main content here -->
9- <div class="flex-1 flex flex-col md:pt-10 space-y-4 p-4 md:ml-4">
10- <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">
10+ <!-- This div will contain the error message when something goes wrong -->
11+ <div id="container-images-error" style="display:none;">
12+ Something went wrong. </div>
13+ <div class="flex-1 flex flex-col space-y-4 p-4 md:ml-4">
14+ <div class="flex flex-col md:flex-row w-full flex-grow md:mt-24">
1115 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">
12- <h1>hello world</h1>
16+ <h1>Container Manager</h1>
17+ <!-- List all the images on load with HTMX -->
18+ <div id="container-images" hx-get="/image-manager" hx-trigger="load" hx-swap="innerHTML" hx-swap-oob="true"
19+ hx-target-error="container-images-error">
20+ {{range .Images}}
21+ <div class="image-info">
22+ <p>ID: {{.ID}}</p>
23+ <p>Repository: {{.Repository}}</p>
24+ <p>Tag: {{.Tag}}</p>
25+ <p>Created: {{.Created}}</p>
26+ <p>Size: {{.Size}}</p>
27+ </div>
28+ {{else}}
29+ <p>No images found.</p>
30+ {{end}}
31+ </div>
32+
33+
1334 </div>
1435 </div>
36+ </div>
1537
16- <!-- footer -->
17- {{template "footer.gohtml" .}}
38+ <!-- footer -->
39+ {{template "footer.gohtml" .}}
1840 </body>
1941
2042 </html>⏎̸
@@ -1,20 +1,42 @@
1 <!-- manager.gohtml -->1 <!-- manager.gohtml -->
2-{{template "header.gohtml" .}}
3 <!DOCTYPE html>2 <!DOCTYPE html>
4 <html lang="en">3 <html lang="en">
5 4
5+{{template "header.gohtml" .}}
6+
6 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">7 <body class="bg-zinc-200 flex flex-col md:flex-row p-4 md:p-8 p-0">
7 {{template "leftmenu.gohtml" .}}8 {{template "leftmenu.gohtml" .}}
8 <!-- Main content here -->9 <!-- Main content here -->
9- <div class="flex-1 flex flex-col md:pt-10 space-y-4 p-4 md:ml-4">10+ <!-- This div will contain the error message when something goes wrong -->
10- <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">11+ <div id="container-images-error" style="display:none;">
12+ Something went wrong. </div>
13+ <div class="flex-1 flex flex-col space-y-4 p-4 md:ml-4">
14+ <div class="flex flex-col md:flex-row w-full flex-grow md:mt-24">
11 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">15 <div class="flex-grow bg-white p-4 rounded-md shadow mb-4">
12- <h1>hello world</h1>16+ <h1>Container Manager</h1>
17+ <!-- List all the images on load with HTMX -->
18+ <div id="container-images" hx-get="/image-manager" hx-trigger="load" hx-swap="innerHTML" hx-swap-oob="true"
19+ hx-target-error="container-images-error">
20+ {{range .Images}}
21+ <div class="image-info">
22+ <p>ID: {{.ID}}</p>
23+ <p>Repository: {{.Repository}}</p>
24+ <p>Tag: {{.Tag}}</p>
25+ <p>Created: {{.Created}}</p>
26+ <p>Size: {{.Size}}</p>
27+ </div>
28+ {{else}}
29+ <p>No images found.</p>
30+ {{end}}
31+ </div>
32+
33+
13 </div>34 </div>
14 </div>35 </div>
36+ </div>
15 37
16- <!-- footer -->38+ <!-- footer -->
17- {{template "footer.gohtml" .}}39+ {{template "footer.gohtml" .}}
18 </body>40 </body>
19 41
20 </html>⏎̸42 </html>⏎̸
M internal/gotemplate/models/html/fragments/header.gohtml +2 -2
@@ -4,8 +4,8 @@
44 <title>{{ .header.meta.title }}</title>
55 <link rel="stylesheet" href="/assets/css/tailwind.css" />
66 <link rel="stylesheet" href="/libs/iconoir.css" />
7- <script src="/libs/alpine.min.js"></script>
7+ <script src="/libs/alpine.min.js" defer></script>
88 <script src="/libs/htmx.min.js"></script>
99 <script src="/libs/htmx-sse.js"></script>
10- <script src="assets/js/custom.js"></script>
10+ <script src="/assets/js/custom.js" defer></script>
1111 </head>⏎̸
@@ -4,8 +4,8 @@
4 <title>{{ .header.meta.title }}</title>4 <title>{{ .header.meta.title }}</title>
5 <link rel="stylesheet" href="/assets/css/tailwind.css" />5 <link rel="stylesheet" href="/assets/css/tailwind.css" />
6 <link rel="stylesheet" href="/libs/iconoir.css" />6 <link rel="stylesheet" href="/libs/iconoir.css" />
7- <script src="/libs/alpine.min.js"></script>7+ <script src="/libs/alpine.min.js" defer></script>
8 <script src="/libs/htmx.min.js"></script>8 <script src="/libs/htmx.min.js"></script>
9 <script src="/libs/htmx-sse.js"></script>9 <script src="/libs/htmx-sse.js"></script>
10- <script src="assets/js/custom.js"></script>10+ <script src="/assets/js/custom.js" defer></script>
11 </head>⏎̸11 </head>⏎̸
M internal/gotemplate/models/html/fragments/leftmenu.gohtml +6 -5
@@ -9,22 +9,23 @@
99 </div>
1010 <div class="w-full">
1111 <ul
12- class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit">
12+ class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit"
13+ hx-boost="true">
1314 <li class="flex items-center w-1/2 md:w-full">
1415 <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i>
15- <a href="#">Dashboard</a>
16+ <a href="/admin">Dashboard</a>
1617 </li>
1718 <li class="flex items-center w-1/2 md:w-full">
1819 <i class="iconoir-server mr-2 md:text-3xl"></i>
19- <a href="#manager">Manager</a>
20+ <a href="/admin/manager">Manager</a>
2021 </li>
2122 <li class="flex items-center w-1/2 md:w-full">
2223 <i class="iconoir-community mr-2 md:text-3xl"></i>
23- <a href="#users">Users</a>
24+ <a href="/admin/users">Users</a>
2425 </li>
2526 <li class="flex items-center w-1/2 md:w-full">
2627 <i class="iconoir-database-settings mr-2 md:text-3xl"></i>
27- <a href="#gordon-settings">Settings</a>
28+ <a href="/admin/settings">Settings</a>
2829 </li>
2930 </ul>
3031 </div>
@@ -9,22 +9,23 @@
9 </div>9 </div>
10 <div class="w-full">10 <div class="w-full">
11 <ul11 <ul
12- class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit">12+ class="flex flex-wrap md:flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4 min-w-fit"
13+ hx-boost="true">
13 <li class="flex items-center w-1/2 md:w-full">14 <li class="flex items-center w-1/2 md:w-full">
14 <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i>15 <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i>
15- <a href="#">Dashboard</a>16+ <a href="/admin">Dashboard</a>
16 </li>17 </li>
17 <li class="flex items-center w-1/2 md:w-full">18 <li class="flex items-center w-1/2 md:w-full">
18 <i class="iconoir-server mr-2 md:text-3xl"></i>19 <i class="iconoir-server mr-2 md:text-3xl"></i>
19- <a href="#manager">Manager</a>20+ <a href="/admin/manager">Manager</a>
20 </li>21 </li>
21 <li class="flex items-center w-1/2 md:w-full">22 <li class="flex items-center w-1/2 md:w-full">
22 <i class="iconoir-community mr-2 md:text-3xl"></i>23 <i class="iconoir-community mr-2 md:text-3xl"></i>
23- <a href="#users">Users</a>24+ <a href="/admin/users">Users</a>
24 </li>25 </li>
25 <li class="flex items-center w-1/2 md:w-full">26 <li class="flex items-center w-1/2 md:w-full">
26 <i class="iconoir-database-settings mr-2 md:text-3xl"></i>27 <i class="iconoir-database-settings mr-2 md:text-3xl"></i>
27- <a href="#gordon-settings">Settings</a>28+ <a href="/admin/settings">Settings</a>
28 </li>29 </li>
29 </ul>30 </ul>
30 </div>31 </div>
A internal/httpserve/handler/docker.go +31 -0
@@ -0,0 +1,31 @@
1+package handler
2+
3+import (
4+ "net/http"
5+
6+ "github.com/bnema/gordon/pkg/utils/docker"
7+ "github.com/bnema/gordon/pkg/utils/sanitize"
8+ "github.com/labstack/echo/v4"
9+)
10+
11+func ImageManagerHandler(c echo.Context) error {
12+ // Retrieve the list of container images.
13+ images, err := docker.ListContainerImages()
14+ if err != nil {
15+ rawErrHTML := `<div id="container-images">Error: ` + err.Error() + `</div>`
16+ sanitizedHTML, err := sanitize.SanitizeHTML(rawErrHTML)
17+ if err != nil {
18+ // Handle the sanitization error
19+ return c.String(http.StatusInternalServerError, "An error occurred during sanitization")
20+ }
21+ return c.HTML(http.StatusInternalServerError, sanitizedHTML)
22+ }
23+
24+ // Create a map to hold the data you want to pass to the template.
25+ data := map[string]interface{}{
26+ "Images": images,
27+ }
28+
29+ // Render the template with the data.
30+ return c.Render(http.StatusOK, "manager", data)
31+}
@@ -0,0 +1,31 @@
1+package handler
2+
3+import (
4+ "net/http"
5+
6+ "github.com/bnema/gordon/pkg/utils/docker"
7+ "github.com/bnema/gordon/pkg/utils/sanitize"
8+ "github.com/labstack/echo/v4"
9+)
10+
11+func ImageManagerHandler(c echo.Context) error {
12+ // Retrieve the list of container images.
13+ images, err := docker.ListContainerImages()
14+ if err != nil {
15+ rawErrHTML := `<div id="container-images">Error: ` + err.Error() + `</div>`
16+ sanitizedHTML, err := sanitize.SanitizeHTML(rawErrHTML)
17+ if err != nil {
18+ // Handle the sanitization error
19+ return c.String(http.StatusInternalServerError, "An error occurred during sanitization")
20+ }
21+ return c.HTML(http.StatusInternalServerError, sanitizedHTML)
22+ }
23+
24+ // Create a map to hold the data you want to pass to the template.
25+ data := map[string]interface{}{
26+ "Images": images,
27+ }
28+
29+ // Render the template with the data.
30+ return c.Render(http.StatusOK, "manager", data)
31+}
M internal/httpserve/router.go +1 -1
@@ -26,7 +26,7 @@ func RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {
2626 bindAdminRoute(e, a, AdminPath)
2727 bindStaticRoute(e, a, "/*")
2828 bindLoginRoute(e, a, AdminPath)
29-
29+ e.GET("/image-manager", handler.ImageManagerHandler)
3030 // Protect the root path with a 403
3131 e.GET("/", func(c echo.Context) error {
3232 return c.String(403, "403 Forbidden")
@@ -26,7 +26,7 @@ func RegisterRoutes(e *echo.Echo, a *app.App) *echo.Echo {
26 bindAdminRoute(e, a, AdminPath)26 bindAdminRoute(e, a, AdminPath)
27 bindStaticRoute(e, a, "/*")27 bindStaticRoute(e, a, "/*")
28 bindLoginRoute(e, a, AdminPath)28 bindLoginRoute(e, a, AdminPath)
29-29+ e.GET("/image-manager", handler.ImageManagerHandler)
30 // Protect the root path with a 40330 // Protect the root path with a 403
31 e.GET("/", func(c echo.Context) error {31 e.GET("/", func(c echo.Context) error {
32 return c.String(403, "403 Forbidden")32 return c.String(403, "403 Forbidden")
M internal/webui/public/assets/css/tailwind.css +20 -0
@@ -558,6 +558,10 @@ video {
558558 margin-right: 0.5rem;
559559 }
560560
561+.mt-20 {
562+ margin-top: 5rem;
563+}
564+
561565 .mt-4 {
562566 margin-top: 1rem;
563567 }
@@ -623,6 +627,10 @@ video {
623627 flex-grow: 1;
624628 }
625629
630+.transform {
631+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
632+}
633+
626634 .flex-row {
627635 flex-direction: row;
628636 }
@@ -818,6 +826,14 @@ video {
818826 outline-offset: 2px;
819827 }
820828
829+.transition {
830+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
831+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
832+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
833+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
834+ transition-duration: 150ms;
835+}
836+
821837 /* Import IBM Plex Fonts */
822838
823839 @font-face {
@@ -949,6 +965,10 @@ video {
949965 margin-left: 1rem;
950966 }
951967
968+ .md\:mt-24 {
969+ margin-top: 6rem;
970+ }
971+
952972 .md\:flex {
953973 display: flex;
954974 }
@@ -558,6 +558,10 @@ video {
558 margin-right: 0.5rem;558 margin-right: 0.5rem;
559 }559 }
560 560
561+.mt-20 {
562+ margin-top: 5rem;
563+}
564+
561 .mt-4 {565 .mt-4 {
562 margin-top: 1rem;566 margin-top: 1rem;
563 }567 }
@@ -623,6 +627,10 @@ video {
623 flex-grow: 1;627 flex-grow: 1;
624 }628 }
625 629
630+.transform {
631+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
632+}
633+
626 .flex-row {634 .flex-row {
627 flex-direction: row;635 flex-direction: row;
628 }636 }
@@ -818,6 +826,14 @@ video {
818 outline-offset: 2px;826 outline-offset: 2px;
819 }827 }
820 828
829+.transition {
830+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
831+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
832+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
833+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
834+ transition-duration: 150ms;
835+}
836+
821 /* Import IBM Plex Fonts */837 /* Import IBM Plex Fonts */
822 838
823 @font-face {839 @font-face {
@@ -949,6 +965,10 @@ video {
949 margin-left: 1rem;965 margin-left: 1rem;
950 }966 }
951 967
968+ .md\:mt-24 {
969+ margin-top: 6rem;
970+ }
971+
952 .md\:flex {972 .md\:flex {
953 display: flex;973 display: flex;
954 }974 }
A internal/webui/public/assets/js/custom.js +15 -0
@@ -0,0 +1,15 @@
1+document.body.addEventListener('htmx:afterRequest', function (evt) {
2+ const targetError = evt.target.attributes.getNamedItem('hx-target-error');
3+ if (evt.detail.failed && targetError) {
4+ const errorElement = document.getElementById(targetError.value);
5+ errorElement.innerHTML = evt.detail.xhr.responseText; // Set the response text as content
6+ errorElement.style.display = "inline";
7+ }
8+});
9+
10+document.body.addEventListener('htmx:beforeRequest', function (evt) {
11+ const targetError = evt.target.attributes.getNamedItem('hx-target-error');
12+ if (targetError) {
13+ document.getElementById(targetError.value).style.display = "none";
14+ }
15+});
@@ -0,0 +1,15 @@
1+document.body.addEventListener('htmx:afterRequest', function (evt) {
2+ const targetError = evt.target.attributes.getNamedItem('hx-target-error');
3+ if (evt.detail.failed && targetError) {
4+ const errorElement = document.getElementById(targetError.value);
5+ errorElement.innerHTML = evt.detail.xhr.responseText; // Set the response text as content
6+ errorElement.style.display = "inline";
7+ }
8+});
9+
10+document.body.addEventListener('htmx:beforeRequest', function (evt) {
11+ const targetError = evt.target.attributes.getNamedItem('hx-target-error');
12+ if (targetError) {
13+ document.getElementById(targetError.value).style.display = "none";
14+ }
15+});
M pkg/utils/docker/initclient.go +79 -16
@@ -1,9 +1,25 @@
11 package docker
22
33 import (
4- "log"
4+ "context"
5+ "fmt"
6+ "net"
7+ "net/http"
8+ "net/url"
9+ "time"
10+
11+ "github.com/docker/docker/api/types"
12+ "github.com/docker/docker/client"
513 )
614
15+type ContainerImage struct {
16+ ID string
17+ Repository string
18+ Tag string
19+ Created time.Time
20+ Size int64
21+}
22+
723 type ContainerEngineClient interface {
824 InitializeClient(*Config) error
925 // Add other methods that both Docker and Podman should implement
@@ -14,29 +30,76 @@ type Config struct {
1430 }
1531
1632 var engineClient ContainerEngineClient
33+var dockerCli *client.Client
1734
1835 // DockerClient implements the ContainerEngineClient interface for Docker
1936 type DockerClient struct{}
2037
2138 func (d *DockerClient) InitializeClient(config *Config) error {
22- // Initialize Docker client here
23- return nil // Return an error if something goes wrong
24-}
39+ // Create a custom HTTP client that uses the Docker socket
40+ httpClient := &http.Client{
41+ Transport: &http.Transport{
42+ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
43+ return net.Dial("unix", config.Sock)
44+ },
45+ },
46+ }
2547
26-// PodmanClient implements the ContainerEngineClient interface for Podman
27-type PodmanClient struct{}
48+ // Initialize Docker client
49+ cli, err := client.NewClientWithOpts(
50+ client.WithHTTPClient(httpClient),
51+ client.WithAPIVersionNegotiation(),
52+ client.WithScheme("unix"),
53+ client.WithHost(url.PathEscape(config.Sock)),
54+ )
55+ if err != nil {
56+ return err
57+ }
2858
29-func (p *PodmanClient) InitializeClient(config *Config) error {
30- // Initialize Podman client here
31- return nil // Return an error if something goes wrong
59+ dockerCli = cli
60+ return nil
3261 }
33-func InitializeEngineClient(config *Config) {
34- if config.PodmanEnable {
35- engineClient = &PodmanClient{}
36- } else {
37- engineClient = &DockerClient{}
62+
63+func ListContainerImages() ([]ContainerImage, error) {
64+ // Check if the Docker client has been initialized
65+ if dockerCli == nil {
66+ return nil, fmt.Errorf("Docker client has not been initialized")
3867 }
39- if err := engineClient.InitializeClient(config); err != nil {
40- log.Fatalf("Error initializing container engine client: %v", err)
68+
69+ // List images using the Docker client
70+ images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{})
71+ if err != nil {
72+ return nil, err
73+ }
74+
75+ // Populate the ContainerImage slice
76+ var containerImages []ContainerImage
77+ for _, image := range images {
78+ containerImages = append(containerImages, ContainerImage{
79+ ID: image.ID,
80+ // Repository and Tag information may require additional processing
81+ Created: time.Unix(image.Created, 0),
82+ Size: image.Size,
83+ })
4184 }
85+
86+ return containerImages, nil
4287 }
88+
89+// // PodmanClient implements the ContainerEngineClient interface for Podman
90+// type PodmanClient struct{}
91+
92+// func (p *PodmanClient) InitializeClient(config *Config) error {
93+// // Initialize Podman client here
94+// return nil // Return an error if something goes wrong
95+// }
96+// func InitializeEngineClient(config *Config) {
97+// if config.PodmanEnable {
98+// engineClient = &PodmanClient{}
99+// } else {
100+// engineClient = &DockerClient{}
101+// }
102+// if err := engineClient.InitializeClient(config); err != nil {
103+// log.Fatalf("Error initializing container engine client: %v", err)
104+// }
105+// }
@@ -1,9 +1,25 @@
1 package docker1 package docker
2 2
3 import (3 import (
4- "log"4+ "context"
5+ "fmt"
6+ "net"
7+ "net/http"
8+ "net/url"
9+ "time"
10+
11+ "github.com/docker/docker/api/types"
12+ "github.com/docker/docker/client"
5 )13 )
6 14
15+type ContainerImage struct {
16+ ID string
17+ Repository string
18+ Tag string
19+ Created time.Time
20+ Size int64
21+}
22+
7 type ContainerEngineClient interface {23 type ContainerEngineClient interface {
8 InitializeClient(*Config) error24 InitializeClient(*Config) error
9 // Add other methods that both Docker and Podman should implement25 // Add other methods that both Docker and Podman should implement
@@ -14,29 +30,76 @@ type Config struct {
14 }30 }
15 31
16 var engineClient ContainerEngineClient32 var engineClient ContainerEngineClient
33+var dockerCli *client.Client
17 34
18 // DockerClient implements the ContainerEngineClient interface for Docker35 // DockerClient implements the ContainerEngineClient interface for Docker
19 type DockerClient struct{}36 type DockerClient struct{}
20 37
21 func (d *DockerClient) InitializeClient(config *Config) error {38 func (d *DockerClient) InitializeClient(config *Config) error {
22- // Initialize Docker client here39+ // Create a custom HTTP client that uses the Docker socket
23- return nil // Return an error if something goes wrong40+ httpClient := &http.Client{
24-}41+ Transport: &http.Transport{
42+ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
43+ return net.Dial("unix", config.Sock)
44+ },
45+ },
46+ }
25 47
26-// PodmanClient implements the ContainerEngineClient interface for Podman48+ // Initialize Docker client
27-type PodmanClient struct{}49+ cli, err := client.NewClientWithOpts(
50+ client.WithHTTPClient(httpClient),
51+ client.WithAPIVersionNegotiation(),
52+ client.WithScheme("unix"),
53+ client.WithHost(url.PathEscape(config.Sock)),
54+ )
55+ if err != nil {
56+ return err
57+ }
28 58
29-func (p *PodmanClient) InitializeClient(config *Config) error {59+ dockerCli = cli
30- // Initialize Podman client here60+ return nil
31- return nil // Return an error if something goes wrong
32 }61 }
33-func InitializeEngineClient(config *Config) {62+
34- if config.PodmanEnable {63+func ListContainerImages() ([]ContainerImage, error) {
35- engineClient = &PodmanClient{}64+ // Check if the Docker client has been initialized
36- } else {65+ if dockerCli == nil {
37- engineClient = &DockerClient{}66+ return nil, fmt.Errorf("Docker client has not been initialized")
38 }67 }
39- if err := engineClient.InitializeClient(config); err != nil {68+
40- log.Fatalf("Error initializing container engine client: %v", err)69+ // List images using the Docker client
70+ images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{})
71+ if err != nil {
72+ return nil, err
73+ }
74+
75+ // Populate the ContainerImage slice
76+ var containerImages []ContainerImage
77+ for _, image := range images {
78+ containerImages = append(containerImages, ContainerImage{
79+ ID: image.ID,
80+ // Repository and Tag information may require additional processing
81+ Created: time.Unix(image.Created, 0),
82+ Size: image.Size,
83+ })
41 }84 }
85+
86+ return containerImages, nil
42 }87 }
88+
89+// // PodmanClient implements the ContainerEngineClient interface for Podman
90+// type PodmanClient struct{}
91+
92+// func (p *PodmanClient) InitializeClient(config *Config) error {
93+// // Initialize Podman client here
94+// return nil // Return an error if something goes wrong
95+// }
96+// func InitializeEngineClient(config *Config) {
97+// if config.PodmanEnable {
98+// engineClient = &PodmanClient{}
99+// } else {
100+// engineClient = &DockerClient{}
101+// }
102+// if err := engineClient.InitializeClient(config); err != nil {
103+// log.Fatalf("Error initializing container engine client: %v", err)
104+// }
105+// }
A pkg/utils/sanitize/htmlsanitizer.go +22 -0
@@ -0,0 +1,22 @@
1+package sanitize
2+
3+import (
4+ "errors"
5+
6+ "github.com/microcosm-cc/bluemonday"
7+)
8+
9+// SanitizeHTML takes a string containing raw HTML and returns a sanitized string.
10+func SanitizeHTML(rawHTML string) (string, error) {
11+ // Use bluemonday's UGCPolicy for user generated content
12+ p := bluemonday.UGCPolicy()
13+
14+ // Sanitize the raw HTML string
15+ sanitized := p.Sanitize(rawHTML)
16+
17+ if sanitized == "" && rawHTML != "" {
18+ return "", errors.New("Sanitization removed all content")
19+ }
20+
21+ return sanitized, nil
22+}
@@ -0,0 +1,22 @@
1+package sanitize
2+
3+import (
4+ "errors"
5+
6+ "github.com/microcosm-cc/bluemonday"
7+)
8+
9+// SanitizeHTML takes a string containing raw HTML and returns a sanitized string.
10+func SanitizeHTML(rawHTML string) (string, error) {
11+ // Use bluemonday's UGCPolicy for user generated content
12+ p := bluemonday.UGCPolicy()
13+
14+ // Sanitize the raw HTML string
15+ sanitized := p.Sanitize(rawHTML)
16+
17+ if sanitized == "" && rawHTML != "" {
18+ return "", errors.New("Sanitization removed all content")
19+ }
20+
21+ return sanitized, nil
22+}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close