There was an interesting question by Fool recently on the StackExchange site for Boardgames: How do you play a game like Rock-Paper-Scissors with friends online? Or any other game where players have to simultaneously submit their moves (e.g. Diplomacy, or Rock-Paper-Scissors-Lizzard-Spock), which, as I just learned, are simultaneous action selection games. While there are websites dedicated to playing specific games, such as webdiplomacy.net, we could not find a generic one that you can use if you, for example, invent your own variants of a game.| Week | Squeeze | Wheezy | Diff |
|---|---|---|---|
| 43 | 284 (213+71) | 468 (332+136) | +184 (+119/+65) |
| 44 | 261 (201+60) | 408 (265+143) | +147 (+64/+83) |
| 45 | 261 (205+56) | 425 (291+134) | +164 (+86/+78) |
| 46 | 271 (200+71) | 401 (258+143) | +130 (+58/+72) |
| 47 | 283 (209+74) | 366 (221+145) | +83 (+12/+71) |
| 48 | 256 (177+79) | 378 (230+148) | +122 (+53/+69) |
| 49 | 256 (180+76) | 360 (216+155) | +104 (+36/+79) |
| 50 | 204 (148+56) | 339 (195+144) | +135 (+47/+90) |
| 51 | 178 (124+54) | 323 (190+133) | +145 (+66/+79) |
| 52 | 115 (78+37) | 289 (190+99) | +174 (+112/+62) |
| 1 | 93 (60+33) | 287 (171+116) | +194 (+111/+83) |
| 2 | 82 (46+36) | 271 (162+109) | +189 (+116/+73) |
| 3 | 25 (15+10) | 249 (165+84) | +224 (+150/+74) |
| 4 | 14 (8+6) | 244 (176+68) | +230 (+168/+62) |
| 5 | 2 (0+2) | 224 (132+92) | +222 (+132/+90) |
| 6 | release! | 212 (129+83) | +212 (+129/+83) |
| 7 | release+1 | 194 (128+66) | +194 (+128/+66) |
| 8 | release+2 | 206 (144+62) | +206 (+144/+62) |
| 9 | release+3 | 174 (105+69) | +174 (+105/+69) |
| 10 | release+4 | 120 (72+48) | +120 (+72/+48) |
| 11 | release+5 | 115 (74+41) | +115 (+74/+41) |
| 12 | release+6 | 93 (47+46) | +93 (+47/+46) |
| 13 | release+7 | 50 (24+26) | +50 (+24/+26) |
| 14 | release+8 | 51 (32+19) | +51 (+32/+19) |
| 15 | release+9 | 39 (32+7) | +39 (+32/+7) |
| 16 | release+10 | 20 (12+8) | +20 (+12/+8) |
| 17 | release+11 | 24 (19+5) | +24 (+19/+5) |
| 18 | release+12 | 2 (2+0) | +2 (+2/+0) |
This post was written with Andr s Monroy-Hern ndez. It is a summary of a paper just published in American Behavioral Scientist. You can also read the full paper: The remixing dilemma: The trade-off between generativity and originality. It is part of a series of papers I have written with Monroy-Hern ndez using data from Scratch. You can find the others on my academic website.Remixing the reworking and recombination of existing creative artifacts represents a widespread, important, and controversial form of social creativity online. Proponents of remix culture often speak of remixing in terms of rich ecosystems where creative works are novel and highly generative. However, examples like this can be difficult to find. Although there is a steady stream of media being shared freely on the web, only a tiny fraction of these projects are remixed even once. On top of this, many remixes are not very different from the works they are built upon. Why is some content more attractive to remixers? Why are some projects remixed in deeper and more transformative ways?


