A while ago Rohan Garg suggested we should use Aptly, a relatively new repository management system written in Go featuring advanced features such as repository mirroring, publishing to Amazon S3 and a REST API. Since I do like me some REST APIs I was quickly sold on the idea of adopting it as our primary repository system.
Alas, most of our CI rigging is written in Ruby and there was no usable API gem in sight.
Low and behold: I wrote a Ruby gem for Aptly’s REST API. It’s called aptly-api.
It covers all the common repository usage from creating repositories and adding files, to publishing repositories to a publishing location. Let’s look at some code.
For example here we create a repository and publish it as public-name.
require 'aptly' Aptly.configure do |config| config.host = 'localhost' config.port = 8080 end repo = Aptly::Repository.create('kewl-new-repo') repo.publish('public-name', Distribution: 'wily', Architectures: %w(amd64 i386))
Aptly has two notions of a repository. There is a repository and then there is a published repository. A published repository essentially is an on-disk representation of a repository, namely what you would actually find on any deb repository like archive.ubuntu.com. These published repositories have one (or more!) repositories associated with it. All packages in that repository will be part of the published repository. This allows you to have neat repository sets where internally you have packages separate in multiple repositories but publicly they show up in the same published repository tree. For instance you could have a repository for qt and a repository for kde-frameworks, but publicly your deb repository would contain both qt’s and kde-frameworks’ packages.
Let’s add a deb to our repository…
repo = Aptly::Repository.get('kewl-new-repo') repo.upload('kitteh.deb')
At this point kitteh will not actually show up in the published directory, we first have to update it. In fact, let’s update all published repositories our repository is part of, chances are we want all to refresh anyway.
Bonus: Secure Remote
Aptly presently doesn’t support API authentication, so you’d rightfully wonder how exactly we secure the beast. Surely we aren’t publicly binding the API server for all the world to abuse.
The solution, as so often in life, is of course SSH. Namely if you want to use the API on a remote you could simply tunnel the relevant port to your localhost.
require 'aptly' require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new('hostname', 'username') port = gateway.open('localhost', 8080, 8080) Aptly.configure do |config| config.host = 'localhost' config.port = port end