[arch-commits] Commit in caddy/trunk (10 files)

Levente Polyak anthraxx at archlinux.org
Sat Feb 13 04:19:40 UTC 2021


    Date: Saturday, February 13, 2021 @ 04:19:40
  Author: anthraxx
Revision: 857818

move next version to current root dir

Added:
  caddy/trunk/caddy-api.service
  caddy/trunk/caddy.sysusers
  caddy/trunk/override-main-module-version.patch
  caddy/trunk/use-data-dir-for-autosave.patch
Modified:
  caddy/trunk/Caddyfile
  caddy/trunk/PKGBUILD
  caddy/trunk/caddy.service
  caddy/trunk/caddy.tmpfiles
Deleted:
  caddy/trunk/next/
  caddy/trunk/plugins.go

------------------------------------+
 Caddyfile                          |   42 +++++++-
 PKGBUILD                           |  171 +++++++++++------------------------
 caddy-api.service                  |   62 ++++++++++++
 caddy.service                      |   64 +++++++++----
 caddy.sysusers                     |    1 
 caddy.tmpfiles                     |    5 -
 override-main-module-version.patch |   28 +++++
 plugins.go                         |   61 ------------
 use-data-dir-for-autosave.patch    |   30 ++++++
 9 files changed, 264 insertions(+), 200 deletions(-)