Two plots of estimated values for prototypical projects. Panel 1 (left) displays predicted probabilities of being remixed. Panel 2 (right) displays predicted edit distances. Both panels show predicted values for both remixes and de novo projects from 0 to 1,204 blocks (99th percentile).
With wheezy released, the floodgates are opened on a lot of debhelper
changes that have been piling up. Most of these should be pretty minor, but
I released one yesterday that will affect all users of dh. Hopefully in a
good way.
I made dh smarter about selecting which debhelper commands it runs.
It can tell when a package does not use the stuff done by a particular
command, and skips running the command entirely.
So the debian/rules binary of a package using dh
will now often look like this:
dh binary dh_testroot dh_prep dh_auto_install dh_installdocs dh_installchangelogs dh_perl dh_link dh_compress dh_fixperms dh_installdeb dh_gencontrol dh_md5sums dh_builddebWhich is pretty close to the optimal hand-crafted
debian/rules file (and just
about as fast, too). But with the benefit that if you later add, say, cron job
files, dh_installcron will automatically start being run too.
Hopefully this will not result in any behavior changes, other than packages
building faster and with less noise. If there is a bug it'll probably
be something missing in the specification of when a command needs to be run.
Beyond speed, I hope that this will help to lower the bar to adding new
commands to debhelper, and to the default dh sequences. Before, every such
new command slowed things down and was annoying. Now more special-purpose
commands won't get in the way of packages that don't need them.
dh_installexamples
# PROMISE: DH NOOP WITHOUT examples
Mostly this specifies the files in debian/ that are used by the command, and
whose presence triggers the command to run. There is also a syntax to specify
items that can be present in the package build directory to trigger the command
to run.
(Unfortunatly, dh_perl can't use this. There's no good way to specify
when dh_perl needs to run, short of doing nearly as much work as dh_perl
would do when run. Oh well.)
Note that third-party dh_ commands can include these directives too, if that
makes sense.
$behavior = main_behavior("docs tmp(usr/share/doc/)", sub
my $package=shift;
my $docs=shift;
my $docdir=shift;
install($docs, $docdir);
);
$behavior->($package);
Debhelper a monad, within which each command
executes.
main = runDebhelperIO installDocs
installDocs :: Monad a => Debhelper a
installDocs = do
docs <- configFile "docs"
docdir <- tmpDir "usr/share/doc"
lift $ install docs docdir
runDebhelperIO would loop over all the packages
and run the action, in the Debhelper IO monad.
But, this also allows making an examineDebhelper that takes an action
like installDocs, and runs it in a Debhelper Writer monad. That would
accumulate a list of all the inputs used by the action, and return it,
without performing any side effecting IO actions.
It's been 15 years since I last changed the language debhelper was written
in. I did that for less gains than this, really. (The issue back then was
that shell getopt sucked.) IIRC it was not very hard, and only took a few
days. Still, I don't really anticipate reimplementing debhelper in Haskell
any time soon.
For one thing, individual Haskell binaries are quite large, statically
linking all Haskell libraries they use, and so the installed size of
debhelper would go up quite a bit. I hope that forthcoming changes will
move things toward dynamically linked haskell libraries, and make it more
appealing for projects that involve a lot of small commands.
So, just a thought experiment for now..
I've been working on TPMs lately. It turns out that they're moderately awful, but what's significantly more awful is basically all the existing documentation. So here's some of what I've learned, presented in the hope that it saves someone else some amount of misery.
Ordinarily, I m a big believer that it is important to keep up to date with what every piece of software which competes with yours is doing, to remain educated on the latest concepts. Sometimes, there are concepts that get added which are definitely worth ripping off. We ve ripped off plenty of the better design choices from Windows or Mac OS, over the years, for use in the Free Desktop.
So, what about Windows 8, the hip new OS on everyone s lips?
Well, here s the thing I ve been using it on and off for a few months now for running legacy apps, and I can t for the life of me find anything worth stealing.
Let s take the key change Windows 8 has apps built with a new design paradigm which definitely isn t called Metro. Metro apps don t really have windows in the traditional sense they re more modeled on full-screen apps from smartphones or tablets than on Windows 1.0 -> 7. Which is fine, really, if you re running Windows 8 on a tablet or touchscreen device. But what if you re not? What about the normal PC user?
As Microsoft themselves ask:
The answer to that is, well, you sorta don t.
Metro apps can exist in three states fullscreen, almost fullscreen, or vertical stripe. You re allowed to have two apps at most at the same time one mostly full screen, and one vertical stripe. So what happens if you try to *use* that? Let s take a fairly common thing I do watch a video and play Minesweeper. In this example, the video player is the current replacement for Windows Media Player, and ships by default. The Minesweeper game isn t installed by default, but is the only Minesweeper game in the Windows 8 app store which is gratis and by Microsoft Game Studios.
Here s option A:
And for contrast, here s option B:
Which of these does a better job of letting me play Minesweeper and watch a video at the same time?
Oh, here s option C, dumping Microsoft s own software, and using a third-party video player and third party Minesweeper implementation:
It s magical almost as if picking my own window sizes makes the experience better.
So, as you can see above, the old OS is still hiding there, in the form of a Windows 8 app called Desktop . Oh, sorry, didn t I say? Metro apps, and non-Metro apps, are segregated. You can run both (the Desktop app can also be almost-fullscreen or a vertical strip), but they get their own lists of apps when multitasking. Compare the list on the left with the list at the bottom:
And it s even more fun for apps like Internet Explorer, which can be started in both modes (and you often need both modes). Oh, and notice how the Ribbon interface from Office 2007 has invaded Explorer, filling the view with large buttons to do things you never want to do under normal circumstances.
So, that s a short primer on why Windows 8 is terrible.
Is there really nothing here worth stealing? Actually, yes, there is! After much research, I have discovered Windows 8 s shining jewel:
The new Task Manager is lovely. I want it on my Linux systems. But that s it.
And an example of package failing:
At time of writing, most of the packages in unstable have been rebuilt (16 % are remaining). However, due to resource constraints, only amd64 packages are built. Contact me if you have resources to share for other architectures.
Thanks to Paul Wise, the PTS (Debian package tracking system) proposes a link to the clang build logs (failing or not).
A repository will be automatically updated with the results of these builds (once I find the time to get into buildd).
2) clang-built repositorydeb http://clang.debian.net/repository-2013-04-07/ unstable-clang mainThis allows some cool stuff like:
$ echo "deb http://clang.debian.net/repository-2013-04-07/ unstable-clang main">>/etc/apt/sources.list $ apt-get update $ apt-get install coreutils/unstable-clang $ ls $ awkNote that this repository was only one-shoot and does not get updated. Quality of the binary produced (performance and size) can be tested thanks to this repository. Feedbacks are welcome!
And an example of package failing:
At time of writing, most of the packages in unstable have been rebuilt (16 % are remaining). However, due to resource constraints, only amd64 packages are built. Contact me if you have resources to share for other architectures.
Thanks to Paul Wise, the PTS (Debian package tracking system) proposes a link to the clang build logs (failing or not).
A repository will be automatically updated with the results of these builds (once I find the time to get into buildd).
2) clang-built repositorydeb http://clang.debian.net/repository-2013-04-07/ unstable-clang mainThis allows some cool stuff like:
$ echo "deb http://clang.debian.net/repository-2013-04-07/ unstable-clang main">>/etc/apt/sources.list $ apt-get update $ apt-get install coreutils/unstable-clang $ ls $ awkNote that this repository was only one-shoot and does not get updated. Quality of the binary produced (performance and size) can be tested thanks to this repository. Feedbacks are welcome!
And an example of package failing:
At time of writing, most of the packages in unstable have been rebuilt (16 % are remaining). However, due to resource constraints, only amd64 packages are built. Contact me if you have resources to share for other architectures.
Thanks to Paul Wise, the PTS (Debian package tracking system) proposes a link to the clang build logs (failing or not).
A repository will be automatically updated with the results of these builds (once I find the time to get into buildd).
2) clang-built repositorydeb http://clang.debian.net/repository-2013-04-07/ unstable-clang mainThis allows some cool stuff like:
$ echo "deb http://clang.debian.net/repository-2013-04-07/ unstable-clang main">>/etc/apt/sources.list $ apt-get update $ apt-get install coreutils/unstable-clang $ ls $ awkNote that this repository was only one-shoot and does not get updated. Quality of the binary produced (performance and size) can be tested thanks to this repository. Feedbacks are welcome!
(It took me a while to come up with new CDBS packaging series post not
because I stopped using CDBS just because I was procrastinating myself
as busy)
This is the second post in the CDBS packaging series. In this series
I'm going to talk about package relationship management.
The better example where this feature is useful is packages where
build-depends and run-time dependencies overlap. Most of the Perl
modules which have test suites have build-depend and run-time
dependency intersection. So let me take example of a Perl module.
First lets see control file of a Perl package which is not using CDBS
and then let me explain how CDBS can help you improve the situation. I
choose libxml-libxml-perl lets see part of control file which includes
Build-Depends Depends Suggests Recommends.
Source: libxml-libxml-perl
Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
Uploaders: Jonathan Yu <jawnsy@cpan.org>,
gregor herrmann <gregoa@debian.org>,
Chris Butler <chrisb@debian.org>
Section: perl
Priority: optional
Build-Depends: perl (>= 5.12),
debhelper (>= 9.20120312),
libtest-pod-perl,
libxml2-dev,
libxml-namespacesupport-perl,
libxml-sax-perl,
zlib1g-dev
Standards-Version: 3.9.4
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-perl/packages/libxml-libxml-perl.git
Vcs-Git: git://anonscm.debian.org/pkg-perl/packages/libxml-libxml-perl.git
Homepage: https://metacpan.org/release/XML-LibXML/
Package: libxml-libxml-perl
Architecture: any
Depends: $ shlibs:Depends , $ misc:Depends , $ perl:Depends ,
libxml-namespacesupport-perl,
libxml-sax-perl
Breaks: libxml-libxml-common-perl
Replaces: libxml-libxml-common-perl
Description: Perl interface to the libxml2 library
XML::LibXML is a Perl interface to the GNOME libxml2 library, which provides
interfaces for parsing and manipulating XML files. This module allows Perl
programmers to make use of the highly capable validating XML parser and the
high performance Document Object Model (DOM) implementation. Additionally, it
supports using the XML Path Language (XPath) to find and extract information.
--- debian/control 2013-04-28 23:08:11.930082600 +0530
+++ debian/control.in 2013-05-04 20:51:18.849680419 +0530
@@ -5,13 +5,7 @@
Chris Butler <chrisb@debian.org>
Section: perl
Priority: optional
-Build-Depends: perl (>= 5.12),
- debhelper (>= 9.20120312),
- libtest-pod-perl,
- libxml2-dev,
- libxml-namespacesupport-perl,
- libxml-sax-perl,
- zlib1g-dev
+Build-Depends: @cdbs@
Standards-Version: 3.9.4
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-perl/packages/libxml-libxml-perl.git
Vcs-Git: git://anonscm.debian.org/pkg-perl/packages/libxml-libxml-perl.git
@@ -20,8 +14,7 @@
Package: libxml-libxml-perl
Architecture: any
Depends: $ shlibs:Depends , $ misc:Depends , $ perl:Depends ,
- libxml-namespacesupport-perl,
- libxml-sax-perl
+ $ cdbs:Depends
Breaks: libxml-libxml-common-perl
Replaces: libxml-libxml-common-perl
Description: Perl interface to the libxml2 library
@@ -30,4 +23,3 @@
programmers to make use of the highly capable validating XML parser and the
high performance Document Object Model (DOM) implementation. Additionally, it
supports using the XML Path Language (XPath) to find and extract information.
-
#!/usr/bin/make -f
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/utils.mk
include /usr/share/cdbs/1/rules/upstream-tarball.mk
include /usr/share/cdbs/1/class/perl-makemaker.mk
pkg = $(DEB_SOURCE_PACKAGE)
deps = libxml-libxml-perl libxml-sax-perl
deps-test = libtest-pod-perl
CDBS_BUILD_DEPENDS +=, $(deps), $(deps-test)
CDBS_BUILD_DEPENDS +=, zlib1g-dev, libxml2-dev, perl (>= 5.12)
CDBS_DEPENDS_$(pkg) = , $(deps)
DEB_MAINTAINER_MODE=1 fakeroot debian/rules debian/control
NMUs need not (but are encouraged to) make special use of these tools. In particular, the debian/control.in file can be completely ignored.Before closing down the post, If you find some mistake in the post please let me know either through comments or through the email. Soon I will be back with new CDBS recipes till then cya.
| Publisher: | Haymarket |
| Copyright: | 2012 |
| ISBN: | 1-60846-247-1 |
| Format: | Kindle |
| Pages: | 220 |
| Week | Squeeze | Wheezy | Diff |
|---|---|---|---|
| 43 | 284 (213+71) | 468 (332+136) | +184 (+119/+65) |
| 44 | 261 (201+60) | 408 (265+143) | +147 (+64/+83) |
| 45 | 261 (205+56) | 425 (291+134) | +164 (+86/+78) |
| 46 | 271 (200+71) | 401 (258+143) | +130 (+58/+72) |
| 47 | 283 (209+74) | 366 (221+145) | +83 (+12/+71) |
| 48 | 256 (177+79) | 378 (230+148) | +122 (+53/+69) |
| 49 | 256 (180+76) | 360 (216+155) | +104 (+36/+79) |
| 50 | 204 (148+56) | 339 (195+144) | +135 (+47/+90) |
| 51 | 178 (124+54) | 323 (190+133) | +145 (+66/+79) |
| 52 | 115 (78+37) | 289 (190+99) | +174 (+112/+62) |
| 1 | 93 (60+33) | 287 (171+116) | +194 (+111/+83) |
| 2 | 82 (46+36) | 271 (162+109) | +189 (+116/+73) |
| 3 | 25 (15+10) | 249 (165+84) | +224 (+150/+74) |
| 4 | 14 (8+6) | 244 (176+68) | +230 (+168/+62) |
| 5 | 2 (0+2) | 224 (132+92) | +222 (+132/+90) |
| 6 | release! | 212 (129+83) | +212 (+129/+83) |
| 7 | release+1 | 194 (128+66) | +194 (+128/+66) |
| 8 | release+2 | 206 (144+62) | +206 (+144/+62) |
| 9 | release+3 | 174 (105+69) | +174 (+105/+69) |
| 10 | release+4 | 120 (72+48) | +120 (+72/+48) |
| 11 | release+5 | 115 (74+41) | +115 (+74/+41) |
| 12 | release+6 | 93 (47+46) | +93 (+47/+46) |
| 13 | release+7 | 50 (24+26) | +50 (+24/+26) |
| 14 | release+8 | 51 (32+19) | +51 (+32/+19) |
| 15 | release+9 | 39 (32+7) | +39 (+32/+7) |
| 16 | release+10 | 20 (12+8) | +20 (+12/+8) |
| 17 | release+11 | 24 (19+5) | +24 (+19/+5) |
| 18 | release+12 | 2 (2+0) | +2 (+2/+0) |
Debian wheezy includes a bunch of excellent new Haskell libraries.
I'm going to highlight one that should be interesting to non-Haskell
developers, who may have struggled with writing non-buggy threaded
programs in other languages:
libghc-stm-dev
I had given up on most threaded programs before learning about
Software Transactional Memory.
Writing a correct threaded program, when multiple threads needed
to modify the same state, needed careful uses of locking.
In my experience, locking is almost never gotten right the first time.
A real life example I encountered is an app that displays a queue of files
to be downloaded, and a list of files currently downloading. Starting
a new download would go something like this:
startDownload = do
file <- getQueuedFile
startDownloadThread file
push file currentDownLoads
getQueuedFile implemented?
If the queue is empty, it needs to wait on a file being added. But how
can a file be added the queue if we've locked it in order to perform this
larger startDownload operation? What should be really simple code
has become really complex juggling of locks.
STM deals with this in a much nicer way:
startDownload = atomically $ do
file <- getQueuedFile
startDownloadThread file
push file currentDownLoads
getQueuedFile can do whatever waiting it needs to, also using STM.
This becomes part of the same larger transaction, in a way that cannot
deadlock. It might be implemented like this:
getQueuedFile = atomically $
if empty downloadQueue
then retry
else pop downloadQueue
getQueuedFile that run entirely in STM are building blocks
that can be snapped together without worries to build more and more complex
things.
For non-Haskell developers, STM is also available in Clojure, and work
is underway to add it to gcc. There is also Hardware Transactional Memory
coming, to speed it up. Although in my experience it's quite acceptably
fast already.
However, as far as I know, all these other implementations of STM leave
developers with a problem nearly as thorny as the original problem with
locking. STM inherently works by detecting when a change is made that
conflicts with another transaction, throwing away the change,
and retrying. This means that code inside a STM transaction may
run more than once.
Wait a second.. Doesn't that mean this code has a problem?
startDownload = atomically $ do
file <- getQueuedFile
startDownloadThread file
push file currentDownLoads
startDownloadThread is
not safe to put in the middle of a STM transaction. You're left with no
choice but to change things so the thread is only
spawned once the transaction succeeds:
startDownload = do
file <- atomically $ do
f <- getQueuedFile
push f currentDownLoads
return f
startDownloadThread file
| Series: | The Baroque Cycle #3 |
| Publisher: | William Morrow |
| Copyright: | 2004 |
| ISBN: | 0-06-052387-5 |
| Format: | Hardcover |
| Pages: | 892 |
The below is written in the hope it will be helpful for my fellow DDs.
Why using build after push ?
Simple answer: to save time, to always use a clean build environment, to automate more tests.
Real answer: because you are lazy, and tired of always having to type these build commands, and that watching the IRC channel is more fun than watching the build process.
Other less important answers: building takes some CPU time, and makes your computer run slower for other tasks. It is really nice that building doesn t consume CPU cycles on your workstation/laptop, and that a server does the work, not disturbing you while you are working. It is also super nice that it can maintain a Debian repository for you after a successful build, available for everyone to use and test, which would be harder to achieve on your work machine (which may be behind a router doing NAT, or even sometimes turned off, etc.). It s also kind of fun to have an IRC robot telling everyone when a build is successful, so that you don t have to tell them, they can see it and start testing your work.
Install a SID box that can build with cowbuilderhttp://<ip-of-your-server>:8080/There is no auth by default, so anyone will be able to access your jenkins web GUI and start any script under the jenkins user (sic!). Jenkins auth
ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ ProxyRequests OffThen perform the following commands on the shell:
htpasswd -c /etc/apache2/jenkins_htpasswd <your-jenkins-username> a2enmod proxy a2enmod proxy_http a2enmod ssl a2ensite default-ssl a2dissite default apache2ctl restartThen disable access to the port 8080 of jenkins from outside:
iptables -I INPUT -d <ip-of-your-server> -p tcp --dport 8080 -j REJECTOf course, this doesn t mean you shouldn t take the steps to activate Jenkins own authentication, which is disabled by default (sic!). Build a script to build packages in a cowbuilder I thought it was hard. In fact it was not. All together, this was kind of fun to hack. Yes hack. What I did yet another kind of 10km ugly shell script. The way to use it is simply: build-openstack-pkg <package-name>. On my build server, I have put that script in /usr/bin, so that it is accessible from the default path.Ugly, but it does the job! Jenkins build script for openstack At the end of the script, scan_repo() generates the necessary files for a Debian repository to work under /home/ftp. I use pure-ftpd to serve it. /home/ftp must be owned by jenkins:jenkins so that the build script can copy packages in it. This build script is by no mean state of the art, and in fact, it s quite hack-ish (so I m not particularly proud of it, but it does its job ). If I am showing it in this blog post, it is just to show an example of what can be done. It is left as an exercise to the reader to create another build script adapted to its own needs, and write something cleaner and more modular. Dependency building Let s say that you are using the Built-Using: field, and that package B needs to be built if package A changes. Well, Jenkins can be configured to do that. Simply edit the configuration of project B (you will find it, it s easy ). My use case: In my case, for building Glance, Heat, Keystone, Nova, Quantum, Cinder and Ceilometer, which are all components of Openstack, I have written a small (about 500 lines) library of shell functions, and an also small (90 lines) Makefile, which are packaged in openstack-pkg-tools (so Nova, Glance, etc. all build-depends on openstack-pkg-tools). The shell functions are included in each maintainer scripts (debian/*.config and debian/*.postinst mainly) to avoid having some pre-depends that would break debconf flow. The Makefile of openstack-pkg-tools is included in debian/rules of each packages. In such a case, trying to manage the build process by hand is boring and time consuming (spending your time watching the build process of package A, so that you can manually start the build of package B, then wait again ). But it is also error prone: it is easy to do a mistakes in the build order, you can forget to dpkg -i the new version of package A, etc. But that s not it. Probably at some point, you will want Jenkins to rebuild everything. Well, that s easy to do. Simply create a dummy project, and have other project to build after that one. The build steps could simply be: echo Dummy project as a shell script (I m not even sure that s needed ). Configuring git to start a build on each push In Jenkins, pass your mouse over the Build now URL. Well, we just need to wget that URL in your Alioth repository. A small drawing is better than long explanation:
for i in ls /git/openstack ; do
echo "wget -q --no-check-certificate \
https://<ip-of-your-server>/job/$ PROJ_NAME /build?delay=0sec \
-O /dev/null" >/git/openstack/$ i /hooks/post-receive \
&& chmod 0770 /git/openstack/$ i /hooks/post-receive;
done
The chmod 0770 is necessary if you don t want every Alioth users to have access to your Jenkins server web interface and see an eventual htpassword protection that you can add to your jenkins box (I m not covering that, but it is fairly easy to add such protection). Note that all of the members of your Alioth group will then have access to this post-receive hook, containing the password of your htaccess, so you must trust everyone in your Alioth group to not do nasty things with your Jenkins.
Bonus point: IRC robot
If you would like to see the result of your build published on IRC, Jenkins can do that. Click on Manage Jenkins , then on Manage Plugins . Then click on available and check the box in front of IRC plugin . Go at the bottom of the screen and click on Add . Then check the box to restart Jenkins automatically. Once it is restarted, go again under Manage jenkins then Configure system . Select the IRC Notification and configure it to join the network and the channel you want. Click on Advanced to select the IRC nick name of your bot, and make sure you change the port (by default jenkins has 194, when IRC normally uses 6667). Be patient when waiting for the IRC robot to connect / disconnect, this can take some time.
Now, for each jenkins Job, you can tick the IRC Notification option.
Doing piuparts after build
One nice thing with automated builds, is that most of the time, you don t need to wait starring at them. So you can add as many tests as you want, the Jenkins IRC robot will anyway let you know sooner or later the result of your build. So adding piuparts tests in the build script seems the correct thing to do. Though that is still on my todo, so maybe that will be for my next blog post.
I was going to start this series with explaining how I did the remote set-up, but instead I will share something that happened today.
One of the first things you want to do when putting a server directly connected to the Internet is some filtering. You don't want to have an application listening on the network by mistake, so a simple netfilter firewall is a good way to ensure you are only accepting connections on ports you explicitly allowed.
I have been a long-time user of ferm, a simple tool that will read a configuration file written in a special structured syntax, and generates iptables commands from it. I have used it successfully to build very complex firewalls in previous jobs, and it had the huge benefit of keeping your firewall description readable and easy to modify by other people.
This time I thought I may go with something simpler, as I only wanted a handful of very simple netfilter rules. I looked at Shorewall, and browsed a bit a few others. But in the end I decided against them: there was the need to learn the tools' concepts about different parts of the network, or there were more slanted towards command-line commands, so your actual configuration will be some files in /var/lib, totally managed by the tool. With ferm, I just need to write a very small configuration file, which reads almost like iptables commands, and that's it.
In fact, the default configuration placed by the Debian package, already did 90% of what I wanted: accept incoming SSH connections, ICMP packets, and reject everything else. I took the example IPv6 configuration from /usr/share/doc/ferm/examples/ipv6.ferm and in 10 minutes it was ready:
table filter
chain INPUT
policy DROP;
mod state state INVALID DROP;
mod state state (ESTABLISHED RELATED) ACCEPT;
interface lo ACCEPT;
proto icmp ACCEPT;
# allow IPsec
proto udp dport 500 ACCEPT;
proto (esp ah) ACCEPT;
proto tcp dport ssh ACCEPT;
proto tcp dport (http https) ACCEPT;
chain OUTPUT policy ACCEPT;
chain FORWARD policy DROP;
domain ip6 table filter
chain INPUT
policy DROP;
mod state state INVALID DROP;
mod state state (ESTABLISHED RELATED) ACCEPT;
interface lo ACCEPT;
proto ipv6-icmp ACCEPT;
proto tcp dport ssh ACCEPT;
proto tcp dport (http https) ACCEPT;
chain OUTPUT policy ACCEPT;
chain FORWARD policy DROP;
It is important to note than when doing this kind of thing on a remote machine, you want to make sure you don't get locked out by accident. My method is that before activating any dangerous change, I drop an at job to disable the firewall in a few minutes:
# echo /etc/init.d/ferm stop at now +10min
warning: commands will be executed using /bin/sh
job 4 at Mon Apr 29 02:47:00 2013
And if everything goes well, I just remove the job:
# atrm 4
Update: As paravoid pointed out in the comments, now (read: since many years ago, but I've never noticed) ferm has a --interactive mode which will revert the changes if you get locked out, much like the screen resolution changing dialog in Gnome.
PermitRootLogin=no setting, there are a couple of popular methods to stop people probing random username/password combinations (I am assuming here that you actually have sensible passwords, or no passwords at all): running SSH in a non-standard port, and the great fail2ban daemon.
Since I don't like non-standard stuff, I installed fail2ban, which by default it will inspect /var/log/auth.log for SSH login failures and insert netfilter rules to block the offenders.
Problem is, I don't like much how fail2ban inserts rules and chains into my very tidy netfilter configuration which I had just created. So, I added an "action" to do things my way: only create a service-related chain and insert rules there, I will call that chain from my main ferm.conf. Ferm runs early in the boot sequence, so this won't be a problem during normal operation. The only caveat is that after changing a configuration in ferm, I need to restart fail2ban so it will recreate the netfilter chains and rules, which were wiped by ferm.
This is my configuration, note that I am ignoring the port and protocol: the whole IP is blocked for a few minutes.
# cat /etc/fail2ban/jail.local
[DEFAULT]
action = iptables-fixed[name=%(__name__)s]
# cat /etc/fail2ban/action.d/iptables-fixed.conf
[Definition]
actionstart = iptables -N fail2ban-<name>
iptables -I fail2ban -j fail2ban-<name>
actionstop = iptables -D fail2ban -j fail2ban-<name>
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
actioncheck = iptables -n -L grep -q fail2ban-<name>
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
[Init]
name = default
Next.