mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-01 04:40:38 +00:00
Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a6541aac41 | |||
| 7fd8bd0171 | |||
| 4707efe4d6 | |||
| 8ae61f9448 | |||
| a138d0111d | |||
| af1adb44ce | |||
| 2943422d5d | |||
| 91219e3a0a | |||
| 7f8db9087a | |||
| 92c844b8ac | |||
| 2b56a3937b | |||
| 9cea9b6470 | |||
| e3e68b9f22 | |||
| d56839664d | |||
| 516dd7b044 | |||
| 53e59d3765 | |||
| 11d828b3b1 | |||
| 07472bec50 | |||
| f737787c01 | |||
| c6c1012330 | |||
| 070347295e | |||
| acd8d4a6ea | |||
| c9768416ed | |||
| bfb9ffad1d | |||
| 9cfe1307e3 | |||
| db8595711b | |||
| ce0001f94c | |||
| b102562478 | |||
| 69cbe10690 | |||
| e3e4ea91bd | |||
| 02c582e227 | |||
| 6e96cd29dc | |||
| 17044f43dc | |||
| 5d3b170ffc | |||
| a0f7b2242d | |||
| b8e7ad9022 | |||
| 1b80d55ea4 | |||
| a0832adfa5 | |||
| f17d398e8f | |||
| bc3b2ed5a8 | |||
| 07cf8925f9 | |||
| 564ebf3130 | |||
| dbee214259 | |||
| 6267c5cb25 | |||
| 4c06e26d85 | |||
| f2dc4eeec9 | |||
| f86e6ebf1f | |||
| 0d208c93bc | |||
| 485f311498 | |||
| 46b0d637e2 | |||
| 5a71847b7f | |||
| 38a9917815 | |||
| 4456f8da57 | |||
| 970b1a424a | |||
| edffa24658 | |||
| 3040e7360a | |||
| b948180b4e | |||
| f58d2627c1 | |||
| ab0d77f6f9 | |||
| 33d6cd8c0a | |||
| 4eef4f1803 | |||
| c75d4c749c | |||
| c8a1b9a1f0 | |||
| d8d8973ad5 | |||
| d1ded5c224 | |||
| 155a801bc1 | |||
| 6212b39264 | |||
| 92116072c2 | |||
| b0ab39e07f | |||
| 4bf27d1dae | |||
| 207ebffbb8 | |||
| b0dd83335f | |||
| 8df6457931 | |||
| 7d2a396b27 | |||
| d5df049630 | |||
| 7c62a706c4 | |||
| 96948d6f18 | |||
| 43e6498713 | |||
| 91561b40f6 | |||
| 0e8ea6363a | |||
| 345fa02fdc | |||
| 064adbae57 | |||
| ab458f4dfc | |||
| 0fdee9cbf6 | |||
| 50e3e93166 | |||
| 570835227b | |||
| 781c22e256 | |||
| babccfa21f | |||
| 891113717e | |||
| bfb9045fa9 | |||
| 1c6b174b8a | |||
| fb27fb01ea | |||
| b6327ecc43 | |||
| af71b9541c | |||
| f31b5ec3f8 | |||
| 6becd5a3aa | |||
| 653255c728 | |||
| 5f0ce38161 | |||
| d100033b46 | |||
| d008cabf07 | |||
| f3214144a4 | |||
| d41841b84a | |||
| 2a95e0eb1b | |||
| 81f8ab2691 | |||
| 4e61db8d0f | |||
| 273d4cfa1b | |||
| d290950d4f | |||
| 2ade5b8a7f | |||
| fcd4429370 | |||
| 8e62620880 | |||
| 511fb439ac | |||
| 34ea7e8d61 | |||
| 543c986885 | |||
| f939532461 | |||
| aa4e225455 | |||
| 65541a1df2 | |||
| 0a74b50a12 | |||
| 902c6487da | |||
| 1d5b7f59cf | |||
| 1c45c79cc1 | |||
| 85c5aeddae | |||
| a95e409f52 | |||
| 53b571d6fc | |||
| 7a8af044ee | |||
| a667744502 | |||
| aa53b8da15 |
@@ -0,0 +1,14 @@
|
|||||||
|
<!--- Provide a general summary of the issue in the Title above -->
|
||||||
|
|
||||||
|
## Detailed Description
|
||||||
|
<!--- Provide a detailed description of the change or addition you are proposing -->
|
||||||
|
|
||||||
|
## Context
|
||||||
|
<!--- Why is this change important to you? How would you use it? -->
|
||||||
|
<!--- How can it benefit other users? -->
|
||||||
|
|
||||||
|
## Possible Implementation
|
||||||
|
<!--- Not obligatory, but suggest an idea for implementing addition or change -->
|
||||||
|
|
||||||
|
## Your Environment
|
||||||
|
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
Fixes #
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
All new code should be covered with tests, documentation should be updated. CI should pass.
|
||||||
|
|
||||||
|
## Description of the Change
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Why this change is important?
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] unit-test added (if change is algorithm)
|
||||||
|
- [ ] functional test added/updated (if change is functional)
|
||||||
|
- [ ] man page updated (if applicable)
|
||||||
|
- [ ] bash completion updated (if applicable)
|
||||||
|
- [ ] documentation updated
|
||||||
|
- [ ] author name in `AUTHORS`
|
||||||
+4
-2
@@ -27,8 +27,10 @@ coverage*.out
|
|||||||
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
_vendor/
|
xc-out/
|
||||||
|
root/
|
||||||
|
|
||||||
gen
|
|
||||||
man/aptly.1.html
|
man/aptly.1.html
|
||||||
man/aptly.1.ronn
|
man/aptly.1.ronn
|
||||||
|
|
||||||
|
.goxc.local.json
|
||||||
|
|||||||
+11
-3
@@ -2,10 +2,12 @@
|
|||||||
"AppName": "aptly",
|
"AppName": "aptly",
|
||||||
"ArtifactsDest": "xc-out/",
|
"ArtifactsDest": "xc-out/",
|
||||||
"TasksExclude": [
|
"TasksExclude": [
|
||||||
"rmbin"
|
"rmbin",
|
||||||
|
"go-test",
|
||||||
|
"go-vet"
|
||||||
],
|
],
|
||||||
"TasksAppend": [
|
"TasksAppend": [
|
||||||
"bintray"
|
"bintray"
|
||||||
],
|
],
|
||||||
"TaskSettings": {
|
"TaskSettings": {
|
||||||
"deb": {
|
"deb": {
|
||||||
@@ -31,8 +33,14 @@
|
|||||||
"downloadspage": "bintray.md"
|
"downloadspage": "bintray.md"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ResourcesInclude": "README.rst,LICENSE,AUTHORS,man/aptly.1",
|
||||||
"Arch": "386 amd64",
|
"Arch": "386 amd64",
|
||||||
"Os": "linux darwin freebsd",
|
"Os": "linux darwin freebsd",
|
||||||
"MainDirsExclude": "man,_vendor",
|
"MainDirsExclude": "_man,vendor",
|
||||||
|
"BuildSettings": {
|
||||||
|
"LdFlagsXVars": {
|
||||||
|
"Version": "main.Version"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ConfigVersion": "0.9"
|
"ConfigVersion": "0.9"
|
||||||
}
|
}
|
||||||
+10
-3
@@ -3,8 +3,9 @@ sudo: false
|
|||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.4
|
- 1.6
|
||||||
- 1.5
|
- 1.7
|
||||||
|
- 1.8
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
@@ -21,7 +22,13 @@ env:
|
|||||||
before_install:
|
before_install:
|
||||||
- virtualenv env
|
- virtualenv env
|
||||||
- . env/bin/activate
|
- . env/bin/activate
|
||||||
- pip install boto requests python-swiftclient
|
- pip install six packaging appdirs
|
||||||
|
- pip install -U pip setuptools
|
||||||
|
- pip install boto requests requests-unixsocket python-swiftclient
|
||||||
|
- mkdir -p $GOPATH/src/github.com/smira
|
||||||
|
- ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/smira || true
|
||||||
|
- cd $GOPATH/src/github.com/smira/aptly
|
||||||
|
- make version
|
||||||
install:
|
install:
|
||||||
- make prepare
|
- make prepare
|
||||||
|
|
||||||
|
|||||||
@@ -22,3 +22,7 @@ List of contributors, in chronological order:
|
|||||||
* Phil Frost (https://github.com/bitglue)
|
* Phil Frost (https://github.com/bitglue)
|
||||||
* Benoit Foucher (https://github.com/bentoi)
|
* Benoit Foucher (https://github.com/bentoi)
|
||||||
* Geoffrey Thomas (https://github.com/geofft)
|
* Geoffrey Thomas (https://github.com/geofft)
|
||||||
|
* Oliver Sauder (https://github.com/sliverc)
|
||||||
|
* Harald Sitter (https://github.com/apachelogger)
|
||||||
|
* Johannes Layher (https://github.com/jola5)
|
||||||
|
* Charles Hsu (https://github.com/charz)
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity and
|
||||||
|
orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at [team@aptly.info](mailto:team@aptly.info). All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
gom 'github.com/AlekSi/pointer', :commit => '5f6d527dae3d678b46fbb20331ddf44e2b841943'
|
|
||||||
gom 'github.com/awalterschulze/gographviz', :commit => '20d1f693416d9be045340150094aa42035a41c9e'
|
|
||||||
gom 'github.com/aws/aws-sdk-go', :commit => 'a170e9cb76475a0da7c0326a13cc2b39e9244b3b'
|
|
||||||
gom 'github.com/cheggaaa/pb', :commit => '2c1b74620cc58a81ac152ee2d322e28c806d81ed'
|
|
||||||
gom 'github.com/DisposaBoy/JsonConfigReader', :commit => '33a99fdf1d5ee1f79b5077e9c06f955ad356d5f4'
|
|
||||||
gom 'github.com/gin-gonic/gin', :commit => 'b1758d3bfa09e61ddbc1c9a627e936eec6a170de'
|
|
||||||
gom 'github.com/go-ini/ini', :commit => 'afbd495e5aaea13597b5e14fe514ddeaa4d76fc3'
|
|
||||||
gom 'github.com/jlaffaye/ftp', :commit => 'fec71e62e457557fbe85cefc847a048d57815d76'
|
|
||||||
gom 'github.com/jmespath/go-jmespath', :commit => '0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74'
|
|
||||||
gom 'github.com/julienschmidt/httprouter', :commit => '46807412fe50aaceb73bb57061c2230fd26a1640'
|
|
||||||
gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4'
|
|
||||||
gom 'github.com/mkrautz/goar', :commit => '282caa8bd9daba480b51f1d5a988714913b97aad'
|
|
||||||
gom 'github.com/mxk/go-flowrate/flowrate', :commit => 'cca7078d478f8520f85629ad7c68962d31ed7682'
|
|
||||||
gom 'github.com/ncw/swift', :commit => '384ef27c70645e285f8bb9d02276bf654d06027e'
|
|
||||||
gom 'github.com/smira/go-aws-auth', :commit => '0070896e9d7f4f9f2d558532b2d896ce2239992a'
|
|
||||||
gom 'github.com/smira/go-xz', :commit => '0c531f070014e218b21f3cfca801cc992d52726d'
|
|
||||||
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
|
|
||||||
gom 'github.com/smira/flag', :commit => '357ed3e599ffcbd4aeaa828e1d10da2df3ea5107'
|
|
||||||
gom 'github.com/smira/go-ftp-protocol/protocol', :commit => '066b75c2b70dca7ae10b1b88b47534a3c31ccfaa'
|
|
||||||
gom 'github.com/smira/go-uuid/uuid', :commit => 'ed3ca8a15a931b141440a7e98e4f716eec255f7d'
|
|
||||||
gom 'github.com/smira/lzma', :commit => '7f0af6269940baa2c938fabe73e0d7ba41205683'
|
|
||||||
gom 'github.com/golang/snappy', :commit => '723cc1e459b8eea2dea4583200fd60757d40097a'
|
|
||||||
gom 'github.com/syndtr/goleveldb/leveldb', :commit => '917f41c560270110ceb73c5b38be2a9127387071'
|
|
||||||
gom 'github.com/ugorji/go/codec', :commit => '71c2886f5a673a35f909803f38ece5810165097b'
|
|
||||||
gom 'github.com/vaughan0/go-ini', :commit => 'a98ad7ee00ec53921f08832bc06ecf7fd600e6a1'
|
|
||||||
gom 'github.com/wsxiaoys/terminal/color', :commit => '5668e431776a7957528361f90ce828266c69ed08'
|
|
||||||
gom 'golang.org/x/crypto/ssh/terminal', :commit => 'a7ead6ddf06233883deca151dffaef2effbf498f'
|
|
||||||
|
|
||||||
group :test do
|
|
||||||
gom 'gopkg.in/check.v1'
|
|
||||||
end
|
|
||||||
|
|
||||||
group :development do
|
|
||||||
gom 'github.com/golang/lint/golint'
|
|
||||||
gom 'github.com/mattn/goveralls'
|
|
||||||
gom 'github.com/axw/gocov/gocov'
|
|
||||||
gom 'golang.org/x/tools/cmd/cover'
|
|
||||||
end
|
|
||||||
@@ -1,59 +1,58 @@
|
|||||||
GOVERSION=$(shell go version | awk '{print $$3;}')
|
GOVERSION=$(shell go version | awk '{print $$3;}')
|
||||||
|
VERSION=$(shell git describe --tags | sed 's@^v@@' | sed 's@-@+@g')
|
||||||
PACKAGES=context database deb files http query swift s3 utils
|
PACKAGES=context database deb files http query swift s3 utils
|
||||||
ALL_PACKAGES=api aptly context cmd console database deb files http query swift s3 utils
|
|
||||||
BINPATH=$(abspath ./_vendor/bin)
|
|
||||||
GOM_ENVIRONMENT=-test
|
|
||||||
PYTHON?=python
|
PYTHON?=python
|
||||||
|
TESTS?=
|
||||||
|
BINPATH?=$(GOPATH)/bin
|
||||||
|
|
||||||
ifeq ($(GOVERSION), devel)
|
ifeq ($(GOVERSION), devel)
|
||||||
TRAVIS_TARGET=coveralls
|
TRAVIS_TARGET=coveralls
|
||||||
GOM_ENVIRONMENT+=-development
|
|
||||||
else
|
else
|
||||||
TRAVIS_TARGET=test
|
TRAVIS_TARGET=test
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TRAVIS), true)
|
|
||||||
GOM=$(HOME)/gopath/bin/gom
|
|
||||||
else
|
|
||||||
GOM=gom
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: test check system-test
|
all: test check system-test
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
go get -u github.com/mattn/gom
|
go get -u github.com/mattn/goveralls
|
||||||
$(GOM) $(GOM_ENVIRONMENT) install
|
go get -u github.com/axw/gocov/gocov
|
||||||
|
go get -u golang.org/x/tools/cmd/cover
|
||||||
|
go get -u github.com/alecthomas/gometalinter
|
||||||
|
gometalinter --install
|
||||||
|
|
||||||
|
dev:
|
||||||
|
go get -u github.com/golang/dep/...
|
||||||
|
go get -u github.com/laher/goxc
|
||||||
|
|
||||||
coverage.out:
|
coverage.out:
|
||||||
rm -f coverage.*.out
|
rm -f coverage.*.out
|
||||||
for i in $(PACKAGES); do $(GOM) test -coverprofile=coverage.$$i.out -covermode=count ./$$i; done
|
for i in $(PACKAGES); do go test -coverprofile=coverage.$$i.out -covermode=count ./$$i; done
|
||||||
echo "mode: count" > coverage.out
|
echo "mode: count" > coverage.out
|
||||||
grep -v -h "mode: count" coverage.*.out >> coverage.out
|
grep -v -h "mode: count" coverage.*.out >> coverage.out
|
||||||
rm -f coverage.*.out
|
rm -f coverage.*.out
|
||||||
|
|
||||||
coverage: coverage.out
|
coverage: coverage.out
|
||||||
$(GOM) exec go tool cover -html=coverage.out
|
go tool cover -html=coverage.out
|
||||||
rm -f coverage.out
|
rm -f coverage.out
|
||||||
|
|
||||||
check:
|
check:
|
||||||
$(GOM) exec go tool vet -all=true $(ALL_PACKAGES:%=./%)
|
gometalinter --vendor --vendored-linters --config=linter.json ./...
|
||||||
$(GOM) exec golint $(ALL_PACKAGES:%=./%)
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
$(GOM) build -o $(BINPATH)/aptly
|
go install -v -ldflags "-X main.Version=$(VERSION)"
|
||||||
|
|
||||||
system-test: install
|
system-test: install
|
||||||
if [ ! -e ~/aptly-fixture-db ]; then git clone https://github.com/aptly-dev/aptly-fixture-db.git ~/aptly-fixture-db/; fi
|
if [ ! -e ~/aptly-fixture-db ]; then git clone https://github.com/aptly-dev/aptly-fixture-db.git ~/aptly-fixture-db/; fi
|
||||||
if [ ! -e ~/aptly-fixture-pool ]; then git clone https://github.com/aptly-dev/aptly-fixture-pool.git ~/aptly-fixture-pool/; fi
|
if [ ! -e ~/aptly-fixture-pool ]; then git clone https://github.com/aptly-dev/aptly-fixture-pool.git ~/aptly-fixture-pool/; fi
|
||||||
PATH=$(BINPATH)/:$(PATH) $(PYTHON) system/run.py --long
|
APTLY_VERSION=$(VERSION) PATH=$(BINPATH)/:$(PATH) $(PYTHON) system/run.py --long $(TESTS)
|
||||||
|
|
||||||
travis: $(TRAVIS_TARGET) system-test
|
travis: $(TRAVIS_TARGET) check system-test
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(GOM) test -v ./... -gocheck.v=true
|
go test -v `go list ./... | grep -v vendor/` -gocheck.v=true
|
||||||
|
|
||||||
coveralls: coverage.out
|
coveralls: coverage.out
|
||||||
$(GOM) exec $(BINPATH)/goveralls -service travis-ci.org -coverprofile=coverage.out -repotoken=$(COVERALLS_TOKEN)
|
$(BINPATH)/goveralls -service travis-ci.org -coverprofile=coverage.out -repotoken=$(COVERALLS_TOKEN)
|
||||||
|
|
||||||
mem.png: mem.dat mem.gp
|
mem.png: mem.dat mem.gp
|
||||||
gnuplot mem.gp
|
gnuplot mem.gp
|
||||||
@@ -63,14 +62,10 @@ src-package:
|
|||||||
rm -rf aptly-$(VERSION)
|
rm -rf aptly-$(VERSION)
|
||||||
mkdir -p aptly-$(VERSION)/src/github.com/smira/aptly/
|
mkdir -p aptly-$(VERSION)/src/github.com/smira/aptly/
|
||||||
cd aptly-$(VERSION)/src/github.com/smira/ && git clone https://github.com/smira/aptly && cd aptly && git checkout v$(VERSION)
|
cd aptly-$(VERSION)/src/github.com/smira/ && git clone https://github.com/smira/aptly && cd aptly && git checkout v$(VERSION)
|
||||||
cd aptly-$(VERSION)/src/github.com/smira/aptly && gom -production install
|
|
||||||
cd aptly-$(VERSION)/src/github.com/smira/aptly && find . \( -name .git -o -name .bzr -o -name .hg \) -print | xargs rm -rf
|
|
||||||
rm -rf aptly-$(VERSION)/src/github.com/smira/aptly/_vendor/{pkg,bin}
|
|
||||||
mkdir -p aptly-$(VERSION)/bash_completion.d
|
mkdir -p aptly-$(VERSION)/bash_completion.d
|
||||||
(cd aptly-$(VERSION)/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/$(VERSION)/aptly)
|
(cd aptly-$(VERSION)/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/$(VERSION)/aptly)
|
||||||
tar cyf aptly-$(VERSION)-src.tar.bz2 aptly-$(VERSION)
|
tar cyf aptly-$(VERSION)-src.tar.bz2 aptly-$(VERSION)
|
||||||
rm -rf aptly-$(VERSION)
|
rm -rf aptly-$(VERSION)
|
||||||
curl -T aptly-$(VERSION)-src.tar.bz2 -usmira:$(BINTRAY_KEY) https://api.bintray.com/content/smira/aptly/aptly/$(VERSION)/$(VERSION)/aptly-$(VERSION)-src.tar.bz2
|
|
||||||
|
|
||||||
goxc:
|
goxc:
|
||||||
rm -rf root/
|
rm -rf root/
|
||||||
@@ -78,6 +73,12 @@ goxc:
|
|||||||
cp man/aptly.1 root/usr/share/man/man1
|
cp man/aptly.1 root/usr/share/man/man1
|
||||||
(cd root/etc/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/master/aptly)
|
(cd root/etc/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/master/aptly)
|
||||||
gzip root/usr/share/man/man1/aptly.1
|
gzip root/usr/share/man/man1/aptly.1
|
||||||
gom exec goxc -pv=$(VERSION) -max-processors=4 $(GOXC_OPTS)
|
goxc -pv=$(VERSION) -max-processors=4 $(GOXC_OPTS)
|
||||||
|
|
||||||
.PHONY: coverage.out
|
man:
|
||||||
|
make -C man
|
||||||
|
|
||||||
|
version:
|
||||||
|
@echo $(VERSION)
|
||||||
|
|
||||||
|
.PHONY: coverage.out man version
|
||||||
|
|||||||
+8
-10
@@ -11,8 +11,8 @@ aptly
|
|||||||
.. image:: https://badges.gitter.im/Join Chat.svg
|
.. image:: https://badges.gitter.im/Join Chat.svg
|
||||||
:target: https://gitter.im/smira/aptly?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
:target: https://gitter.im/smira/aptly?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||||
|
|
||||||
.. image:: http://goreportcard.com/badge/gojp/goreportcard
|
.. image:: http://goreportcard.com/badge/smira/aptly
|
||||||
:target: http://goreportcard.com/report/gojp/goreportcard
|
:target: http://goreportcard.com/report/smira/aptly
|
||||||
|
|
||||||
Aptly is a swiss army knife for Debian repository management.
|
Aptly is a swiss army knife for Debian repository management.
|
||||||
|
|
||||||
@@ -64,19 +64,14 @@ If you would like to use nightly builds (unstable), please use following reposit
|
|||||||
|
|
||||||
Binary executables (depends almost only on libc) are available for download from `Bintray <http://dl.bintray.com/smira/aptly/>`_.
|
Binary executables (depends almost only on libc) are available for download from `Bintray <http://dl.bintray.com/smira/aptly/>`_.
|
||||||
|
|
||||||
If you have Go environment set up, you can build aptly from source by running (go 1.4+ required)::
|
If you have Go environment set up, you can build aptly from source by running (go 1.6+ required)::
|
||||||
|
|
||||||
go get -u github.com/mattn/gom
|
|
||||||
mkdir -p $GOPATH/src/github.com/smira/aptly
|
mkdir -p $GOPATH/src/github.com/smira/aptly
|
||||||
git clone https://github.com/smira/aptly $GOPATH/src/github.com/smira/aptly
|
git clone https://github.com/smira/aptly $GOPATH/src/github.com/smira/aptly
|
||||||
cd $GOPATH/src/github.com/smira/aptly
|
cd $GOPATH/src/github.com/smira/aptly
|
||||||
gom -production install
|
make install
|
||||||
gom build -o $GOPATH/bin/aptly
|
|
||||||
|
|
||||||
Aptly is using `gom <https://github.com/mattn/gom>`_ to fix external dependencies, so regular ``go get github.com/smira/aptly``
|
Binary would be installed to ```$GOPATH/bin/aptly``.
|
||||||
should work as well, but might fail or produce different result (if external libraries got updated).
|
|
||||||
|
|
||||||
If you don't have Go installed (or older version), you can easily install Go using `gvm <https://github.com/moovweb/gvm/>`_.
|
|
||||||
|
|
||||||
Integrations
|
Integrations
|
||||||
------------
|
------------
|
||||||
@@ -98,6 +93,8 @@ With configuration management systems:
|
|||||||
(Heavy Water Operations, LLC)
|
(Heavy Water Operations, LLC)
|
||||||
- `Puppet module <https://github.com/alphagov/puppet-aptly>`_ by
|
- `Puppet module <https://github.com/alphagov/puppet-aptly>`_ by
|
||||||
Government Digital Services
|
Government Digital Services
|
||||||
|
- `Puppet module <https://github.com/tubemogul/puppet-aptly>`_ by
|
||||||
|
TubeMogul
|
||||||
- `SaltStack Formula <https://github.com/saltstack-formulas/aptly-formula>`_ by
|
- `SaltStack Formula <https://github.com/saltstack-formulas/aptly-formula>`_ by
|
||||||
Forrest Alvarez and Brian Jackson
|
Forrest Alvarez and Brian Jackson
|
||||||
- `Ansible role <https://github.com/aioue/ansible-role-aptly>`_ by Tom Paine
|
- `Ansible role <https://github.com/aioue/ansible-role-aptly>`_ by Tom Paine
|
||||||
@@ -105,6 +102,7 @@ With configuration management systems:
|
|||||||
CLI for aptly API:
|
CLI for aptly API:
|
||||||
|
|
||||||
- `Ruby aptly CLI/library <https://github.com/sepulworld/aptly_cli>`_ by Zane Williamson
|
- `Ruby aptly CLI/library <https://github.com/sepulworld/aptly_cli>`_ by Zane Williamson
|
||||||
|
- `Python aptly CLI (good for CI) <https://github.com/TimSusa/aptly_api_cli>`_ by Tim Susa
|
||||||
|
|
||||||
Scala sbt:
|
Scala sbt:
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/cmd"
|
|
||||||
"github.com/smira/commander"
|
|
||||||
"github.com/smira/flag"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/cmd"
|
||||||
|
"github.com/smira/commander"
|
||||||
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
func allFlags(flags *flag.FlagSet) []*flag.Flag {
|
func allFlags(flags *flag.FlagSet) []*flag.Flag {
|
||||||
@@ -55,8 +55,7 @@ func main() {
|
|||||||
command.UsageLine = "aptly"
|
command.UsageLine = "aptly"
|
||||||
command.Dispatch(nil)
|
command.Dispatch(nil)
|
||||||
|
|
||||||
_, _File, _, _ := runtime.Caller(0)
|
_File, _ := filepath.Abs("./man")
|
||||||
_File, _ = filepath.Abs(_File)
|
|
||||||
|
|
||||||
templ := template.New("man").Funcs(template.FuncMap{
|
templ := template.New("man").Funcs(template.FuncMap{
|
||||||
"allFlags": allFlags,
|
"allFlags": allFlags,
|
||||||
+7
-6
@@ -3,12 +3,13 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lock order acquisition (canonical):
|
// Lock order acquisition (canonical):
|
||||||
@@ -23,8 +24,8 @@ func apiVersion(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ACQUIREDB = iota
|
acquiredb = iota
|
||||||
RELEASEDB
|
releasedb
|
||||||
)
|
)
|
||||||
|
|
||||||
// Flushes all collections which cache in-memory objects
|
// Flushes all collections which cache in-memory objects
|
||||||
@@ -80,14 +81,14 @@ func acquireDatabase(requests chan int, acks chan error) {
|
|||||||
for {
|
for {
|
||||||
request := <-requests
|
request := <-requests
|
||||||
switch request {
|
switch request {
|
||||||
case ACQUIREDB:
|
case acquiredb:
|
||||||
if clients == 0 {
|
if clients == 0 {
|
||||||
acks <- context.ReOpenDatabase()
|
acks <- context.ReOpenDatabase()
|
||||||
} else {
|
} else {
|
||||||
acks <- nil
|
acks <- nil
|
||||||
}
|
}
|
||||||
clients++
|
clients++
|
||||||
case RELEASEDB:
|
case releasedb:
|
||||||
clients--
|
clients--
|
||||||
if clients == 0 {
|
if clients == 0 {
|
||||||
flushColections()
|
flushColections()
|
||||||
|
|||||||
+2
-1
@@ -2,11 +2,12 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func verifyPath(path string) bool {
|
func verifyPath(path string) bool {
|
||||||
|
|||||||
+13
-4
@@ -3,15 +3,16 @@ package api
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/smira/aptly/deb"
|
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/smira/aptly/deb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GET /api/graph.:ext
|
// GET /api/graph.:ext?layout=[vertical|horizontal(default)]
|
||||||
func apiGraph(c *gin.Context) {
|
func apiGraph(c *gin.Context) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
@@ -19,6 +20,7 @@ func apiGraph(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
ext := c.Params.ByName("ext")
|
ext := c.Params.ByName("ext")
|
||||||
|
layout := c.Request.URL.Query().Get("layout")
|
||||||
|
|
||||||
factory := context.CollectionFactory()
|
factory := context.CollectionFactory()
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ func apiGraph(c *gin.Context) {
|
|||||||
factory.PublishedRepoCollection().RLock()
|
factory.PublishedRepoCollection().RLock()
|
||||||
defer factory.PublishedRepoCollection().RUnlock()
|
defer factory.PublishedRepoCollection().RUnlock()
|
||||||
|
|
||||||
graph, err := deb.BuildGraph(factory)
|
graph, err := deb.BuildGraph(factory, layout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, err)
|
c.JSON(500, err)
|
||||||
return
|
return
|
||||||
@@ -39,6 +41,13 @@ func apiGraph(c *gin.Context) {
|
|||||||
|
|
||||||
buf := bytes.NewBufferString(graph.String())
|
buf := bytes.NewBufferString(graph.String())
|
||||||
|
|
||||||
|
if ext == "dot" || ext == "gv" {
|
||||||
|
// If the raw dot data is requested, return it as string.
|
||||||
|
// This allows client-side rendering rather than server-side.
|
||||||
|
c.String(200, buf.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
command := exec.Command("dot", "-T"+ext)
|
command := exec.Command("dot", "-T"+ext)
|
||||||
command.Stderr = os.Stderr
|
command.Stderr = os.Stderr
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -2,10 +2,11 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SigningOptions is a shared between publish API GPG options structure
|
// SigningOptions is a shared between publish API GPG options structure
|
||||||
|
|||||||
+12
-11
@@ -2,13 +2,14 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GET /api/repos
|
// GET /api/repos
|
||||||
@@ -60,9 +61,9 @@ func apiReposCreate(c *gin.Context) {
|
|||||||
// PUT /api/repos/:name
|
// PUT /api/repos/:name
|
||||||
func apiReposEdit(c *gin.Context) {
|
func apiReposEdit(c *gin.Context) {
|
||||||
var b struct {
|
var b struct {
|
||||||
Comment string
|
Comment *string
|
||||||
DefaultDistribution string
|
DefaultDistribution *string
|
||||||
DefaultComponent string
|
DefaultComponent *string
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.Bind(&b) {
|
if !c.Bind(&b) {
|
||||||
@@ -79,14 +80,14 @@ func apiReposEdit(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.Comment != "" {
|
if b.Comment != nil {
|
||||||
repo.Comment = b.Comment
|
repo.Comment = *b.Comment
|
||||||
}
|
}
|
||||||
if b.DefaultDistribution != "" {
|
if b.DefaultDistribution != nil {
|
||||||
repo.DefaultDistribution = b.DefaultDistribution
|
repo.DefaultDistribution = *b.DefaultDistribution
|
||||||
}
|
}
|
||||||
if b.DefaultComponent != "" {
|
if b.DefaultComponent != nil {
|
||||||
repo.DefaultComponent = b.DefaultComponent
|
repo.DefaultComponent = *b.DefaultComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
err = collection.Update(repo)
|
err = collection.Update(repo)
|
||||||
|
|||||||
+4
-3
@@ -1,9 +1,10 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
ctx "github.com/smira/aptly/context"
|
ctx "github.com/smira/aptly/context"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var context *ctx.AptlyContext
|
var context *ctx.AptlyContext
|
||||||
@@ -26,14 +27,14 @@ func Router(c *ctx.AptlyContext) http.Handler {
|
|||||||
go cacheFlusher(requests, acks)
|
go cacheFlusher(requests, acks)
|
||||||
|
|
||||||
router.Use(func(c *gin.Context) {
|
router.Use(func(c *gin.Context) {
|
||||||
requests <- ACQUIREDB
|
requests <- acquiredb
|
||||||
err := <-acks
|
err := <-acks
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fail(500, err)
|
c.Fail(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
requests <- RELEASEDB
|
requests <- releasedb
|
||||||
err = <-acks
|
err = <-acks
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fail(500, err)
|
c.Fail(500, err)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
|
|||||||
+3
-2
@@ -3,8 +3,9 @@
|
|||||||
package aptly
|
package aptly
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackagePool is asbtraction of package pool storage.
|
// PackagePool is asbtraction of package pool storage.
|
||||||
@@ -82,7 +83,7 @@ type Downloader interface {
|
|||||||
// Download starts new download task
|
// Download starts new download task
|
||||||
Download(url string, destination string, result chan<- error)
|
Download(url string, destination string, result chan<- error)
|
||||||
// DownloadWithChecksum starts new download task with checksum verification
|
// DownloadWithChecksum starts new download task with checksum verification
|
||||||
DownloadWithChecksum(url string, destination string, result chan<- error, expected utils.ChecksumInfo, ignoreMismatch bool)
|
DownloadWithChecksum(url string, destination string, result chan<- error, expected utils.ChecksumInfo, ignoreMismatch bool, maxTries int)
|
||||||
// Pause pauses task processing
|
// Pause pauses task processing
|
||||||
Pause()
|
Pause()
|
||||||
// Resume resumes task processing
|
// Resume resumes task processing
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
package aptly
|
package aptly
|
||||||
|
|
||||||
// Version of aptly
|
// Version of aptly (filled in at link time)
|
||||||
const Version = "0.9.7"
|
var Version string
|
||||||
|
|
||||||
// Enable debugging features?
|
// EnableDebug triggers some debugging features
|
||||||
const EnableDebug = false
|
const EnableDebug = false
|
||||||
|
|||||||
+57
-4
@@ -2,10 +2,16 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/smira/aptly/api"
|
"github.com/smira/aptly/api"
|
||||||
|
"github.com/smira/aptly/systemd/activation"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyAPIServe(cmd *commander.Command, args []string) error {
|
func aptlyAPIServe(cmd *commander.Command, args []string) error {
|
||||||
@@ -18,10 +24,53 @@ func aptlyAPIServe(cmd *commander.Command, args []string) error {
|
|||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
listen := context.Flags().Lookup("listen").Value.String()
|
// There are only two working options for aptly's rootDir:
|
||||||
|
// 1. rootDir does not exist, then we'll create it
|
||||||
|
// 2. rootDir exists and is writable
|
||||||
|
// anything else must fail.
|
||||||
|
// E.g.: Running the service under a different user may lead to a rootDir
|
||||||
|
// that exists but is not usable due to access permissions.
|
||||||
|
err = utils.DirIsAccessible(context.Config().RootDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to recycle systemd fds for listening
|
||||||
|
listeners, err := activation.Listeners(true)
|
||||||
|
if len(listeners) > 1 {
|
||||||
|
panic("Got more than 1 listener from systemd. This is currently not supported!")
|
||||||
|
}
|
||||||
|
if err == nil && len(listeners) == 1 {
|
||||||
|
listener := listeners[0]
|
||||||
|
defer listener.Close()
|
||||||
|
fmt.Printf("\nTaking over web server at: %s (press Ctrl+C to quit)...\n", listener.Addr().String())
|
||||||
|
err = http.Serve(listener, api.Router(context))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to serve: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are none: use the listen argument.
|
||||||
|
listen := context.Flags().Lookup("listen").Value.String()
|
||||||
fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen)
|
fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen)
|
||||||
|
|
||||||
|
listenURL, err := url.Parse(listen)
|
||||||
|
if err == nil && listenURL.Scheme == "unix" {
|
||||||
|
file := listenURL.Path
|
||||||
|
os.Remove(file)
|
||||||
|
listener, err := net.Listen("unix", file)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to listen on: %s\n%s", file, err)
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
err = http.Serve(listener, api.Router(context))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to serve: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
err = http.ListenAndServe(listen, api.Router(context))
|
err = http.ListenAndServe(listen, api.Router(context))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to serve: %s", err)
|
return fmt.Errorf("unable to serve: %s", err)
|
||||||
@@ -36,16 +85,20 @@ func makeCmdAPIServe() *commander.Command {
|
|||||||
UsageLine: "serve",
|
UsageLine: "serve",
|
||||||
Short: "start API HTTP service",
|
Short: "start API HTTP service",
|
||||||
Long: `
|
Long: `
|
||||||
Stat HTTP server with aptly REST API.
|
Start HTTP server with aptly REST API. The server can listen to either a port
|
||||||
|
or Unix domain socket. When using a socket, Aptly will fully manage the socket
|
||||||
|
file. This command also supports taking over from a systemd file descriptors to
|
||||||
|
enable systemd socket activation.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly api serve -listen=:8080
|
$ aptly api serve -listen=:8080
|
||||||
|
$ aptly api serve -listen=unix:///tmp/aptly.sock
|
||||||
`,
|
`,
|
||||||
Flag: *flag.NewFlagSet("aptly-serve", flag.ExitOnError),
|
Flag: *flag.NewFlagSet("aptly-serve", flag.ExitOnError),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flag.String("listen", ":8080", "host:port for HTTP listening")
|
cmd.Flag.String("listen", ":8080", "host:port for HTTP listening or unix://path to listen on a Unix domain socket")
|
||||||
cmd.Flag.Bool("no-lock", false, "don't lock the database")
|
cmd.Flag.Bool("no-lock", false, "don't lock the database")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|||||||
+4
-3
@@ -4,13 +4,14 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
"text/template"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListPackagesRefList shows list of packages in PackageRefList
|
// ListPackagesRefList shows list of packages in PackageRefList
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -2,11 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// aptly db cleanup
|
// aptly db cleanup
|
||||||
@@ -153,7 +154,7 @@ func aptlyDbCleanup(cmd *commander.Command, args []string) error {
|
|||||||
context.Progress().ColoredPrintf("@{w!}Loading list of all packages...@|")
|
context.Progress().ColoredPrintf("@{w!}Loading list of all packages...@|")
|
||||||
allPackageRefs := context.CollectionFactory().PackageCollection().AllPackageRefs()
|
allPackageRefs := context.CollectionFactory().PackageCollection().AllPackageRefs()
|
||||||
|
|
||||||
toDelete := allPackageRefs.Substract(existingPackageRefs)
|
toDelete := allPackageRefs.Subtract(existingPackageRefs)
|
||||||
|
|
||||||
// delete packages that are no longer referenced
|
// delete packages that are no longer referenced
|
||||||
context.Progress().ColoredPrintf("@{r!}Deleting unreferenced packages (%d)...@|", toDelete.Len())
|
context.Progress().ColoredPrintf("@{r!}Deleting unreferenced packages (%d)...@|", toDelete.Len())
|
||||||
|
|||||||
+43
-7
@@ -3,14 +3,18 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/deb"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"github.com/smira/commander"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/deb"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyGraph(cmd *commander.Command, args []string) error {
|
func aptlyGraph(cmd *commander.Command, args []string) error {
|
||||||
@@ -21,8 +25,11 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout := context.Flags().Lookup("layout").Value.String()
|
||||||
|
|
||||||
fmt.Printf("Generating graph...\n")
|
fmt.Printf("Generating graph...\n")
|
||||||
graph, err := deb.BuildGraph(context.CollectionFactory())
|
graph, err := deb.BuildGraph(context.CollectionFactory(), layout)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -73,23 +80,51 @@ func aptlyGraph(cmd *commander.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = os.Remove(tempfilename)
|
||||||
|
}()
|
||||||
|
|
||||||
if output != "" {
|
if output != "" {
|
||||||
err = utils.CopyFile(tempfilename, output)
|
err = utils.CopyFile(tempfilename, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to copy %s -> %s: %s", tempfilename, output, err)
|
return fmt.Errorf("unable to copy %s -> %s: %s", tempfilename, output, err)
|
||||||
}
|
}
|
||||||
_ = os.Remove(tempfilename)
|
|
||||||
|
|
||||||
fmt.Printf("Output saved to %s\n", output)
|
fmt.Printf("Output saved to %s\n", output)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Rendered to %s file: %s, trying to open it...\n", format, tempfilename)
|
command := getOpenCommand()
|
||||||
|
fmt.Printf("Rendered to %s file: %s, trying to open it with: %s %s...\n", format, tempfilename, command, tempfilename)
|
||||||
|
|
||||||
_ = exec.Command("open", tempfilename).Run()
|
args := strings.Split(command, " ")
|
||||||
|
|
||||||
|
viewer := exec.Command(args[0], append(args[1:], tempfilename)...)
|
||||||
|
viewer.Stderr = os.Stderr
|
||||||
|
if err = viewer.Start(); err == nil {
|
||||||
|
// Wait for a second so that the visualizer has a chance to
|
||||||
|
// open the input file. This needs to be done even if we're
|
||||||
|
// waiting for the visualizer as it can be just a wrapper that
|
||||||
|
// spawns a browser tab and returns right away.
|
||||||
|
defer func(t <-chan time.Time) {
|
||||||
|
<-t
|
||||||
|
}(time.After(time.Second))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getOpenCommand tries to guess command to open image for OS
|
||||||
|
func getOpenCommand() string {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
return "/usr/bin/open"
|
||||||
|
case "windows":
|
||||||
|
return "cmd /c start"
|
||||||
|
default:
|
||||||
|
return "xdg-open"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func makeCmdGraph() *commander.Command {
|
func makeCmdGraph() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlyGraph,
|
Run: aptlyGraph,
|
||||||
@@ -108,6 +143,7 @@ Example:
|
|||||||
|
|
||||||
cmd.Flag.String("format", "png", "render graph to specified format (png, svg, pdf, etc.)")
|
cmd.Flag.String("format", "png", "render graph to specified format (png, svg, pdf, etc.)")
|
||||||
cmd.Flag.String("output", "", "specify output filename, default is to open result in viewer")
|
cmd.Flag.String("output", "", "specify output filename, default is to open result in viewer")
|
||||||
|
cmd.Flag.String("layout", "horizontal", "create a more 'vertical' or a more 'horizontal' graph layout")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1,10 +1,11 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getVerifier(flags *flag.FlagSet) (utils.Verifier, error) {
|
func getVerifier(flags *flag.FlagSet) (utils.Verifier, error) {
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyMirrorCreate(cmd *commander.Command, args []string) error {
|
func aptlyMirrorCreate(cmd *commander.Command, args []string) error {
|
||||||
@@ -43,6 +44,7 @@ func aptlyMirrorCreate(cmd *commander.Command, args []string) error {
|
|||||||
repo.Filter = context.Flags().Lookup("filter").Value.String()
|
repo.Filter = context.Flags().Lookup("filter").Value.String()
|
||||||
repo.FilterWithDeps = context.Flags().Lookup("filter-with-deps").Value.Get().(bool)
|
repo.FilterWithDeps = context.Flags().Lookup("filter-with-deps").Value.Get().(bool)
|
||||||
repo.SkipComponentCheck = context.Flags().Lookup("force-components").Value.Get().(bool)
|
repo.SkipComponentCheck = context.Flags().Lookup("force-components").Value.Get().(bool)
|
||||||
|
repo.SkipArchitectureCheck = context.Flags().Lookup("force-architectures").Value.Get().(bool)
|
||||||
|
|
||||||
if repo.Filter != "" {
|
if repo.Filter != "" {
|
||||||
_, err = query.Parse(repo.Filter)
|
_, err = query.Parse(repo.Filter)
|
||||||
@@ -97,6 +99,7 @@ Example:
|
|||||||
cmd.Flag.String("filter", "", "filter packages in mirror")
|
cmd.Flag.String("filter", "", "filter packages in mirror")
|
||||||
cmd.Flag.Bool("filter-with-deps", false, "when filtering, include dependencies of matching packages as well")
|
cmd.Flag.Bool("filter-with-deps", false, "when filtering, include dependencies of matching packages as well")
|
||||||
cmd.Flag.Bool("force-components", false, "(only with component list) skip check that requested components are listed in Release file")
|
cmd.Flag.Bool("force-components", false, "(only with component list) skip check that requested components are listed in Release file")
|
||||||
|
cmd.Flag.Bool("force-architectures", false, "(only with architecture list) skip check that requested architectures are listed in Release file")
|
||||||
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
|
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
|
|||||||
+2
-1
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyMirrorList(cmd *commander.Command, args []string) error {
|
func aptlyMirrorList(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
func makeCmdMirrorSearch() *commander.Command {
|
func makeCmdMirrorSearch() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlySnapshotMirrorRepoSearch,
|
Run: aptlySnapshotMirrorRepoSearch,
|
||||||
UsageLine: "search <name> <package-query>",
|
UsageLine: "search <name> [<package-query>]",
|
||||||
Short: "search mirror for packages matching query",
|
Short: "search mirror for packages matching query",
|
||||||
Long: `
|
Long: `
|
||||||
Command search displays list of packages in mirror that match package query
|
Command search displays list of packages in mirror that match package query
|
||||||
|
|
||||||
|
If query is not specified, all the packages are displayed.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly mirror search wheezy-main '$Architecture (i386), Name (% *-dev)'
|
$ aptly mirror search wheezy-main '$Architecture (i386), Name (% *-dev)'
|
||||||
|
|||||||
+2
-1
@@ -2,11 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyMirrorShow(cmd *commander.Command, args []string) error {
|
func aptlyMirrorShow(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
+11
-8
@@ -2,14 +2,15 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
||||||
@@ -40,6 +41,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ignoreMismatch := context.Flags().Lookup("ignore-checksums").Value.Get().(bool)
|
ignoreMismatch := context.Flags().Lookup("ignore-checksums").Value.Get().(bool)
|
||||||
|
maxTries := context.Flags().Lookup("max-tries").Value.Get().(int)
|
||||||
|
|
||||||
verifier, err := getVerifier(context.Flags())
|
verifier, err := getVerifier(context.Flags())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -52,7 +54,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.Progress().Printf("Downloading & parsing package files...\n")
|
context.Progress().Printf("Downloading & parsing package files...\n")
|
||||||
err = repo.DownloadPackageIndexes(context.Progress(), context.Downloader(), context.CollectionFactory(), ignoreMismatch)
|
err = repo.DownloadPackageIndexes(context.Progress(), context.Downloader(), context.CollectionFactory(), ignoreMismatch, maxTries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to update: %s", err)
|
return fmt.Errorf("unable to update: %s", err)
|
||||||
}
|
}
|
||||||
@@ -87,7 +89,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// on any interruption, unlock the mirror
|
// on any interruption, unlock the mirror
|
||||||
err := context.ReOpenDatabase()
|
err = context.ReOpenDatabase()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
repo.MarkAsIdle()
|
repo.MarkAsIdle()
|
||||||
context.CollectionFactory().RemoteRepoCollection().Update(repo)
|
context.CollectionFactory().RemoteRepoCollection().Update(repo)
|
||||||
@@ -121,7 +123,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
// In separate goroutine (to avoid blocking main), push queue to downloader
|
// In separate goroutine (to avoid blocking main), push queue to downloader
|
||||||
go func() {
|
go func() {
|
||||||
for _, task := range queue {
|
for _, task := range queue {
|
||||||
context.Downloader().DownloadWithChecksum(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch, task.Checksums, ignoreMismatch)
|
context.Downloader().DownloadWithChecksum(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch, task.Checksums, ignoreMismatch, maxTries)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need queue after this point
|
// We don't need queue after this point
|
||||||
@@ -129,7 +131,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for all downloads to finish
|
// Wait for all downloads to finish
|
||||||
errors := make([]string, 0)
|
var errors []string
|
||||||
|
|
||||||
for count > 0 {
|
for count > 0 {
|
||||||
select {
|
select {
|
||||||
@@ -148,7 +150,7 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
|
|||||||
signal.Stop(sigch)
|
signal.Stop(sigch)
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
return fmt.Errorf("unable to update: download errors:\n %s\n", strings.Join(errors, "\n "))
|
return fmt.Errorf("unable to update: download errors:\n %s", strings.Join(errors, "\n "))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = context.ReOpenDatabase()
|
err = context.ReOpenDatabase()
|
||||||
@@ -187,6 +189,7 @@ Example:
|
|||||||
cmd.Flag.Bool("ignore-checksums", false, "ignore checksum mismatches while downloading package files and metadata")
|
cmd.Flag.Bool("ignore-checksums", false, "ignore checksum mismatches while downloading package files and metadata")
|
||||||
cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures")
|
cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures")
|
||||||
cmd.Flag.Int64("download-limit", 0, "limit download speed (kbytes/sec)")
|
cmd.Flag.Int64("download-limit", 0, "limit download speed (kbytes/sec)")
|
||||||
|
cmd.Flag.Int("max-tries", 1, "max download tries till process fails with download error")
|
||||||
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
|
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|||||||
+19
-7
@@ -2,21 +2,31 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyPackageSearch(cmd *commander.Command, args []string) error {
|
func aptlyPackageSearch(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var (
|
||||||
if len(args) != 1 {
|
err error
|
||||||
|
q deb.PackageQuery
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
q, err := query.Parse(args[0])
|
if len(args) == 1 {
|
||||||
if err != nil {
|
q, err = query.Parse(args[0])
|
||||||
return fmt.Errorf("unable to search: %s", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to search: %s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
q = &deb.MatchAllQuery{}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := q.Query(context.CollectionFactory().PackageCollection())
|
result := q.Query(context.CollectionFactory().PackageCollection())
|
||||||
@@ -33,10 +43,12 @@ func aptlyPackageSearch(cmd *commander.Command, args []string) error {
|
|||||||
func makeCmdPackageSearch() *commander.Command {
|
func makeCmdPackageSearch() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlyPackageSearch,
|
Run: aptlyPackageSearch,
|
||||||
UsageLine: "search <package-query>",
|
UsageLine: "search [<package-query>]",
|
||||||
Short: "search for packages matching query",
|
Short: "search for packages matching query",
|
||||||
Long: `
|
Long: `
|
||||||
Command search displays list of packages in whole DB that match package query
|
Command search displays list of packages in whole DB that match package query.
|
||||||
|
|
||||||
|
If query is not specified, all the packages are displayed.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -3,11 +3,12 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func printReferencesTo(p *deb.Package) (err error) {
|
func printReferencesTo(p *deb.Package) (err error) {
|
||||||
@@ -125,7 +126,7 @@ inclusion into mirrors/snapshots/local repos is shown.
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly package show nginx-light_1.2.1-2.2+wheezy2_i386'
|
$ aptly package show 'nginx-light_1.2.1-2.2+wheezy2_i386'
|
||||||
`,
|
`,
|
||||||
Flag: *flag.NewFlagSet("aptly-package-show", flag.ExitOnError),
|
Flag: *flag.NewFlagSet("aptly-package-show", flag.ExitOnError),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ func makeCmdPublish() *commander.Command {
|
|||||||
makeCmdPublishSnapshot(),
|
makeCmdPublishSnapshot(),
|
||||||
makeCmdPublishSwitch(),
|
makeCmdPublishSwitch(),
|
||||||
makeCmdPublishUpdate(),
|
makeCmdPublishUpdate(),
|
||||||
|
makeCmdPublishShow(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyPublishList(cmd *commander.Command, args []string) error {
|
func aptlyPublishList(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/deb"
|
||||||
|
"github.com/smira/commander"
|
||||||
|
)
|
||||||
|
|
||||||
|
func aptlyPublishShow(cmd *commander.Command, args []string) error {
|
||||||
|
var err error
|
||||||
|
if len(args) < 1 || len(args) > 2 {
|
||||||
|
cmd.Usage()
|
||||||
|
return commander.ErrCommandError
|
||||||
|
}
|
||||||
|
|
||||||
|
distribution := args[0]
|
||||||
|
param := "."
|
||||||
|
|
||||||
|
if len(args) == 2 {
|
||||||
|
param = args[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
storage, prefix := deb.ParsePrefix(param)
|
||||||
|
|
||||||
|
repo, err := context.CollectionFactory().PublishedRepoCollection().ByStoragePrefixDistribution(storage, prefix, distribution)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to show: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo.Storage != "" {
|
||||||
|
fmt.Printf("Storage: %s\n", repo.Storage)
|
||||||
|
}
|
||||||
|
fmt.Printf("Prefix: %s\n", repo.Prefix)
|
||||||
|
if repo.Distribution != "" {
|
||||||
|
fmt.Printf("Distribution: %s\n", repo.Distribution)
|
||||||
|
}
|
||||||
|
fmt.Printf("Architectures: %s\n", strings.Join(repo.Architectures, " "))
|
||||||
|
|
||||||
|
fmt.Printf("Sources:\n")
|
||||||
|
for component, sourceID := range repo.Sources {
|
||||||
|
var name string
|
||||||
|
if repo.SourceKind == "snapshot" {
|
||||||
|
source, err := context.CollectionFactory().SnapshotCollection().ByUUID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = source.Name
|
||||||
|
} else if repo.SourceKind == "local" {
|
||||||
|
source, err := context.CollectionFactory().LocalRepoCollection().ByUUID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = source.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
fmt.Printf(" %s: %s [%s]\n", component, name, repo.SourceKind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCmdPublishShow() *commander.Command {
|
||||||
|
cmd := &commander.Command{
|
||||||
|
Run: aptlyPublishShow,
|
||||||
|
UsageLine: "show <distribution> [[<endpoint>:]<prefix>]",
|
||||||
|
Short: "shows details of published repository",
|
||||||
|
Long: `
|
||||||
|
Command show displays full information of a published repository.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
$ aptly publish show wheezy
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
@@ -2,12 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
|
|||||||
+2
-1
@@ -2,12 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
func aptlyRepoAdd(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
+24
-2
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
@@ -9,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func aptlyRepoCreate(cmd *commander.Command, args []string) error {
|
func aptlyRepoCreate(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if len(args) != 1 {
|
if !(len(args) == 1 || (len(args) == 4 && args[1] == "from" && args[2] == "snapshot")) {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
@@ -26,6 +27,22 @@ func aptlyRepoCreate(cmd *commander.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(args) == 4 {
|
||||||
|
var snapshot *deb.Snapshot
|
||||||
|
|
||||||
|
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(args[3])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load source snapshot: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load source snapshot: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo.UpdateRefList(snapshot.RefList())
|
||||||
|
}
|
||||||
|
|
||||||
err = context.CollectionFactory().LocalRepoCollection().Add(repo)
|
err = context.CollectionFactory().LocalRepoCollection().Add(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to add local repo: %s", err)
|
return fmt.Errorf("unable to add local repo: %s", err)
|
||||||
@@ -38,16 +55,21 @@ func aptlyRepoCreate(cmd *commander.Command, args []string) error {
|
|||||||
func makeCmdRepoCreate() *commander.Command {
|
func makeCmdRepoCreate() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlyRepoCreate,
|
Run: aptlyRepoCreate,
|
||||||
UsageLine: "create <name>",
|
UsageLine: "create <name> [ from snapshot <snapshot> ]",
|
||||||
Short: "create local repository",
|
Short: "create local repository",
|
||||||
Long: `
|
Long: `
|
||||||
Create local package repository. Repository would be empty when
|
Create local package repository. Repository would be empty when
|
||||||
created, packages could be added from files, copied or moved from
|
created, packages could be added from files, copied or moved from
|
||||||
another local repository or imported from the mirror.
|
another local repository or imported from the mirror.
|
||||||
|
|
||||||
|
If local package repository is created from snapshot, repo initial
|
||||||
|
contents are copied from snapsot contents.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly repo create testing
|
$ aptly repo create testing
|
||||||
|
|
||||||
|
$ aptly repo create mysql35 from snapshot mysql-35-2017
|
||||||
`,
|
`,
|
||||||
Flag: *flag.NewFlagSet("aptly-repo-create", flag.ExitOnError),
|
Flag: *flag.NewFlagSet("aptly-repo-create", flag.ExitOnError),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/AlekSi/pointer"
|
"github.com/AlekSi/pointer"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
|
|||||||
+4
-3
@@ -3,15 +3,16 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyRepoInclude(cmd *commander.Command, args []string) error {
|
func aptlyRepoInclude(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
+2
-1
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyRepoList(cmd *commander.Command, args []string) error {
|
func aptlyRepoList(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
+2
-1
@@ -2,11 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyRepoMoveCopyImport(cmd *commander.Command, args []string) error {
|
func aptlyRepoMoveCopyImport(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-1
@@ -8,11 +8,13 @@ import (
|
|||||||
func makeCmdRepoSearch() *commander.Command {
|
func makeCmdRepoSearch() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlySnapshotMirrorRepoSearch,
|
Run: aptlySnapshotMirrorRepoSearch,
|
||||||
UsageLine: "search <name> <package-query>",
|
UsageLine: "search <name> [<package-query>]",
|
||||||
Short: "search repo for packages matching query",
|
Short: "search repo for packages matching query",
|
||||||
Long: `
|
Long: `
|
||||||
Command search displays list of packages in local repository that match package query
|
Command search displays list of packages in local repository that match package query
|
||||||
|
|
||||||
|
If query is not specified, all the packages are displayed.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly repo search my-software '$Architecture (i386), Name (% *-dev)'
|
$ aptly repo search my-software '$Architecture (i386), Name (% *-dev)'
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
ctx "github.com/smira/aptly/context"
|
ctx "github.com/smira/aptly/context"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Run runs single command starting from root cmd with args, optionally initializing context
|
// Run runs single command starting from root cmd with args, optionally initializing context
|
||||||
|
|||||||
+17
-5
@@ -2,16 +2,17 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/deb"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"github.com/smira/commander"
|
|
||||||
"github.com/smira/flag"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/deb"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
"github.com/smira/commander"
|
||||||
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlyServe(cmd *commander.Command, args []string) error {
|
func aptlyServe(cmd *commander.Command, args []string) error {
|
||||||
@@ -22,6 +23,17 @@ func aptlyServe(cmd *commander.Command, args []string) error {
|
|||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There are only two working options for aptly's rootDir:
|
||||||
|
// 1. rootDir does not exist, then we'll create it
|
||||||
|
// 2. rootDir exists and is writable
|
||||||
|
// anything else must fail.
|
||||||
|
// E.g.: Running the service under a different user may lead to a rootDir
|
||||||
|
// that exists but is not usable due to access permissions.
|
||||||
|
err = utils.DirIsAccessible(context.Config().RootDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if context.CollectionFactory().PublishedRepoCollection().Len() == 0 {
|
if context.CollectionFactory().PublishedRepoCollection().Len() == 0 {
|
||||||
fmt.Printf("No published repositories, unable to serve.\n")
|
fmt.Printf("No published repositories, unable to serve.\n")
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlySnapshotFilter(cmd *commander.Command, args []string) error {
|
func aptlySnapshotFilter(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlySnapshotMerge(cmd *commander.Command, args []string) error {
|
func aptlySnapshotMerge(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
func aptlySnapshotPull(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
+18
-7
@@ -2,16 +2,21 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/aptly/query"
|
"github.com/smira/aptly/query"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error {
|
func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error {
|
||||||
var err error
|
var (
|
||||||
if len(args) != 2 {
|
err error
|
||||||
|
q deb.PackageQuery
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(args) < 1 || len(args) > 2 {
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return commander.ErrCommandError
|
return commander.ErrCommandError
|
||||||
}
|
}
|
||||||
@@ -68,9 +73,13 @@ func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error
|
|||||||
|
|
||||||
list.PrepareIndex()
|
list.PrepareIndex()
|
||||||
|
|
||||||
q, err := query.Parse(args[1])
|
if len(args) == 2 {
|
||||||
if err != nil {
|
q, err = query.Parse(args[1])
|
||||||
return fmt.Errorf("unable to search: %s", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to search: %s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
q = &deb.MatchAllQuery{}
|
||||||
}
|
}
|
||||||
|
|
||||||
withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool)
|
withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool)
|
||||||
@@ -109,11 +118,13 @@ func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error
|
|||||||
func makeCmdSnapshotSearch() *commander.Command {
|
func makeCmdSnapshotSearch() *commander.Command {
|
||||||
cmd := &commander.Command{
|
cmd := &commander.Command{
|
||||||
Run: aptlySnapshotMirrorRepoSearch,
|
Run: aptlySnapshotMirrorRepoSearch,
|
||||||
UsageLine: "search <name> <package-query>",
|
UsageLine: "search <name> [<package-query>]",
|
||||||
Short: "search snapshot for packages matching query",
|
Short: "search snapshot for packages matching query",
|
||||||
Long: `
|
Long: `
|
||||||
Command search displays list of packages in snapshot that match package query
|
Command search displays list of packages in snapshot that match package query
|
||||||
|
|
||||||
|
If query is not specified, all the packages are displayed.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ aptly snapshot search wheezy-main '$Architecture (i386), Name (% *-dev)'
|
$ aptly snapshot search wheezy-main '$Architecture (i386), Name (% *-dev)'
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
)
|
)
|
||||||
@@ -29,6 +30,35 @@ func aptlySnapshotShow(cmd *commander.Command, args []string) error {
|
|||||||
fmt.Printf("Created At: %s\n", snapshot.CreatedAt.Format("2006-01-02 15:04:05 MST"))
|
fmt.Printf("Created At: %s\n", snapshot.CreatedAt.Format("2006-01-02 15:04:05 MST"))
|
||||||
fmt.Printf("Description: %s\n", snapshot.Description)
|
fmt.Printf("Description: %s\n", snapshot.Description)
|
||||||
fmt.Printf("Number of packages: %d\n", snapshot.NumPackages())
|
fmt.Printf("Number of packages: %d\n", snapshot.NumPackages())
|
||||||
|
if len(snapshot.SourceIDs) > 0 {
|
||||||
|
fmt.Printf("Sources:\n")
|
||||||
|
for _, sourceID := range snapshot.SourceIDs {
|
||||||
|
var name string
|
||||||
|
if snapshot.SourceKind == "snapshot" {
|
||||||
|
source, err := context.CollectionFactory().SnapshotCollection().ByUUID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = source.Name
|
||||||
|
} else if snapshot.SourceKind == "local" {
|
||||||
|
source, err := context.CollectionFactory().LocalRepoCollection().ByUUID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = source.Name
|
||||||
|
} else if snapshot.SourceKind == "repo" {
|
||||||
|
source, err := context.CollectionFactory().RemoteRepoCollection().ByUUID(sourceID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = source.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
fmt.Printf(" %s [%s]\n", name, snapshot.SourceKind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
withPackages := context.Flags().Lookup("with-packages").Value.Get().(bool)
|
withPackages := context.Flags().Lookup("with-packages").Value.Get().(bool)
|
||||||
if withPackages {
|
if withPackages {
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/deb"
|
"github.com/smira/aptly/deb"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func aptlySnapshotVerify(cmd *commander.Command, args []string) error {
|
func aptlySnapshotVerify(cmd *commander.Command, args []string) error {
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ func aptlyTaskRun(cmd *commander.Command, args []string) error {
|
|||||||
|
|
||||||
var finfo os.FileInfo
|
var finfo os.FileInfo
|
||||||
if finfo, err = os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
|
if finfo, err = os.Stat(filename); os.IsNotExist(err) || finfo.IsDir() {
|
||||||
return fmt.Errorf("no such file, %s\n", filename)
|
return fmt.Errorf("no such file, %s", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print("Reading file...\n\n")
|
fmt.Print("Reading file...\n\n")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -2,10 +2,11 @@ package console
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/cheggaaa/pb"
|
"github.com/cheggaaa/pb"
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/wsxiaoys/terminal/color"
|
"github.com/wsxiaoys/terminal/color"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
package console
|
package console
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunningOnTerminal checks whether stdout is terminal
|
// RunningOnTerminal checks whether stdout is terminal
|
||||||
|
|||||||
+9
-8
@@ -3,6 +3,14 @@ package context
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/console"
|
"github.com/smira/aptly/console"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
@@ -14,13 +22,6 @@ import (
|
|||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"github.com/smira/commander"
|
"github.com/smira/commander"
|
||||||
"github.com/smira/flag"
|
"github.com/smira/flag"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"runtime/pprof"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AptlyContext is a common context shared by all commands
|
// AptlyContext is a common context shared by all commands
|
||||||
@@ -337,7 +338,7 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
publishedStorage, err = swift.NewPublishedStorage(params.UserName, params.Password,
|
publishedStorage, err = swift.NewPublishedStorage(params.UserName, params.Password,
|
||||||
params.AuthURL, params.Tenant, params.TenantID, params.Container, params.Prefix)
|
params.AuthURL, params.Tenant, params.TenantID, params.Domain, params.DomainID, params.TenantDomain, params.TenantDomainID, params.Container, params.Prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-3
@@ -4,6 +4,9 @@ package database
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||||
@@ -16,11 +19,17 @@ var (
|
|||||||
ErrNotFound = errors.New("key not found")
|
ErrNotFound = errors.New("key not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// StorageProcessor is a function to process one single storage entry
|
||||||
|
type StorageProcessor func(key []byte, value []byte) error
|
||||||
|
|
||||||
// Storage is an interface to KV storage
|
// Storage is an interface to KV storage
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
|
CreateTemporary() (Storage, error)
|
||||||
Get(key []byte) ([]byte, error)
|
Get(key []byte) ([]byte, error)
|
||||||
Put(key []byte, value []byte) error
|
Put(key []byte, value []byte) error
|
||||||
Delete(key []byte) error
|
Delete(key []byte) error
|
||||||
|
HasPrefix(prefix []byte) bool
|
||||||
|
ProcessByPrefix(prefix []byte, proc StorageProcessor) error
|
||||||
KeysByPrefix(prefix []byte) [][]byte
|
KeysByPrefix(prefix []byte) [][]byte
|
||||||
FetchByPrefix(prefix []byte) [][]byte
|
FetchByPrefix(prefix []byte) [][]byte
|
||||||
Close() error
|
Close() error
|
||||||
@@ -28,6 +37,7 @@ type Storage interface {
|
|||||||
StartBatch()
|
StartBatch()
|
||||||
FinishBatch() error
|
FinishBatch() error
|
||||||
CompactDB() error
|
CompactDB() error
|
||||||
|
Drop() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type levelDB struct {
|
type levelDB struct {
|
||||||
@@ -41,18 +51,24 @@ var (
|
|||||||
_ Storage = &levelDB{}
|
_ Storage = &levelDB{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func internalOpen(path string) (*leveldb.DB, error) {
|
func internalOpen(path string, throttleCompaction bool) (*leveldb.DB, error) {
|
||||||
o := &opt.Options{
|
o := &opt.Options{
|
||||||
Filter: filter.NewBloomFilter(10),
|
Filter: filter.NewBloomFilter(10),
|
||||||
OpenFilesCacheCapacity: 256,
|
OpenFilesCacheCapacity: 256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if throttleCompaction {
|
||||||
|
o.CompactionL0Trigger = 32
|
||||||
|
o.WriteL0PauseTrigger = 96
|
||||||
|
o.WriteL0SlowdownTrigger = 64
|
||||||
|
}
|
||||||
|
|
||||||
return leveldb.OpenFile(path, o)
|
return leveldb.OpenFile(path, o)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenDB opens (creates) LevelDB database
|
// OpenDB opens (creates) LevelDB database
|
||||||
func OpenDB(path string) (Storage, error) {
|
func OpenDB(path string) (Storage, error) {
|
||||||
db, err := internalOpen(path)
|
db, err := internalOpen(path, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -77,6 +93,20 @@ func RecoverDB(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateTemporary creates new DB of the same type in temp dir
|
||||||
|
func (l *levelDB) CreateTemporary() (Storage, error) {
|
||||||
|
tempdir, err := ioutil.TempDir("", "aptly")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := internalOpen(tempdir, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &levelDB{db: db, path: tempdir}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get key value from database
|
// Get key value from database
|
||||||
func (l *levelDB) Get(key []byte) ([]byte, error) {
|
func (l *levelDB) Get(key []byte) ([]byte, error) {
|
||||||
value, err := l.db.Get(key, nil)
|
value, err := l.db.Get(key, nil)
|
||||||
@@ -152,6 +182,29 @@ func (l *levelDB) FetchByPrefix(prefix []byte) [][]byte {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasPrefix checks whether it can find any key with given prefix and returns true if one exists
|
||||||
|
func (l *levelDB) HasPrefix(prefix []byte) bool {
|
||||||
|
iterator := l.db.NewIterator(nil, nil)
|
||||||
|
defer iterator.Release()
|
||||||
|
return iterator.Seek(prefix) && bytes.HasPrefix(iterator.Key(), prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessByPrefix iterates through all entries where key starts with prefix and calls
|
||||||
|
// StorageProcessor on key value pair
|
||||||
|
func (l *levelDB) ProcessByPrefix(prefix []byte, proc StorageProcessor) error {
|
||||||
|
iterator := l.db.NewIterator(nil, nil)
|
||||||
|
defer iterator.Release()
|
||||||
|
|
||||||
|
for ok := iterator.Seek(prefix); ok && bytes.HasPrefix(iterator.Key(), prefix); ok = iterator.Next() {
|
||||||
|
err := proc(iterator.Key(), iterator.Value())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Close finishes DB work
|
// Close finishes DB work
|
||||||
func (l *levelDB) Close() error {
|
func (l *levelDB) Close() error {
|
||||||
if l.db == nil {
|
if l.db == nil {
|
||||||
@@ -169,7 +222,7 @@ func (l *levelDB) ReOpen() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
l.db, err = internalOpen(l.path)
|
l.db, err = internalOpen(l.path, false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,3 +250,12 @@ func (l *levelDB) FinishBatch() error {
|
|||||||
func (l *levelDB) CompactDB() error {
|
func (l *levelDB) CompactDB() error {
|
||||||
return l.db.CompactRange(util.Range{})
|
return l.db.CompactRange(util.Range{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop removes all the DB files (DANGEROUS!)
|
||||||
|
func (l *levelDB) Drop() error {
|
||||||
|
if l.db != nil {
|
||||||
|
return errors.New("DB is still open")
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.RemoveAll(l.path)
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,29 @@ func (s *LevelDBSuite) TestGetPut(c *C) {
|
|||||||
c.Assert(result, DeepEquals, value)
|
c.Assert(result, DeepEquals, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LevelDBSuite) TestTemporaryDelete(c *C) {
|
||||||
|
var (
|
||||||
|
key = []byte("key")
|
||||||
|
value = []byte("value")
|
||||||
|
)
|
||||||
|
|
||||||
|
err := s.db.Put(key, value)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
temp, err := s.db.CreateTemporary()
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
c.Check(s.db.HasPrefix([]byte(nil)), Equals, true)
|
||||||
|
c.Check(temp.HasPrefix([]byte(nil)), Equals, false)
|
||||||
|
|
||||||
|
err = temp.Put(key, value)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
c.Check(temp.HasPrefix([]byte(nil)), Equals, true)
|
||||||
|
|
||||||
|
c.Assert(temp.Close(), IsNil)
|
||||||
|
c.Assert(temp.Drop(), IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LevelDBSuite) TestDelete(c *C) {
|
func (s *LevelDBSuite) TestDelete(c *C) {
|
||||||
var (
|
var (
|
||||||
key = []byte("key")
|
key = []byte("key")
|
||||||
@@ -107,10 +130,41 @@ func (s *LevelDBSuite) TestByPrefix(c *C) {
|
|||||||
c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{{0x01}, {0x02}, {0x03}})
|
c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{{0x01}, {0x02}, {0x03}})
|
||||||
c.Check(s.db.KeysByPrefix([]byte{0x80}), DeepEquals, [][]byte{{0x80, 0x01}, {0x80, 0x02}, {0x80, 0x03}})
|
c.Check(s.db.KeysByPrefix([]byte{0x80}), DeepEquals, [][]byte{{0x80, 0x01}, {0x80, 0x02}, {0x80, 0x03}})
|
||||||
|
|
||||||
|
keys := [][]byte{}
|
||||||
|
values := [][]byte{}
|
||||||
|
|
||||||
|
c.Check(s.db.ProcessByPrefix([]byte{0x80}, func(k, v []byte) error {
|
||||||
|
keys = append(keys, append([]byte(nil), k...))
|
||||||
|
values = append(values, append([]byte(nil), v...))
|
||||||
|
return nil
|
||||||
|
}), IsNil)
|
||||||
|
|
||||||
|
c.Check(values, DeepEquals, [][]byte{{0x01}, {0x02}, {0x03}})
|
||||||
|
c.Check(keys, DeepEquals, [][]byte{{0x80, 0x01}, {0x80, 0x02}, {0x80, 0x03}})
|
||||||
|
|
||||||
|
c.Check(s.db.ProcessByPrefix([]byte{0x80}, func(k, v []byte) error {
|
||||||
|
return ErrNotFound
|
||||||
|
}), Equals, ErrNotFound)
|
||||||
|
|
||||||
|
c.Check(s.db.ProcessByPrefix([]byte{0xa0}, func(k, v []byte) error {
|
||||||
|
return ErrNotFound
|
||||||
|
}), IsNil)
|
||||||
|
|
||||||
c.Check(s.db.FetchByPrefix([]byte{0xa0}), DeepEquals, [][]byte{})
|
c.Check(s.db.FetchByPrefix([]byte{0xa0}), DeepEquals, [][]byte{})
|
||||||
c.Check(s.db.KeysByPrefix([]byte{0xa0}), DeepEquals, [][]byte{})
|
c.Check(s.db.KeysByPrefix([]byte{0xa0}), DeepEquals, [][]byte{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LevelDBSuite) TestHasPrefix(c *C) {
|
||||||
|
c.Check(s.db.HasPrefix([]byte(nil)), Equals, false)
|
||||||
|
c.Check(s.db.HasPrefix([]byte{0x80}), Equals, false)
|
||||||
|
|
||||||
|
s.db.Put([]byte{0x80, 0x01}, []byte{0x01})
|
||||||
|
|
||||||
|
c.Check(s.db.HasPrefix([]byte(nil)), Equals, true)
|
||||||
|
c.Check(s.db.HasPrefix([]byte{0x80}), Equals, true)
|
||||||
|
c.Check(s.db.HasPrefix([]byte{0x79}), Equals, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LevelDBSuite) TestBatch(c *C) {
|
func (s *LevelDBSuite) TestBatch(c *C) {
|
||||||
var (
|
var (
|
||||||
key = []byte("key")
|
key = []byte("key")
|
||||||
|
|||||||
+21
-2
@@ -2,13 +2,14 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Changes is a result of .changes file parsing
|
// Changes is a result of .changes file parsing
|
||||||
@@ -179,11 +180,29 @@ func (c *Changes) PackageQuery() (PackageQuery, error) {
|
|||||||
var binaryQuery PackageQuery
|
var binaryQuery PackageQuery
|
||||||
if len(c.Binary) > 0 {
|
if len(c.Binary) > 0 {
|
||||||
binaryQuery = &FieldQuery{Field: "Name", Relation: VersionEqual, Value: c.Binary[0]}
|
binaryQuery = &FieldQuery{Field: "Name", Relation: VersionEqual, Value: c.Binary[0]}
|
||||||
|
// matching debug ddeb packages, they're not present in the Binary field
|
||||||
|
var ddebQuery PackageQuery
|
||||||
|
ddebQuery = &FieldQuery{Field: "Name", Relation: VersionEqual, Value: fmt.Sprintf("%s-dbgsym", c.Binary[0])}
|
||||||
|
|
||||||
for _, binary := range c.Binary[1:] {
|
for _, binary := range c.Binary[1:] {
|
||||||
binaryQuery = &OrQuery{
|
binaryQuery = &OrQuery{
|
||||||
L: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: binary},
|
L: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: binary},
|
||||||
R: binaryQuery,
|
R: binaryQuery,
|
||||||
}
|
}
|
||||||
|
ddebQuery = &OrQuery{
|
||||||
|
L: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: fmt.Sprintf("%s-dbgsym", binary)},
|
||||||
|
R: ddebQuery,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ddebQuery = &AndQuery{
|
||||||
|
L: &FieldQuery{Field: "Source", Relation: VersionEqual, Value: c.Source},
|
||||||
|
R: ddebQuery,
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryQuery = &OrQuery{
|
||||||
|
L: binaryQuery,
|
||||||
|
R: ddebQuery,
|
||||||
}
|
}
|
||||||
|
|
||||||
binaryQuery = &AndQuery{
|
binaryQuery = &AndQuery{
|
||||||
|
|||||||
+3
-2
@@ -1,9 +1,10 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "gopkg.in/check.v1"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChangesSuite struct {
|
type ChangesSuite struct {
|
||||||
@@ -54,7 +55,7 @@ func (s *ChangesSuite) TestPackageQuery(c *C) {
|
|||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
c.Check(q.String(), Equals,
|
c.Check(q.String(), Equals,
|
||||||
"(($Architecture (= amd64)) | (($Architecture (= source)) | ($Architecture (= )))), ((($PackageType (= source)), (Name (= calamares))) | ((!($PackageType (= source))), ((Name (= calamares-dbg)) | (Name (= calamares)))))")
|
"(($Architecture (= amd64)) | (($Architecture (= source)) | ($Architecture (= )))), ((($PackageType (= source)), (Name (= calamares))) | ((!($PackageType (= source))), (((Name (= calamares-dbg)) | (Name (= calamares))) | ((Source (= calamares)), ((Name (= calamares-dbg-dbgsym)) | (Name (= calamares-dbgsym)))))))")
|
||||||
}
|
}
|
||||||
|
|
||||||
var changesFile = `Format: 1.8
|
var changesFile = `Format: 1.8
|
||||||
|
|||||||
+9
-1
@@ -1,8 +1,9 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/smira/aptly/database"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CollectionFactory is a single place to generate all desired collections
|
// CollectionFactory is a single place to generate all desired collections
|
||||||
@@ -21,6 +22,13 @@ func NewCollectionFactory(db database.Storage) *CollectionFactory {
|
|||||||
return &CollectionFactory{Mutex: &sync.Mutex{}, db: db}
|
return &CollectionFactory{Mutex: &sync.Mutex{}, db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TemporaryDB creates new temporary DB
|
||||||
|
//
|
||||||
|
// DB should be closed/droped after being used
|
||||||
|
func (factory *CollectionFactory) TemporaryDB() (database.Storage, error) {
|
||||||
|
return factory.db.CreateTemporary()
|
||||||
|
}
|
||||||
|
|
||||||
// PackageCollection returns (or creates) new PackageCollection
|
// PackageCollection returns (or creates) new PackageCollection
|
||||||
func (factory *CollectionFactory) PackageCollection() *PackageCollection {
|
func (factory *CollectionFactory) PackageCollection() *PackageCollection {
|
||||||
factory.Lock()
|
factory.Lock()
|
||||||
|
|||||||
+90
-30
@@ -1,75 +1,135 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
|
||||||
"strings"
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/database"
|
||||||
|
"github.com/smira/go-uuid/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContentsIndex calculates mapping from files to packages, with sorting and aggregation
|
// ContentsIndex calculates mapping from files to packages, with sorting and aggregation
|
||||||
type ContentsIndex struct {
|
type ContentsIndex struct {
|
||||||
index map[string][]*Package
|
db database.Storage
|
||||||
|
prefix []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContentsIndex creates empty ContentsIndex
|
// NewContentsIndex creates empty ContentsIndex
|
||||||
func NewContentsIndex() *ContentsIndex {
|
func NewContentsIndex(db database.Storage) *ContentsIndex {
|
||||||
return &ContentsIndex{
|
return &ContentsIndex{
|
||||||
index: make(map[string][]*Package),
|
db: db,
|
||||||
|
prefix: []byte(uuid.New()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push adds package to contents index, calculating package contents as required
|
// Push adds package to contents index, calculating package contents as required
|
||||||
func (index *ContentsIndex) Push(p *Package, packagePool aptly.PackagePool) {
|
func (index *ContentsIndex) Push(p *Package, packagePool aptly.PackagePool) error {
|
||||||
contents := p.Contents(packagePool)
|
contents := p.Contents(packagePool)
|
||||||
|
qualifiedName := []byte(p.QualifiedName())
|
||||||
|
|
||||||
for _, path := range contents {
|
for _, path := range contents {
|
||||||
index.index[path] = append(index.index[path], p)
|
// for performance reasons we only write to leveldb during push.
|
||||||
|
// merging of qualified names per path will be done in WriteTo
|
||||||
|
err := index.db.Put(append(append(append(index.prefix, []byte(path)...), byte(0)), qualifiedName...), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty checks whether index contains no packages
|
// Empty checks whether index contains no packages
|
||||||
func (index *ContentsIndex) Empty() bool {
|
func (index *ContentsIndex) Empty() bool {
|
||||||
return len(index.index) == 0
|
return !index.db.HasPrefix(index.prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteTo dumps sorted mapping of files to qualified package names
|
// WriteTo dumps sorted mapping of files to qualified package names
|
||||||
func (index *ContentsIndex) WriteTo(w io.Writer) (int64, error) {
|
func (index *ContentsIndex) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
// For performance reasons push method wrote on key per path and package
|
||||||
|
// in this method we now need to merge all packages which have the same path
|
||||||
|
// and write it to contents index file
|
||||||
|
|
||||||
var n int64
|
var n int64
|
||||||
|
|
||||||
paths := make([]string, len(index.index))
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for path := range index.index {
|
|
||||||
paths[i] = path
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(paths)
|
|
||||||
|
|
||||||
nn, err := fmt.Fprintf(w, "%s %s\n", "FILE", "LOCATION")
|
nn, err := fmt.Fprintf(w, "%s %s\n", "FILE", "LOCATION")
|
||||||
n += int64(nn)
|
n += int64(nn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range paths {
|
prefixLen := len(index.prefix)
|
||||||
packages := index.index[path]
|
|
||||||
parts := make([]string, 0, len(packages))
|
var (
|
||||||
for i := range packages {
|
currentPath []byte
|
||||||
name := packages[i].QualifiedName()
|
currentPkgs [][]byte
|
||||||
if !utils.StrSliceHasItem(parts, name) {
|
)
|
||||||
parts = append(parts, name)
|
|
||||||
}
|
err = index.db.ProcessByPrefix(index.prefix, func(key []byte, value []byte) error {
|
||||||
|
// cut prefix
|
||||||
|
key = key[prefixLen:]
|
||||||
|
|
||||||
|
i := bytes.Index(key, []byte{0})
|
||||||
|
if i == -1 {
|
||||||
|
return errors.New("corrupted index entry")
|
||||||
}
|
}
|
||||||
nn, err = fmt.Fprintf(w, "%s %s\n", path, strings.Join(parts, ","))
|
|
||||||
|
path := key[:i]
|
||||||
|
pkg := key[i+1:]
|
||||||
|
|
||||||
|
if !bytes.Equal(path, currentPath) {
|
||||||
|
if currentPath != nil {
|
||||||
|
nn, err = w.Write(append(currentPath, ' '))
|
||||||
|
n += int64(nn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nn, err = w.Write(bytes.Join(currentPkgs, []byte{','}))
|
||||||
|
n += int64(nn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nn, err = w.Write([]byte{'\n'})
|
||||||
|
n += int64(nn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPath = append([]byte(nil), path...)
|
||||||
|
currentPkgs = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPkgs = append(currentPkgs, append([]byte(nil), pkg...))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentPath != nil {
|
||||||
|
nn, err = w.Write(append(currentPath, ' '))
|
||||||
n += int64(nn)
|
n += int64(nn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nn, err = w.Write(bytes.Join(currentPkgs, []byte{','}))
|
||||||
|
n += int64(nn)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nn, err = w.Write([]byte{'\n'})
|
||||||
|
n += int64(nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, nil
|
return n, err
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-13
@@ -2,16 +2,20 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
"bufio"
|
||||||
"compress/bzip2"
|
"compress/bzip2"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mkrautz/goar"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"github.com/smira/go-xz"
|
|
||||||
"github.com/smira/lzma"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/h2non/filetype/matchers"
|
||||||
|
"github.com/mkrautz/goar"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
"github.com/smira/go-xz"
|
||||||
|
"github.com/smira/lzma"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetControlFileFromDeb reads control file from deb package
|
// GetControlFileFromDeb reads control file from deb package
|
||||||
@@ -119,29 +123,41 @@ func GetContentsFromDeb(packageFile string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(header.Name, "data.tar") {
|
if strings.HasPrefix(header.Name, "data.tar") {
|
||||||
|
bufReader := bufio.NewReader(library)
|
||||||
|
signature, err := bufReader.Peek(270)
|
||||||
|
|
||||||
|
var isTar bool
|
||||||
|
if err == nil {
|
||||||
|
isTar = matchers.Tar(signature)
|
||||||
|
}
|
||||||
|
|
||||||
var tarInput io.Reader
|
var tarInput io.Reader
|
||||||
|
|
||||||
switch header.Name {
|
switch header.Name {
|
||||||
case "data.tar":
|
case "data.tar":
|
||||||
tarInput = library
|
tarInput = bufReader
|
||||||
case "data.tar.gz":
|
case "data.tar.gz":
|
||||||
ungzip, err := gzip.NewReader(library)
|
if isTar {
|
||||||
if err != nil {
|
tarInput = bufReader
|
||||||
return nil, fmt.Errorf("unable to ungzip data.tar.gz from %s: %s", packageFile, err)
|
} else {
|
||||||
|
ungzip, err := gzip.NewReader(bufReader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to ungzip data.tar.gz from %s: %s", packageFile, err)
|
||||||
|
}
|
||||||
|
defer ungzip.Close()
|
||||||
|
tarInput = ungzip
|
||||||
}
|
}
|
||||||
defer ungzip.Close()
|
|
||||||
tarInput = ungzip
|
|
||||||
case "data.tar.bz2":
|
case "data.tar.bz2":
|
||||||
tarInput = bzip2.NewReader(library)
|
tarInput = bzip2.NewReader(bufReader)
|
||||||
case "data.tar.xz":
|
case "data.tar.xz":
|
||||||
unxz, err := xz.NewReader(library)
|
unxz, err := xz.NewReader(bufReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to unxz data.tar.xz from %s: %s", packageFile, err)
|
return nil, fmt.Errorf("unable to unxz data.tar.xz from %s: %s", packageFile, err)
|
||||||
}
|
}
|
||||||
defer unxz.Close()
|
defer unxz.Close()
|
||||||
tarInput = unxz
|
tarInput = unxz
|
||||||
case "data.tar.lzma":
|
case "data.tar.lzma":
|
||||||
unlzma := lzma.NewReader(library)
|
unlzma := lzma.NewReader(bufReader)
|
||||||
defer unlzma.Close()
|
defer unlzma.Close()
|
||||||
tarInput = unlzma
|
tarInput = unlzma
|
||||||
default:
|
default:
|
||||||
|
|||||||
+2
-1
@@ -1,10 +1,11 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+28
-10
@@ -2,18 +2,34 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/awalterschulze/gographviz"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/awalterschulze/gographviz"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildGraph generates graph contents from aptly object database
|
// BuildGraph generates graph contents from aptly object database
|
||||||
func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, error) {
|
func BuildGraph(collectionFactory *CollectionFactory, layout string) (gographviz.Interface, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
graph := gographviz.NewEscape()
|
graph := gographviz.NewEscape()
|
||||||
graph.SetDir(true)
|
graph.SetDir(true)
|
||||||
graph.SetName("aptly")
|
graph.SetName("aptly")
|
||||||
|
|
||||||
|
var labelStart string
|
||||||
|
var labelEnd string
|
||||||
|
|
||||||
|
switch layout {
|
||||||
|
case "vertical":
|
||||||
|
graph.AddAttr("aptly", "rankdir", "LR")
|
||||||
|
labelStart = ""
|
||||||
|
labelEnd = ""
|
||||||
|
case "horizontal":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
labelStart = "{"
|
||||||
|
labelEnd = "}"
|
||||||
|
}
|
||||||
|
|
||||||
existingNodes := map[string]bool{}
|
existingNodes := map[string]bool{}
|
||||||
|
|
||||||
err = collectionFactory.RemoteRepoCollection().ForEach(func(repo *RemoteRepo) error {
|
err = collectionFactory.RemoteRepoCollection().ForEach(func(repo *RemoteRepo) error {
|
||||||
@@ -26,9 +42,9 @@ func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, err
|
|||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "darkgoldenrod1",
|
"fillcolor": "darkgoldenrod1",
|
||||||
"label": fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}",
|
"label": fmt.Sprintf("%sMirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d%s", labelStart, repo.Name, repo.ArchiveRoot,
|
||||||
repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "),
|
repo.Distribution, strings.Join(repo.Components, ", "),
|
||||||
strings.Join(repo.Architectures, ", "), repo.NumPackages()),
|
strings.Join(repo.Architectures, ", "), repo.NumPackages(), labelEnd),
|
||||||
})
|
})
|
||||||
existingNodes[repo.UUID] = true
|
existingNodes[repo.UUID] = true
|
||||||
return nil
|
return nil
|
||||||
@@ -48,8 +64,8 @@ func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, err
|
|||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "mediumseagreen",
|
"fillcolor": "mediumseagreen",
|
||||||
"label": fmt.Sprintf("{Repo %s|comment: %s|pkgs: %d}",
|
"label": fmt.Sprintf("%sRepo %s|comment: %s|pkgs: %d%s", labelStart,
|
||||||
repo.Name, repo.Comment, repo.NumPackages()),
|
repo.Name, repo.Comment, repo.NumPackages(), labelEnd),
|
||||||
})
|
})
|
||||||
existingNodes[repo.UUID] = true
|
existingNodes[repo.UUID] = true
|
||||||
return nil
|
return nil
|
||||||
@@ -79,7 +95,8 @@ func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, err
|
|||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "cadetblue1",
|
"fillcolor": "cadetblue1",
|
||||||
"label": fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages()),
|
"label": fmt.Sprintf("%sSnapshot %s|%s|pkgs: %d%s", labelStart,
|
||||||
|
snapshot.Name, description, snapshot.NumPackages(), labelEnd),
|
||||||
})
|
})
|
||||||
|
|
||||||
if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" {
|
if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" {
|
||||||
@@ -102,8 +119,9 @@ func BuildGraph(collectionFactory *CollectionFactory) (gographviz.Interface, err
|
|||||||
"shape": "Mrecord",
|
"shape": "Mrecord",
|
||||||
"style": "filled",
|
"style": "filled",
|
||||||
"fillcolor": "darkolivegreen1",
|
"fillcolor": "darkolivegreen1",
|
||||||
"label": fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution,
|
"label": fmt.Sprintf("%sPublished %s/%s|comp: %s|arch: %s%s", labelStart,
|
||||||
strings.Join(repo.Components(), " "), strings.Join(repo.Architectures, ", ")),
|
repo.Prefix, repo.Distribution, strings.Join(repo.Components(), " "),
|
||||||
|
strings.Join(repo.Architectures, ", "), labelEnd),
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, uuid := range repo.Sources {
|
for _, uuid := range repo.Sources {
|
||||||
|
|||||||
+3
-2
@@ -1,12 +1,13 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CollectPackageFiles walks filesystem collecting all candidates for package files
|
// CollectPackageFiles walks filesystem collecting all candidates for package files
|
||||||
|
|||||||
+4
-3
@@ -3,11 +3,12 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type indexFiles struct {
|
type indexFiles struct {
|
||||||
@@ -62,7 +63,7 @@ func (file *indexFile) Finalize(signer utils.Signer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if file.compressable {
|
if file.compressable {
|
||||||
err = utils.CompressFile(file.tempFile)
|
err = utils.CompressFile(file.tempFile, file.onlyGzip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
file.tempFile.Close()
|
file.tempFile.Close()
|
||||||
return fmt.Errorf("unable to compress index file: %s", err)
|
return fmt.Errorf("unable to compress index file: %s", err)
|
||||||
|
|||||||
+4
-2
@@ -2,9 +2,10 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dependency options
|
// Dependency options
|
||||||
@@ -66,6 +67,7 @@ func NewPackageList() *PackageList {
|
|||||||
return NewPackageListWithDuplicates(false, 1000)
|
return NewPackageListWithDuplicates(false, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPackageListWithDuplicates creates empty package list which might allow or block duplicate packages
|
||||||
func NewPackageListWithDuplicates(duplicates bool, capacity int) *PackageList {
|
func NewPackageListWithDuplicates(duplicates bool, capacity int) *PackageList {
|
||||||
if capacity == 0 {
|
if capacity == 0 {
|
||||||
capacity = 1000
|
capacity = 1000
|
||||||
@@ -247,7 +249,7 @@ func (l *PackageList) Strings() []string {
|
|||||||
|
|
||||||
for _, p := range l.packages {
|
for _, p := range l.packages {
|
||||||
result[i] = string(p.Key(""))
|
result[i] = string(p.Key(""))
|
||||||
i += 1
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
+3
-2
@@ -3,11 +3,12 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/go-uuid/uuid"
|
"github.com/smira/go-uuid/uuid"
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
"log"
|
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LocalRepo is a collection of packages created locally
|
// LocalRepo is a collection of packages created locally
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
|
|||||||
+4
-3
@@ -3,11 +3,12 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package is single instance of Debian package
|
// Package is single instance of Debian package
|
||||||
@@ -317,7 +318,7 @@ func (p *Package) GetArchitecture() string {
|
|||||||
return p.Architecture
|
return p.Architecture
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDependencies compiles list of dependenices by flags from options
|
// GetDependencies compiles list of dependncies by flags from options
|
||||||
func (p *Package) GetDependencies(options int) (dependencies []string) {
|
func (p *Package) GetDependencies(options int) (dependencies []string) {
|
||||||
deps := p.Deps()
|
deps := p.Deps()
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageCollection does management of packages in DB
|
// PackageCollection does management of packages in DB
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ func (s *PackageCollectionSuite) TestByKey(c *C) {
|
|||||||
c.Check(p2.Files()[0].Filename, Equals, "alien-arena-common_7.40-2_i386.deb")
|
c.Check(p2.Files()[0].Filename, Equals, "alien-arena-common_7.40-2_i386.deb")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageCollectionSuite) TestByKeyOld_0_3(c *C) {
|
func (s *PackageCollectionSuite) TestByKeyOld0_3(c *C) {
|
||||||
key := []byte("Pi386 vmware-view-open-client 4.5.0-297975+dfsg-4+b1")
|
key := []byte("Pi386 vmware-view-open-client 4.5.0-297975+dfsg-4+b1")
|
||||||
s.db.Put(key, old_0_3_Package)
|
s.db.Put(key, old0_3Package)
|
||||||
|
|
||||||
p, err := s.collection.ByKey(key)
|
p, err := s.collection.ByKey(key)
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
@@ -133,7 +133,7 @@ func (s *PackageCollectionSuite) TestDeleteByKey(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is old package (pre-0.4) that would habe to be converted
|
// This is old package (pre-0.4) that would habe to be converted
|
||||||
var old_0_3_Package = []byte{0x8f, 0xac, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0xa4, 0x69, 0x33, 0x38, 0x36,
|
var old0_3Package = []byte{0x8f, 0xac, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0xa4, 0x69, 0x33, 0x38, 0x36,
|
||||||
0xac, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0xc0, 0xb1, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65,
|
0xac, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0xc0, 0xb1, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x65,
|
||||||
0x70, 0x65, 0x6e, 0x64, 0x73, 0x49, 0x6e, 0x44, 0x65, 0x70, 0xc0, 0xa7, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0xdc, 0x0, 0x12,
|
0x70, 0x65, 0x6e, 0x64, 0x73, 0x49, 0x6e, 0x44, 0x65, 0x70, 0xc0, 0xa7, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x73, 0xdc, 0x0, 0x12,
|
||||||
0xb7, 0x6c, 0x69, 0x62, 0x61, 0x74, 0x6b, 0x31, 0x2e, 0x30, 0x2d, 0x30, 0x20, 0x28, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x32, 0x2e,
|
0xb7, 0x6c, 0x69, 0x62, 0x61, 0x74, 0x6b, 0x31, 0x2e, 0x30, 0x2d, 0x30, 0x20, 0x28, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x32, 0x2e,
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageFile is a single file entry in package
|
// PackageFile is a single file entry in package
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package deb
|
package deb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/smira/aptly/files"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/files"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -2,12 +2,13 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/smira/aptly/files"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/files"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -2,10 +2,11 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ppaRegexp = regexp.MustCompile("^ppa:([^/]+)/(.+)$")
|
var ppaRegexp = regexp.MustCompile("^ppa:([^/]+)/(.+)$")
|
||||||
|
|||||||
+35
-10
@@ -5,11 +5,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/database"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"github.com/smira/go-uuid/uuid"
|
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -18,6 +13,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/smira/go-uuid/uuid"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/database"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type repoSourceItem struct {
|
type repoSourceItem struct {
|
||||||
@@ -49,7 +51,7 @@ type PublishedRepo struct {
|
|||||||
// Map of sources by each component: component name -> source UUID
|
// Map of sources by each component: component name -> source UUID
|
||||||
Sources map[string]string
|
Sources map[string]string
|
||||||
|
|
||||||
// Legacy fields for compatibily with old published repositories (< 0.6)
|
// Legacy fields for compatibility with old published repositories (< 0.6)
|
||||||
Component string
|
Component string
|
||||||
// SourceUUID is UUID of either snapshot or local repo
|
// SourceUUID is UUID of either snapshot or local repo
|
||||||
SourceUUID string `codec:"SnapshotUUID"`
|
SourceUUID string `codec:"SnapshotUUID"`
|
||||||
@@ -467,6 +469,22 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tempDB, err := collectionFactory.TemporaryDB()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
var e error
|
||||||
|
e = tempDB.Close()
|
||||||
|
if e != nil && progress != nil {
|
||||||
|
progress.Printf("failed to close temp DB: %s", err)
|
||||||
|
}
|
||||||
|
e = tempDB.Drop()
|
||||||
|
if e != nil && progress != nil {
|
||||||
|
progress.Printf("failed to drop temp DB: %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if progress != nil {
|
if progress != nil {
|
||||||
progress.Printf("Loading packages...\n")
|
progress.Printf("Loading packages...\n")
|
||||||
}
|
}
|
||||||
@@ -561,7 +579,7 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP
|
|||||||
contentIndex := contentIndexes[key]
|
contentIndex := contentIndexes[key]
|
||||||
|
|
||||||
if contentIndex == nil {
|
if contentIndex == nil {
|
||||||
contentIndex = NewContentsIndex()
|
contentIndex = NewContentsIndex(tempDB)
|
||||||
contentIndexes[key] = contentIndex
|
contentIndexes[key] = contentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +695,14 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP
|
|||||||
|
|
||||||
release["Components"] = strings.Join(p.Components(), " ")
|
release["Components"] = strings.Join(p.Components(), " ")
|
||||||
|
|
||||||
for path, info := range indexes.generatedFiles {
|
sortedPaths := make([]string, 0, len(indexes.generatedFiles))
|
||||||
|
for path := range indexes.generatedFiles {
|
||||||
|
sortedPaths = append(sortedPaths, path)
|
||||||
|
}
|
||||||
|
sort.Strings(sortedPaths)
|
||||||
|
|
||||||
|
for _, path := range sortedPaths {
|
||||||
|
info := indexes.generatedFiles[path]
|
||||||
release["MD5Sum"] += fmt.Sprintf(" %s %8d %s\n", info.MD5, info.Size, path)
|
release["MD5Sum"] += fmt.Sprintf(" %s %8d %s\n", info.MD5, info.Size, path)
|
||||||
release["SHA1"] += fmt.Sprintf(" %s %8d %s\n", info.SHA1, info.Size, path)
|
release["SHA1"] += fmt.Sprintf(" %s %8d %s\n", info.SHA1, info.Size, path)
|
||||||
release["SHA256"] += fmt.Sprintf(" %s %8d %s\n", info.SHA256, info.Size, path)
|
release["SHA256"] += fmt.Sprintf(" %s %8d %s\n", info.SHA256, info.Size, path)
|
||||||
@@ -905,7 +930,7 @@ func (collection *PublishedRepoCollection) ByUUID(uuid string) (*PublishedRepo,
|
|||||||
|
|
||||||
// BySnapshot looks up repository by snapshot source
|
// BySnapshot looks up repository by snapshot source
|
||||||
func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*PublishedRepo {
|
func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*PublishedRepo {
|
||||||
result := make([]*PublishedRepo, 0)
|
var result []*PublishedRepo
|
||||||
for _, r := range collection.list {
|
for _, r := range collection.list {
|
||||||
if r.SourceKind == "snapshot" {
|
if r.SourceKind == "snapshot" {
|
||||||
if r.SourceUUID == snapshot.UUID {
|
if r.SourceUUID == snapshot.UUID {
|
||||||
@@ -925,7 +950,7 @@ func (collection *PublishedRepoCollection) BySnapshot(snapshot *Snapshot) []*Pub
|
|||||||
|
|
||||||
// ByLocalRepo looks up repository by local repo source
|
// ByLocalRepo looks up repository by local repo source
|
||||||
func (collection *PublishedRepoCollection) ByLocalRepo(repo *LocalRepo) []*PublishedRepo {
|
func (collection *PublishedRepoCollection) ByLocalRepo(repo *LocalRepo) []*PublishedRepo {
|
||||||
result := make([]*PublishedRepo, 0)
|
var result []*PublishedRepo
|
||||||
for _, r := range collection.list {
|
for _, r := range collection.list {
|
||||||
if r.SourceKind == "local" {
|
if r.SourceKind == "local" {
|
||||||
if r.SourceUUID == repo.UUID {
|
if r.SourceUUID == repo.UUID {
|
||||||
|
|||||||
+4
-3
@@ -4,13 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/aptly/files"
|
"github.com/smira/aptly/files"
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ type DependencyQuery struct {
|
|||||||
Dep Dependency
|
Dep Dependency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchAllQuery is query that matches all the packages
|
||||||
|
type MatchAllQuery struct{}
|
||||||
|
|
||||||
// Matches if any of L, R matches
|
// Matches if any of L, R matches
|
||||||
func (q *OrQuery) Matches(pkg PackageLike) bool {
|
func (q *OrQuery) Matches(pkg PackageLike) bool {
|
||||||
return q.L.Matches(pkg) || q.R.Matches(pkg)
|
return q.L.Matches(pkg) || q.R.Matches(pkg)
|
||||||
@@ -275,3 +278,23 @@ func (q *PkgQuery) Query(list PackageCatalog) (result *PackageList) {
|
|||||||
func (q *PkgQuery) String() string {
|
func (q *PkgQuery) String() string {
|
||||||
return fmt.Sprintf("%s_%s_%s", q.Pkg, q.Version, q.Arch)
|
return fmt.Sprintf("%s_%s_%s", q.Pkg, q.Version, q.Arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Matches on specific properties
|
||||||
|
func (q *MatchAllQuery) Matches(pkg PackageLike) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast is always true for match all query
|
||||||
|
func (q *MatchAllQuery) Fast(list PackageCatalog) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query looks up specific package
|
||||||
|
func (q *MatchAllQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
|
return list.Scan(q)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String interface
|
||||||
|
func (q *MatchAllQuery) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
+7
-6
@@ -3,9 +3,10 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/AlekSi/pointer"
|
"github.com/AlekSi/pointer"
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageRefList is a list of keys of packages, this is basis for snapshot
|
// PackageRefList is a list of keys of packages, this is basis for snapshot
|
||||||
@@ -109,8 +110,8 @@ func (l *PackageRefList) Strings() []string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substract returns all packages in l that are not in r
|
// Subtract returns all packages in l that are not in r
|
||||||
func (l *PackageRefList) Substract(r *PackageRefList) *PackageRefList {
|
func (l *PackageRefList) Subtract(r *PackageRefList) *PackageRefList {
|
||||||
result := &PackageRefList{Refs: make([][]byte, 0, 128)}
|
result := &PackageRefList{Refs: make([][]byte, 0, 128)}
|
||||||
|
|
||||||
// pointer to left and right reflists
|
// pointer to left and right reflists
|
||||||
@@ -270,7 +271,7 @@ func (l *PackageRefList) Diff(r *PackageRefList, packageCollection *PackageColle
|
|||||||
|
|
||||||
// Merge merges reflist r into current reflist. If overrideMatching, merge
|
// Merge merges reflist r into current reflist. If overrideMatching, merge
|
||||||
// replaces matching packages (by architecture/name) with reference from r.
|
// replaces matching packages (by architecture/name) with reference from r.
|
||||||
// If ignoreConflicting is set, all packages are preserved, otherwise conflciting
|
// If ignoreConflicting is set, all packages are preserved, otherwise conflicting
|
||||||
// packages are overwritten with packages from "right" snapshot.
|
// packages are overwritten with packages from "right" snapshot.
|
||||||
func (l *PackageRefList) Merge(r *PackageRefList, overrideMatching, ignoreConflicting bool) (result *PackageRefList) {
|
func (l *PackageRefList) Merge(r *PackageRefList, overrideMatching, ignoreConflicting bool) (result *PackageRefList) {
|
||||||
var overriddenArch, overridenName []byte
|
var overriddenArch, overridenName []byte
|
||||||
@@ -327,7 +328,7 @@ func (l *PackageRefList) Merge(r *PackageRefList, overrideMatching, ignoreConfli
|
|||||||
|
|
||||||
if overrideMatching {
|
if overrideMatching {
|
||||||
if bytes.Equal(archL, overriddenArch) && bytes.Equal(nameL, overridenName) {
|
if bytes.Equal(archL, overriddenArch) && bytes.Equal(nameL, overridenName) {
|
||||||
// this package has already been overriden on the right
|
// this package has already been overridden on the right
|
||||||
il++
|
il++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -389,7 +390,7 @@ func (l *PackageRefList) FilterLatestRefs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compensate for the reduced set
|
// Compensate for the reduced set
|
||||||
i -= 1
|
i--
|
||||||
}
|
}
|
||||||
|
|
||||||
lastArch, lastName, lastVer = arch, name, ver
|
lastArch, lastName, lastVer = arch, name, ver
|
||||||
|
|||||||
+7
-6
@@ -2,6 +2,7 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
@@ -156,12 +157,12 @@ func (s *PackageRefListSuite) TestSubstract(c *C) {
|
|||||||
l4 := &PackageRefList{Refs: [][]byte{r4, r5}}
|
l4 := &PackageRefList{Refs: [][]byte{r4, r5}}
|
||||||
l5 := &PackageRefList{Refs: [][]byte{r1, r2, r3}}
|
l5 := &PackageRefList{Refs: [][]byte{r1, r2, r3}}
|
||||||
|
|
||||||
c.Check(l1.Substract(empty), DeepEquals, l1)
|
c.Check(l1.Subtract(empty), DeepEquals, l1)
|
||||||
c.Check(l1.Substract(l2), DeepEquals, l3)
|
c.Check(l1.Subtract(l2), DeepEquals, l3)
|
||||||
c.Check(l1.Substract(l3), DeepEquals, l2)
|
c.Check(l1.Subtract(l3), DeepEquals, l2)
|
||||||
c.Check(l1.Substract(l4), DeepEquals, l5)
|
c.Check(l1.Subtract(l4), DeepEquals, l5)
|
||||||
c.Check(empty.Substract(l1), DeepEquals, empty)
|
c.Check(empty.Subtract(l1), DeepEquals, empty)
|
||||||
c.Check(l2.Substract(l3), DeepEquals, l2)
|
c.Check(l2.Subtract(l3), DeepEquals, l2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PackageRefListSuite) TestDiff(c *C) {
|
func (s *PackageRefListSuite) TestDiff(c *C) {
|
||||||
|
|||||||
+13
-10
@@ -3,12 +3,6 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/aptly"
|
|
||||||
"github.com/smira/aptly/database"
|
|
||||||
"github.com/smira/aptly/http"
|
|
||||||
"github.com/smira/aptly/utils"
|
|
||||||
"github.com/smira/go-uuid/uuid"
|
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -20,6 +14,13 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/smira/aptly/aptly"
|
||||||
|
"github.com/smira/aptly/database"
|
||||||
|
"github.com/smira/aptly/http"
|
||||||
|
"github.com/smira/aptly/utils"
|
||||||
|
"github.com/smira/go-uuid/uuid"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RemoteRepo statuses
|
// RemoteRepo statuses
|
||||||
@@ -60,6 +61,8 @@ type RemoteRepo struct {
|
|||||||
FilterWithDeps bool
|
FilterWithDeps bool
|
||||||
// SkipComponentCheck skips component list verification
|
// SkipComponentCheck skips component list verification
|
||||||
SkipComponentCheck bool
|
SkipComponentCheck bool
|
||||||
|
// SkipArchitectureCheck skips architecture list verification
|
||||||
|
SkipArchitectureCheck bool
|
||||||
// Status marks state of repository (being updated, no action)
|
// Status marks state of repository (being updated, no action)
|
||||||
Status int
|
Status int
|
||||||
// WorkerPID is PID of the process modifying the mirror (if any)
|
// WorkerPID is PID of the process modifying the mirror (if any)
|
||||||
@@ -316,9 +319,9 @@ ok:
|
|||||||
architectures = utils.StrSlicesSubstract(architectures, []string{"source"})
|
architectures = utils.StrSlicesSubstract(architectures, []string{"source"})
|
||||||
if len(repo.Architectures) == 0 {
|
if len(repo.Architectures) == 0 {
|
||||||
repo.Architectures = architectures
|
repo.Architectures = architectures
|
||||||
} else {
|
} else if !repo.SkipArchitectureCheck {
|
||||||
err = utils.StringsIsSubset(repo.Architectures, architectures,
|
err = utils.StringsIsSubset(repo.Architectures, architectures,
|
||||||
fmt.Sprintf("architecture %%s not available in repo %s", repo))
|
fmt.Sprintf("architecture %%s not available in repo %s, use -force-architectures to override", repo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -401,7 +404,7 @@ ok:
|
|||||||
|
|
||||||
// DownloadPackageIndexes downloads & parses package index files
|
// DownloadPackageIndexes downloads & parses package index files
|
||||||
func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.Downloader, collectionFactory *CollectionFactory,
|
func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.Downloader, collectionFactory *CollectionFactory,
|
||||||
ignoreMismatch bool) error {
|
ignoreMismatch bool, maxTries int) error {
|
||||||
if repo.packageList != nil {
|
if repo.packageList != nil {
|
||||||
panic("packageList != nil")
|
panic("packageList != nil")
|
||||||
}
|
}
|
||||||
@@ -431,7 +434,7 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.
|
|||||||
|
|
||||||
for _, info := range packagesURLs {
|
for _, info := range packagesURLs {
|
||||||
url, kind := info[0], info[1]
|
url, kind := info[0], info[1]
|
||||||
packagesReader, packagesFile, err := http.DownloadTryCompression(d, url, repo.ReleaseFiles, ignoreMismatch)
|
packagesReader, packagesFile, err := http.DownloadTryCompression(d, url, repo.ReleaseFiles, ignoreMismatch, maxTries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-22
@@ -2,16 +2,17 @@ package deb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/smira/aptly/aptly"
|
"github.com/smira/aptly/aptly"
|
||||||
"github.com/smira/aptly/console"
|
"github.com/smira/aptly/console"
|
||||||
"github.com/smira/aptly/database"
|
"github.com/smira/aptly/database"
|
||||||
"github.com/smira/aptly/files"
|
"github.com/smira/aptly/files"
|
||||||
"github.com/smira/aptly/http"
|
"github.com/smira/aptly/http"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
. "gopkg.in/check.v1"
|
. "gopkg.in/check.v1"
|
||||||
)
|
)
|
||||||
@@ -103,7 +104,7 @@ func (s *RemoteRepoSuite) TearDownTest(c *C) {
|
|||||||
|
|
||||||
func (s *RemoteRepoSuite) TestInvalidURL(c *C) {
|
func (s *RemoteRepoSuite) TestInvalidURL(c *C) {
|
||||||
_, err := NewRemoteRepo("s", "http://lolo%2", "squeeze", []string{"main"}, []string{}, false, false)
|
_, err := NewRemoteRepo("s", "http://lolo%2", "squeeze", []string{"main"}, []string{}, false, false)
|
||||||
c.Assert(err, ErrorMatches, ".*(hexadecimal escape|percent-encoded characters) in host.*")
|
c.Assert(err, ErrorMatches, ".*(hexadecimal escape in host|percent-encoded characters in host|invalid URL escape).*")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *RemoteRepoSuite) TestFlatCreation(c *C) {
|
func (s *RemoteRepoSuite) TestFlatCreation(c *C) {
|
||||||
@@ -197,7 +198,7 @@ func (s *RemoteRepoSuite) TestFetch(c *C) {
|
|||||||
|
|
||||||
func (s *RemoteRepoSuite) TestFetchNullVerifier1(c *C) {
|
func (s *RemoteRepoSuite) TestFetchNullVerifier1(c *C) {
|
||||||
downloader := http.NewFakeDownloader()
|
downloader := http.NewFakeDownloader()
|
||||||
downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/InRelease", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/InRelease", &http.Error{Code: 404})
|
||||||
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile)
|
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release", exampleReleaseFile)
|
||||||
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release.gpg", "GPG")
|
downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/Release.gpg", "GPG")
|
||||||
|
|
||||||
@@ -257,11 +258,11 @@ func (s *RemoteRepoSuite) TestDownload(c *C) {
|
|||||||
err := s.repo.Fetch(s.downloader, nil)
|
err := s.repo.Fetch(s.downloader, nil)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.bz2", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.bz2", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.gz", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.gz", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages", examplePackagesFile)
|
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages", examplePackagesFile)
|
||||||
|
|
||||||
err = s.repo.DownloadPackageIndexes(s.progress, s.downloader, s.collectionFactory, false)
|
err = s.repo.DownloadPackageIndexes(s.progress, s.downloader, s.collectionFactory, false, 1)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(s.downloader.Empty(), Equals, true)
|
c.Assert(s.downloader.Empty(), Equals, true)
|
||||||
|
|
||||||
@@ -286,14 +287,14 @@ func (s *RemoteRepoSuite) TestDownloadWithSources(c *C) {
|
|||||||
err := s.repo.Fetch(s.downloader, nil)
|
err := s.repo.Fetch(s.downloader, nil)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.bz2", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.bz2", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.gz", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages.gz", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages", examplePackagesFile)
|
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/binary-i386/Packages", examplePackagesFile)
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources.bz2", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources.bz2", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources.gz", &http.HTTPError{Code: 404})
|
s.downloader.ExpectError("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources.gz", &http.Error{Code: 404})
|
||||||
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources", exampleSourcesFile)
|
s.downloader.ExpectResponse("http://mirror.yandex.ru/debian/dists/squeeze/main/source/Sources", exampleSourcesFile)
|
||||||
|
|
||||||
err = s.repo.DownloadPackageIndexes(s.progress, s.downloader, s.collectionFactory, false)
|
err = s.repo.DownloadPackageIndexes(s.progress, s.downloader, s.collectionFactory, false, 1)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(s.downloader.Empty(), Equals, true)
|
c.Assert(s.downloader.Empty(), Equals, true)
|
||||||
|
|
||||||
@@ -327,14 +328,15 @@ func (s *RemoteRepoSuite) TestDownloadWithSources(c *C) {
|
|||||||
func (s *RemoteRepoSuite) TestDownloadFlat(c *C) {
|
func (s *RemoteRepoSuite) TestDownloadFlat(c *C) {
|
||||||
downloader := http.NewFakeDownloader()
|
downloader := http.NewFakeDownloader()
|
||||||
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Release", exampleReleaseFile)
|
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Release", exampleReleaseFile)
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.bz2", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.bz2", &http.Error{Code: 404})
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.gz", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.gz", &http.Error{Code: 404})
|
||||||
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.xz", &http.Error{Code: 404})
|
||||||
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Packages", examplePackagesFile)
|
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Packages", examplePackagesFile)
|
||||||
|
|
||||||
err := s.flat.Fetch(downloader, nil)
|
err := s.flat.Fetch(downloader, nil)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true)
|
err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true, 1)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(downloader.Empty(), Equals, true)
|
c.Assert(downloader.Empty(), Equals, true)
|
||||||
|
|
||||||
@@ -357,17 +359,19 @@ func (s *RemoteRepoSuite) TestDownloadWithSourcesFlat(c *C) {
|
|||||||
|
|
||||||
downloader := http.NewFakeDownloader()
|
downloader := http.NewFakeDownloader()
|
||||||
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Release", exampleReleaseFile)
|
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Release", exampleReleaseFile)
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.bz2", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.bz2", &http.Error{Code: 404})
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.gz", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.gz", &http.Error{Code: 404})
|
||||||
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Packages.xz", &http.Error{Code: 404})
|
||||||
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Packages", examplePackagesFile)
|
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Packages", examplePackagesFile)
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Sources.bz2", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Sources.bz2", &http.Error{Code: 404})
|
||||||
downloader.ExpectError("http://repos.express42.com/virool/precise/Sources.gz", &http.HTTPError{Code: 404})
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Sources.gz", &http.Error{Code: 404})
|
||||||
|
downloader.ExpectError("http://repos.express42.com/virool/precise/Sources.xz", &http.Error{Code: 404})
|
||||||
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Sources", exampleSourcesFile)
|
downloader.ExpectResponse("http://repos.express42.com/virool/precise/Sources", exampleSourcesFile)
|
||||||
|
|
||||||
err := s.flat.Fetch(downloader, nil)
|
err := s.flat.Fetch(downloader, nil)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true)
|
err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true, 1)
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
c.Assert(downloader.Empty(), Equals, true)
|
c.Assert(downloader.Empty(), Equals, true)
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user