Modified: Caddyfile
===================================================================
--- Caddyfile	2021-02-13 04:19:39 UTC (rev 857817)
+++ Caddyfile	2021-02-13 04:19:40 UTC (rev 857818)
@@ -1,6 +1,40 @@
-*:80 {
-	gzip
-	root /usr/share/caddy
+# The Caddyfile is an easy way to configure your Caddy web server.
+#
+# https://caddyserver.com/docs/caddyfile
+#
+# The configuration below serves a welcome page over HTTP on port 80.
+# To use your own domain name (with automatic HTTPS), first make
+# sure your domain's A/AAAA DNS records are properly pointed to
+# this machine's public IP, then replace the line below with your
+# domain name.
+#
+# https://caddyserver.com/docs/caddyfile/concepts#addresses
+
+{
+	# Restrict the admin interface to a local unix file socket whose directory
+	# is restricted to caddy:caddy. By default the TCP socket allows arbitrary
+	# modification for any process and user that has access to the local
+	# interface. If admin over TCP is turned on one should make sure
+	# implications are well understood.
+	admin "unix//run/caddy/admin.socket"
 }
 
-import conf.d/*.conf
+http:// {
+	# Set this path to your site's directory.
+	root * /usr/share/caddy
+
+	# Enable the static file server.
+	file_server
+
+	# Another common task is to set up a reverse proxy:
+	# reverse_proxy localhost:8080
+
+	# Or serve a PHP site through php-fpm:
+	# php_fastcgi localhost:9000
+
+	# Refer to the directive documentation for more options.
+	# https://caddyserver.com/docs/caddyfile/directives
+}
+
+# Import additional caddy config files in /etc/caddy/conf.d/
+import /etc/caddy/conf.d/*

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2021-02-13 04:19:39 UTC (rev 857817)
+++ PKGBUILD	2021-02-13 04:19:40 UTC (rev 857818)
@@ -1,4 +1,5 @@
 # Maintainer: Levente Polyak <anthraxx[at]archlinux[dot]org>
+# Maintainer: Christian Rebischke <chris.rebischke at archlinux.org>
 # Contributor: Wei Congrui < crvv.mail at gmail dot com >
 # Contributor: Carl George < arch at cgtx dot us >
 # Contributor: Eric Engeström <eric at engestrom dot ch>
@@ -6,29 +7,35 @@
 # Contributor: Akshay S Dinesh <asdofindia at gmail dot com>
 
 pkgname=caddy
-pkgver=1.0.5
-_gitcommit=11ae1aa6b88e45b077dd97cb816fe06cd91cca67
-_distcommit=9e93bfd85c97d71ab842a4a4b555d358295c914e
-pkgrel=2
-pkgdesc='HTTP/2 Web Server with Automatic HTTPS'
+pkgver=2.3.0
+_gitcommit=b4989773ebb2dff21283ee50ec667f9138bdd292
+_distcommit=e784a6dd41d1cd4f72de2a427961bfb097b72cf9
+pkgrel=1
+pkgdesc='Fast web server with automatic HTTPS'
 url='https://caddyserver.com'
 arch=('x86_64')
 license=('Apache')
 depends=('glibc')
 makedepends=('go' 'git')
-backup=('etc/caddy/caddy.conf')
-source=("git+https://github.com/caddyserver/caddy#commit=${_gitcommit}?signed"
-        caddy-${_distcommit}-index.html::https://raw.githubusercontent.com/caddyserver/dist/${_distcommit}/welcome/index.html
+backup=('etc/caddy/Caddyfile')
+source=("git+https://github.com/caddyserver/caddy#tag=${_gitcommit}?signed"
+        caddy-dist::"git+https://github.com/caddyserver/dist#commit=${_distcommit}"
         caddy.service
+        caddy-api.service
         caddy.tmpfiles
+        caddy.sysusers
         Caddyfile
-        plugins.go)
-sha256sums=('SKIP'
-            '7668022a48b0cbf459190f0bbfbfb32ae066449a95e006367cac9e1befa80c5f'
-            'c14ac8681e0434caf2c68e4a18dc59f8796fdffe9039f2e3c799ca64d37aa1ea'
-            'c8f002f5ba59985a643600dc3c871e18e110903aa945ef3f2da7c9edd39fbd7a'
-            'fb998b6de7bfe58f65c62eab37a4885e70833d19902da089766ad627a5f5a305'
-            '69956ee6a54ee0469fdee77f6d07cccee61699b1ee24e2f94ef6017c7ec1118b')
+        use-data-dir-for-autosave.patch
+        override-main-module-version.patch)
+sha512sums=('SKIP'
+            'SKIP'
+            'd162f16e16be1673f11c384b79505b82fedbecacea77c2e64303b573aa982ace5706fb74eb7d0b219c5935427459537b685832357aed5ee48345648f439bf274'
+            'a4d9bbcccf3c6fe9be2b7ba98214d579ecd40991c5cc520ca1d105f307b31622f1c6b5a6cd7a4e8b32ccd2a229ed70115cba9c507baa413803897b7183f9abe0'
+            '55ee8d3f8b14f9adddc7a1026addcea4f85b4bae4cd512fd4da2a5e8adaae4b6fd0f486d2e3847f75518f4710a897b4fca84e48ee15700b968bad762125c4742'
+            'c893d88fec89e37da6596030c8dce7103e7e575371e8542a24d2a0741e877358d85219f2d8ade9d6aa0f515efe1156a4badd9fef5f65f553a5b0c72330c4728f'
+            '716da3f4edeb3561243aeaf5c32b01ff7a4ac810b6deba8364fb12a1f71b6a5278c34a97b289bcfdc48784679b942bf780f1f36d416a575791168c94b0d59fe0'
+            '563d6b45e91fc584fb5a27caaa382f59c140cb0a1b28b8d8faced4f7c7cad86d8671eb6ac10056f41518a842c8f606130d7e0c71df2b731d5eb0b4c868ea5d41'
+            'b06369dd976cfcc9b519782c088efa5fba25db61663112fcc4e20b108d5165cbebcf63b6fe6d1e36119a55271374bac0037a4d07af412241d6a4d2b4f4efda0b')
 validpgpkeys=(
   29D0817A67156E4F25DC24782A349DD577D586A5 # Matthew Holt <mholt at users.noreply.github.com>
 )
@@ -39,116 +46,52 @@
 }
 
 prepare() {
-    cd ${pkgname}/caddy
-    sed 's|/var/www/html|/srv/http|g' -i "${srcdir}/caddy-${_distcommit}-index.html"
-    sed 's|Version: "unknown"|Version: "v'${pkgver}'"|' -i caddymain/run.go
-
-    cat > main.go <<EOF
-package main
-
-import (
-  "github.com/caddyserver/caddy/caddy/caddymain"
-EOF
-    if [ ${#_plugins[@]} -gt 0 ]; then
-        echo "enabled plugins: ${_plugins[*]}"
-        go run "${srcdir}/plugins.go" "${_plugins[@]}" >> main.go
-    fi
-    cat >> main.go <<EOF
-)
-
-func main() {
-  caddymain.EnableTelemetry = false
-  caddymain.Run()
+  cd "${pkgname}"
+  # welcome page
+  cp ../caddy-dist/welcome/index.html .
+  sed 's|/var/www/html|/srv/http|g' -i index.html
+  # do not write in /etc
+  patch -Np1 < "${srcdir}/use-data-dir-for-autosave.patch"
+  # fix version identifier if not built from a module
+  patch -Np1 < "${srcdir}/override-main-module-version.patch"
+  sed 's|"unknown"|"v'"${pkgver}"'"|g' -i caddy.go
 }
-EOF
-}
 
 build() {
-  cd ${pkgname}/caddy
+  cd "${pkgname}/cmd/caddy/"
+  export CGO_LDFLAGS="${LDFLAGS}"
   export CGO_CPPFLAGS="${CPPFLAGS}"
   export CGO_CFLAGS="${CFLAGS}"
   export CGO_CXXFLAGS="${CXXFLAGS}"
-  export CGO_LDFLAGS="${LDFLAGS}"
-  export GOFLAGS="-buildmode=pie -trimpath -modcacherw"
-  go build -v .
+  export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
+  go build .
 }
 
+check() {
+  cd "${pkgname}"
+  go test ./...
+  version=$(./cmd/caddy/caddy version)
+  echo "Caddy version: ${version}"
+  if [[ $version != v$pkgver ]]; then
+    exit 1
+  fi
+}
+
 package() {
-  cd ${pkgname}/caddy
-  install -Dm 755 caddy -t "${pkgdir}/usr/bin"
-  install -Dm 644 "${srcdir}/caddy.service" -t "${pkgdir}/usr/lib/systemd/system"
+  cd "${pkgname}"
+  install -Dm 755 cmd/caddy/caddy -t "${pkgdir}/usr/bin"
+
+  install -Dm 644 "${srcdir}/caddy.service" "${srcdir}/caddy-api.service" -t "${pkgdir}/usr/lib/systemd/system"
   install -Dm 644 "${srcdir}/caddy.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/caddy.conf"
-  install -Dm 644 "${srcdir}/Caddyfile" "${pkgdir}/etc/caddy/caddy.conf"
-  install -Dm 644 "${srcdir}/caddy-${_distcommit}-index.html" "${pkgdir}/usr/share/caddy/index.html"
+  install -Dm 644 "${srcdir}/caddy.sysusers" "${pkgdir}/usr/lib/sysusers.d/caddy.conf"
+
+  install -Dm 644 "${srcdir}/Caddyfile" -t "${pkgdir}/etc/caddy"
   install -d "${pkgdir}/etc/caddy/conf.d"
+
+  install -Dm 644 index.html "${pkgdir}/usr/share/caddy/index.html"
+
+  install -Dm 644 "${srcdir}/caddy-dist/scripts/completions/_caddy" -t "${pkgdir}/usr/share/zsh/site-functions"
+  install -Dm 644 "${srcdir}/caddy-dist/scripts/completions/bash-completion" "${pkgdir}/usr/share/bash-completion/completions/caddy"
 }
 
-# carefully check before enabling any plugin, they are basically untrusted code
-# the enabled tls.dns plugins are built by mholt and maintained in the same space
-_plugins=(
-#    'dns'
-#    'docker'
-#    'dyndns'
-#    'hook.service'
-#    'http.authz'
-#    'http.awses'
-#    'http.awslambda'
-#    'http.cache'
-#    'http.cgi'
-#    'http.cors'
-#    'http.datadog'
-#    'http.expires'
-#    'http.filter'
-#    'http.forwardproxy'
-#    'http.geoip'
-#    'http.git'
-#    'http.gopkg'
-#    'http.grpc'
-#    'http.ipfilter'
-#    'http.jwt'
-#    'http.locale'
-#    'http.login'
-#    'http.mailout'
-#    'http.minify'
-#    'http.nobots'
-#    'http.prometheus'
-#    'http.proxyprotocol'
-#    'http.ratelimit'
-#    'http.realip'
-#    'http.reauth'
-#    'http.restic'
-#    'http.s3browser'
-#    'http.supervisor'
-#    'http.webdav'
-#    'net'
-#    'supervisor'
-    'tls.dns.auroradns'
-    'tls.dns.azure'
-    'tls.dns.cloudflare'
-    'tls.dns.cloudxns'
-    'tls.dns.digitalocean'
-    'tls.dns.dnsimple'
-    'tls.dns.dnsmadeeasy'
-    'tls.dns.dnspod'
-    'tls.dns.duckdns'
-    'tls.dns.dyn'
-    'tls.dns.exoscale'
-    'tls.dns.gandi'
-    'tls.dns.gandiv5'
-    'tls.dns.godaddy'
-    'tls.dns.googlecloud'
-    'tls.dns.lightsail'
-    'tls.dns.linode'
-    'tls.dns.namecheap'
-    'tls.dns.namedotcom'
-    'tls.dns.ns1'
-    'tls.dns.otc'
-    'tls.dns.ovh'
-    'tls.dns.powerdns'
-    'tls.dns.rackspace'
-    'tls.dns.rfc2136'
-    'tls.dns.route53'
-    'tls.dns.vultr'
-)
-
 # vim: ts=2 sw=2 et:

Added: caddy-api.service
===================================================================
--- caddy-api.service	                        (rev 0)
+++ caddy-api.service	2021-02-13 04:19:40 UTC (rev 857818)
@@ -0,0 +1,62 @@
+# caddy-api.service
+#
+# For using Caddy with its API.
+#
+# This unit is "durable" in that it will automatically resume
+# the last active configuration if the service is restarted.
+#
+# See https://caddyserver.com/docs/install for instructions.
+
+[Unit]
+Description=Caddy API Server
+Documentation=https://caddyserver.com/docs/
+After=network-online.target
+Wants=network-online.target systemd-networkd-wait-online.service
+StartLimitIntervalSec=14400
+StartLimitBurst=10
+
+[Service]
+User=caddy
+Group=caddy
+Environment=XDG_DATA_HOME=/var/lib
+Environment=XDG_CONFIG_HOME=/var/lib
+ExecStart=/usr/bin/caddy run --environ --resume
+
+# Do not allow the process to be restarted in a tight loop. If the
+# process fails to start, something critical needs to be fixed.
+Restart=on-abnormal
+
+# Use graceful shutdown with a reasonable timeout
+TimeoutStopSec=5s
+
+LimitNOFILE=1048576
+LimitNPROC=512
+
+# Hardening options
+AmbientCapabilities=CAP_NET_BIND_SERVICE
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE
+DevicePolicy=closed
+LockPersonality=true
+MemoryAccounting=true
+MemoryDenyWriteExecute=true
+NoNewPrivileges=true
+PrivateDevices=true
+PrivateTmp=true
+ProcSubset=pid
+ProtectClock=true
+ProtectControlGroups=true
+ProtectHome=true
+ProtectHostname=true
+ProtectKernelLogs=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectProc=invisible
+ProtectSystem=strict
+RemoveIPC=true
+ReadWritePaths=/var/lib/caddy /var/log/caddy /run/caddy
+RestrictNamespaces=true
+RestrictRealtime=true
+RestrictSUIDSGID=true
+
+[Install]
+WantedBy=multi-user.target

Modified: caddy.service
===================================================================
--- caddy.service	2021-02-13 04:19:39 UTC (rev 857817)
+++ caddy.service	2021-02-13 04:19:40 UTC (rev 857818)
@@ -1,6 +1,21 @@
+# caddy.service
+#
+# For using Caddy with a config file.
+#
+# Make sure the ExecStart and ExecReload commands are correct
+# for your installation.
+#
+# See https://caddyserver.com/docs/install for instructions.
+#
+# WARNING: This service does not use the --resume flag, so if you
+# use the API to make changes, they will be overwritten by the
+# Caddyfile next time the service is restarted. If you intend to
+# use Caddy's API to configure it, add the --resume flag to the
+# `caddy run` command or use the caddy-api.service file instead.
+
 [Unit]
-Description=Caddy HTTP/2 web server
-Documentation=https://caddyserver.com/docs
+Description=Caddy web server
+Documentation=https://caddyserver.com/docs/
 After=network-online.target
 Wants=network-online.target systemd-networkd-wait-online.service
 StartLimitIntervalSec=14400
@@ -7,12 +22,13 @@
 StartLimitBurst=10
 
 [Service]
-User=http
-Group=http
-Environment=CADDYPATH=/var/lib/caddy
-EnvironmentFile=-/etc/caddy/envfile
-ExecStart=/usr/bin/caddy -log stdout -agree -conf /etc/caddy/caddy.conf -root=/usr/share/caddy
-ExecReload=/usr/bin/kill -USR1 $MAINPID
+User=caddy
+Group=caddy
+Environment=XDG_DATA_HOME=/var/lib
+Environment=XDG_CONFIG_HOME=/etc
+ExecStartPre=/usr/bin/caddy validate --config /etc/caddy/Caddyfile
+ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
+ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
 
 # Do not allow the process to be restarted in a tight loop. If the
 # process fails to start, something critical needs to be fixed.
@@ -19,8 +35,6 @@
 Restart=on-abnormal
 
 # Use graceful shutdown with a reasonable timeout
-KillMode=mixed
-KillSignal=SIGQUIT
 TimeoutStopSec=5s
 
 LimitNOFILE=1048576
@@ -27,18 +41,30 @@
 LimitNPROC=512
 
 # Hardening options
+AmbientCapabilities=CAP_NET_BIND_SERVICE
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE
+DevicePolicy=closed
+LockPersonality=true
+MemoryAccounting=true
+MemoryDenyWriteExecute=true
+NoNewPrivileges=true
+PrivateDevices=true
 PrivateTmp=true
-PrivateDevices=true
+ProcSubset=pid
+ProtectClock=true
+ProtectControlGroups=true
 ProtectHome=true
+ProtectHostname=true
+ProtectKernelLogs=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectProc=invisible
 ProtectSystem=strict
-ReadWritePaths=/var/lib/caddy /var/log/caddy
-CapabilityBoundingSet=CAP_NET_BIND_SERVICE
-AmbientCapabilities=CAP_NET_BIND_SERVICE
-NoNewPrivileges=true
-ProtectKernelTunables=true
-ProtectKernelModules=true
-ProtectControlGroups=true
-LockPersonality=true
+RemoveIPC=true
+ReadWritePaths=/var/lib/caddy /var/log/caddy /run/caddy
+RestrictNamespaces=true
+RestrictRealtime=true
+RestrictSUIDSGID=true
 
 [Install]
 WantedBy=multi-user.target

Added: caddy.sysusers
===================================================================
--- caddy.sysusers	                        (rev 0)
+++ caddy.sysusers	2021-02-13 04:19:40 UTC (rev 857818)
@@ -0,0 +1 @@
+u caddy - "caddy daemon" /var/lib/caddy

Modified: caddy.tmpfiles
===================================================================
--- caddy.tmpfiles	2021-02-13 04:19:39 UTC (rev 857817)
+++ caddy.tmpfiles	2021-02-13 04:19:40 UTC (rev 857818)
@@ -1,2 +1,3 @@
-d /var/lib/caddy 0750 http http
-d /var/log/caddy 0750 http http
+d /var/lib/caddy 0750 caddy caddy
+d /var/log/caddy 0750 caddy caddy
+d /run/caddy 0750 caddy caddy

Added: override-main-module-version.patch
===================================================================
--- override-main-module-version.patch	                        (rev 0)
+++ override-main-module-version.patch	2021-02-13 04:19:40 UTC (rev 857818)
@@ -0,0 +1,28 @@
+From 56eacff9fa3a84b19ac9b8bb7072d9b7d96755e7 Mon Sep 17 00:00:00 2001
+From: anthraxx <levente at leventepolyak.net>
+Date: Sat, 13 Feb 2021 04:56:30 +0100
+Subject: [PATCH] override main module version which we can be filled with the
+ correct version
+
+Go BuildInfo only works if we build from a module, however we simply
+want to build in tree. Therefor override the main module version with
+something that we can dynamically replace.
+---
+ caddy.go | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/caddy.go b/caddy.go
+index 70135ffb..04d95716 100644
+--- a/caddy.go
++++ b/caddy.go
+@@ -679,6 +679,7 @@ func goModule(mod *debug.Module) *debug.Module {
+ 	mod.Version = "unknown"
+ 	bi, ok := debug.ReadBuildInfo()
+ 	if ok {
++		bi.Main.Version = "unknown"
+ 		mod.Path = bi.Main.Path
+ 		// The recommended way to build Caddy involves
+ 		// creating a separate main module, which
+-- 
+2.30.0
+

Deleted: plugins.go
===================================================================
--- plugins.go	2021-02-13 04:19:39 UTC (rev 857817)
+++ plugins.go	2021-02-13 04:19:40 UTC (rev 857818)
@@ -1,61 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	"sort"
-)
-
-const URL = "https://caddyserver.com/v1/api/download-page"
-
-type Plugin struct {
-	Name       string
-	ImportPath string
-}
-type PluginList struct {
-	Plugins []Plugin `json:"plugins"`
-}
-
-func getPlugins() []Plugin {
-	resp, err := http.Get(URL)
-	if err != nil {
-		log.Fatal(err)
-	}
-	defer resp.Body.Close()
-	body, err := ioutil.ReadAll(resp.Body)
-	list := PluginList{}
-	err = json.Unmarshal(body, &list)
-	if err != nil {
-		log.Fatal(err)
-	}
-	return list.Plugins
-}
-func main() {
-	plugins := getPlugins()
-	sort.Slice(plugins, func(i, j int) bool {
-		return plugins[i].Name < plugins[j].Name
-	})
-	if len(os.Args) == 1 {
-		fmt.Println("plugins=(")
-		for _, plugin := range plugins {
-			fmt.Printf("#    '%s'\n", plugin.Name)
-		}
-		fmt.Println(")")
-		return
-	}
-	pluginsMap := make(map[string]string)
-	for _, plugin := range plugins {
-		pluginsMap[plugin.Name] = plugin.ImportPath
-	}
-	for _, name := range os.Args[1:] {
-		path, ok := pluginsMap[name]
-		if !ok {
-			log.Fatalf("cannot find plugin %s\n", name)
-		}
-		fmt.Printf(`_ "%s"`+"\n", path)
-	}
-}

Added: use-data-dir-for-autosave.patch
===================================================================
--- use-data-dir-for-autosave.patch	                        (rev 0)
+++ use-data-dir-for-autosave.patch	2021-02-13 04:19:40 UTC (rev 857818)
@@ -0,0 +1,30 @@
+From e3a60a8058d2c75c9bc47f550351d0008aefb314 Mon Sep 17 00:00:00 2001
+From: anthraxx <levente at leventepolyak.net>
+Date: Fri, 12 Feb 2021 19:23:50 +0100
+Subject: [PATCH] storage: use data dir for autosave.json as /etc is write
+ protected
+
+This is more a state file instead of a custom file as caddy also
+persists this. We do not want to have any files in /etc being mapped
+writable, not even the /etc/caddy directory, hence move the persisted
+autosave.json state to the actual application data directory.
+---
+ storage.go | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/storage.go b/storage.go
+index 62f9b1c6..5babea79 100644
+--- a/storage.go
++++ b/storage.go
+@@ -154,7 +154,7 @@ func AppDataDir() string {
+ }
+ 
+ // ConfigAutosavePath is the default path to which the last config will be persisted.
+-var ConfigAutosavePath = filepath.Join(AppConfigDir(), "autosave.json")
++var ConfigAutosavePath = filepath.Join(AppDataDir(), "autosave.json")
+ 
+ // DefaultStorage is Caddy's default storage module.
+ var DefaultStorage = &certmagic.FileStorage{Path: AppDataDir()}
+-- 
+2.30.0
+



More information about the arch-commits mailing list