mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-16 12:08:04 +00:00
aptly serve command: handle publishing of repositories, with system test.
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gonuts/commander"
|
||||||
|
"github.com/gonuts/flag"
|
||||||
|
"github.com/smira/aptly/debian"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func aptlyServe(cmd *commander.Command, args []string) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
publishedCollection := debian.NewPublishedRepoCollection(context.database)
|
||||||
|
snapshotCollection := debian.NewSnapshotCollection(context.database)
|
||||||
|
|
||||||
|
if publishedCollection.Len() == 0 {
|
||||||
|
fmt.Printf("No published repositories, unable to serve.\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
listen := cmd.Flag.Lookup("listen").Value.String()
|
||||||
|
|
||||||
|
listenHost, listenPort, err := net.SplitHostPort(listen)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("wrong -listen specification: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if listenHost == "" {
|
||||||
|
listenHost, err = os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
listenHost = "localhost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Serving published repositories, recommended apt sources list:\n\n")
|
||||||
|
|
||||||
|
sources := make(sort.StringSlice, 0, publishedCollection.Len())
|
||||||
|
published := make(map[string]*debian.PublishedRepo, publishedCollection.Len())
|
||||||
|
|
||||||
|
err = publishedCollection.ForEach(func(repo *debian.PublishedRepo) error {
|
||||||
|
err := publishedCollection.LoadComplete(repo, snapshotCollection)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sources = append(sources, repo.String())
|
||||||
|
published[repo.String()] = repo
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to serve: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(sources)
|
||||||
|
|
||||||
|
for _, source := range sources {
|
||||||
|
repo := published[source]
|
||||||
|
|
||||||
|
prefix := repo.Prefix
|
||||||
|
if prefix == "." {
|
||||||
|
prefix = ""
|
||||||
|
} else {
|
||||||
|
prefix += "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("# %s\ndeb http://%s:%s/%s %s %s\n",
|
||||||
|
repo, listenHost, listenPort, prefix, repo.Distribution, repo.Component)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.database.Close()
|
||||||
|
|
||||||
|
fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen)
|
||||||
|
|
||||||
|
err = http.ListenAndServe(listen, http.FileServer(http.Dir(context.packageRepository.PublicPath())))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to serve: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCmdServe() *commander.Command {
|
||||||
|
cmd := &commander.Command{
|
||||||
|
Run: aptlyServe,
|
||||||
|
UsageLine: "serve",
|
||||||
|
Short: "start embedded HTTP server to serve published repositories",
|
||||||
|
Long: `
|
||||||
|
Command serve starts embedded HTTP server (not suitable for real production usage) to serve
|
||||||
|
contents of public/ subdirectory of aptly's root that contains published repositories.
|
||||||
|
|
||||||
|
ex:
|
||||||
|
$ aptly serve -listen=:8080
|
||||||
|
`,
|
||||||
|
Flag: *flag.NewFlagSet("aptly-serve", flag.ExitOnError),
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flag.String("listen", ":8080", "host:port for HTTP listening")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ take snapshots and publish them back as Debian repositories.`,
|
|||||||
makeCmdMirror(),
|
makeCmdMirror(),
|
||||||
makeCmdSnapshot(),
|
makeCmdSnapshot(),
|
||||||
makeCmdPublish(),
|
makeCmdPublish(),
|
||||||
|
makeCmdServe(),
|
||||||
makeCmdVersion(),
|
makeCmdVersion(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Serving published repositories, recommended apt sources list:
|
||||||
|
|
||||||
|
# ./maverick (main) [amd64, i386] publishes [snap1]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
|
||||||
|
deb http://127.0.0.1:8765/ maverick main
|
||||||
|
# debian/maverick (main) [amd64, i386] publishes [snap2]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick
|
||||||
|
deb http://127.0.0.1:8765/debian/ maverick main
|
||||||
|
|
||||||
|
Starting web server at: 127.0.0.1:8765 (press Ctrl+C to quit)...
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<pre>
|
||||||
|
<a href="debian/">debian/</a>
|
||||||
|
<a href="dists/">dists/</a>
|
||||||
|
<a href="pool/">pool/</a>
|
||||||
|
</pre>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
No published repositories, unable to serve.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
"""
|
||||||
|
Testing serving public repo
|
||||||
|
"""
|
||||||
|
|
||||||
|
import httplib
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import shlex
|
||||||
|
import time
|
||||||
|
|
||||||
|
from lib import BaseTest
|
||||||
|
|
||||||
|
|
||||||
|
class VerifySnapshot1Test(BaseTest):
|
||||||
|
"""
|
||||||
|
serve public: two publishes, verify HTTP
|
||||||
|
"""
|
||||||
|
fixtureDB = True
|
||||||
|
fixturePool = True
|
||||||
|
fixtureCmds = [
|
||||||
|
"aptly snapshot create snap1 from mirror gnuplot-maverick",
|
||||||
|
"aptly snapshot create snap2 from mirror gnuplot-maverick",
|
||||||
|
"aptly publish snapshot snap1",
|
||||||
|
"aptly publish snapshot snap2 debian",
|
||||||
|
]
|
||||||
|
runCmd = "aptly serve -listen=127.0.0.1:8765"
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(shlex.split(self.runCmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
conn = httplib.HTTPConnection("127.0.0.1", 8765)
|
||||||
|
conn.request("GET", "/")
|
||||||
|
r = conn.getresponse()
|
||||||
|
if r.status != 200:
|
||||||
|
raise Exception("Expected status 200 != %d" % r.status)
|
||||||
|
self.http_response = r.read()
|
||||||
|
|
||||||
|
output = os.read(proc.stdout.fileno(), 8192)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
proc.send_signal(signal.SIGINT)
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
if proc.returncode != 2:
|
||||||
|
raise Exception("exit code %d != %d (output: %s)" % (proc.returncode, 2, output))
|
||||||
|
self.output = output
|
||||||
|
except Exception, e:
|
||||||
|
raise Exception("Running command %s failed: %s" % (self.runCmd, str(e)))
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
self.check_output()
|
||||||
|
self.verify_match(self.get_gold('http'), self.http_response)
|
||||||
|
|
||||||
|
|
||||||
|
class VerifySnapshot2Test(BaseTest):
|
||||||
|
"""
|
||||||
|
serve public: no publishes
|
||||||
|
"""
|
||||||
|
runCmd = "aptly serve -listen=127.0.0.1:8765"
|
||||||
Reference in New Issue
Block a user