aptly serve command: handle publishing of repositories, with system test.

This commit is contained in:
Andrey Smirnov
2014-01-30 13:10:19 +04:00
parent 0271456ca4
commit 043ed13c18
6 changed files with 185 additions and 0 deletions
+106
View File
@@ -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
}
+1
View File
@@ -30,6 +30,7 @@ take snapshots and publish them back as Debian repositories.`,
makeCmdMirror(),
makeCmdSnapshot(),
makeCmdPublish(),
makeCmdServe(),
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.
+64
View File
@@ -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"