Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Friday, December 12, 2014

How to set up automatic Github uploads

Back to basics

For years, I have been playing with US Weather Data.

A couple years ago, I came up with a lookup server for US weather locations, and -of course- had all kinds of plans for how to expand it to more services and more countries.

So, of course, it went nowhere.

This week, I took a look at the issue again, and came up with a simple set of lookup tables (yes, a tiny database) to replace the server. It reduced the amount of code by about 70%, and it's finally in a maintainable, expandable form. It's simple, and ready for a few drive-by patches.

Which leads to the next question...how to share it with the world?

Well, in this decade, sharing software and data means putting it on GitHub.


Creating the GitHub repositories

We have a Python 3 script that creates the database, another Python 3 example script that consumes the database, and the three CSV files that make up the database tables. Most consumers will probably just want the data for their own purposes - they really don't need the scripts (and it would be quite rude for millions of users to hit NOAA servers to produce their own databases each week)

So I created two repositories on GitHub, one for the data and another for the optional scripts.

If you haven't used GitHub, you first go online and create your account and create the repositories (with initial README file) in a web browser. Then:

cd /tmp
git clone https://github.com/ian-weisser/data   # Create a clone of the online repository
cd data
cp /home/somewhere/else/data/* ./               # Add existing data files into the local clone
git add ./*                                     # Tell git to track the new data files
git commit -m "Add initial data"
git push origin master                          # Push the changes back to GitHub
  Username for 'https://github.com':
  Password for 'https://me@github.com': 
cd /tmp 
rm -rf /tmp/data                                # Clean up

Overall, it's pretty simple. For the next iteration:
  • We must automate the upload credentials so it doesn't prompt for a username and password each time.
  • We must add a cron job that creates the data for upload.
  • Let's move this project from /tmp on my laptop to the server where it will live permanently. This also means that the server should pull the latest Python script...which is also hosted on GitHub.

Let's setup the server:


sudo apt-get install git    # On this server, about 3 MB of download
sudo apt-get install python3-httplib2  # Script dependency
mkdir uploads
cd uploads
git clone https://github.com/ian-weisser/data          # Setup the local 'data' repository
git clone https://github.com/ian-weisser/weather       # Setup the local 'software' repository
weather/nws_database_creator.py                        # Use the script to update CSVs in ~/uploads/data
cd data
git config --global user.email "my_email@example.com"  # First time setup
git config --global user.name "My Name"                # First time setup
git config credential.helper store                     # First time using this repo setup
git add -A
git commit -m "Test update"
git push origin master
  Username for 'https://github.com': my-github-login-name   # First time using this repo setup
  Password for 'https://my-github-login-name@github.com':   # First time using this repo setup


Automating the process

So now subsequently, without all the first time setup:

#!/bin/sh

dir=/home/ian/uploads
hub="https://github.com/ian-weisser"
now=$(/bin/date +%F)

cd $dir/weather
/usr/bin/git pull "$hub"/weather      # Update the database_creator script

cd $dir/data
/usr/bin/git pull "$hub"/data         # Need to pull to be able to push later

$dir/weather/nws_database_creator.py  # Do the update
/usr/bin/git add -A                   # Record any changes
/usr/bin/git commit -m "Scheduled update $now"
/usr/bin/git push origin master
exit 0


And now we can run the shell script weekly from a user cron job:

5 6 * * 7 /home/ian/uploads/cron/weekly_weather > /home/ian/uploads/weather.log 2>&1


A couple of tests, and it works.

It's completely automatic.

Once a week, my server downloads the latest make-a-database script, builds the database, and uploads the database to GitHub for the world to use.


The data


If you want to see the final product (the lat/lon lookup tables for US weather), you can get them at:
https://raw.githubusercontent.com/ian-weisser/data/master/metar.csv
https://raw.githubusercontent.com/ian-weisser/data/master/radar.csv
https://raw.githubusercontent.com/ian-weisser/data/master/zone.csv

They will, of course, be automatically updated weekly.

Monday, February 20, 2012

Simutrans packaging bug

After a bit of scratching my head, I finally figured out that Simutrans 110.0.1 (the version in Ubuntu 11.10) and the Debian-packaged version that is actually in Ubuntu have a weird incompatibility.

About a year ago, Simutrans added a network-multiplayer-server feature. But Debian/Ubuntu-packaged clients can only communicate with Debian/Ubuntu-packaged servers. Similarly, manually-installed clients can only talk to manually installed servers.

Well, that's certainly not intended behavior - all the servers should be able to talk to all the clients, regardless of whether they were packaged or not!

So I filed LP #931181, because the Debian Games Team needs to know.
And I opened a thread on the developer's forum.

Clue: One developer immediately noted that it seemed to be a checksum issue. (Thanks, Dwachs!)

Well, let's check that. Let's take one item in the pakset, building.PostOffice.pak, and see how it checksum:

Let's hash it manually first:
$ openssl sha1 ~/simutrans110/simutrans/pak/building.PostOffice.pak 
SHA1(/home/me/simutrans110/simutrans/pak/building.PostOffice.pak)= 8b1b5caa71013474039f357094cd1716bd3800bd

$ openssl sha1 /usr/share/games/simutrans/pak/building.PostOffice.pak 
SHA1(/usr/share/games/simutrans/pak/building.PostOffice.pak)= 8b1b5caa71013474039f357094cd1716bd3800bd
So the those pakset items (and, by extension, probably the entire pakset) are identical.

Next, let's check the logs of success and failure:

Succesful (Ubuntu 11.10) server: Message: pakset_info_t::debug: PostOffice -> sha1 = B80C3C262A2758C8FC54FF129272F564B7DA8AAF

Succesful (Ubuntu 11.10) client: Message: pakset_info_t::debug: PostOffice -> sha1 = B80C3C262A2758C8FC54FF129272F564B7DA8AAF

Failed (Manually-installed) server: Message: pakset_info_t::debug: PostOffice -> sha1 = 263C0CB8C858272A12FF54FC64F57292AF8ADAB7

Failed (Ubuntu 11.10) client: Message: pakset_info_t::debug: PostOffice -> sha1 = B80C3C262A2758C8FC54FF129272F564B7DA8AAF

It seems that Dwachs put me on the right track. Given identical files to checksum, the two binaries checksum differently, and both do it differently than Ubuntu's default method, even though each claim to be using the same sha1!


Next, let's look for the changed sha-1 patch at the Debian Games Team git repository.

Aha! February 16, 2011: Add replacement for non-free SHA-1 implementation
Aha! February 16, 2011: get-orig-source: Remove non-free SHA-1 implementation.

The patch, is clearly a replacement for the original Simutrans trunk/utils/sha1.cc
And, looking at the current tree, the patch is still applied.

Er, did I just walk into a year-old dispute between Debian and Simutrans devs?

Next, I need to prove that the patch is the culprit. I need to apply the patch to a stock simutrans source, compile it, run it as a server (in debug mode), successfully join the game from a debian-install client.


Happily, I already have a stock 110.0.1 source, setup, and pakset in my simutrans110 directory, from earlier troubleshooting. Full instructions on how to compile are in this post.

Let's build the unpatched (stock) version first. This should be compatible with a manual install, and incompatible with the Debian version.
$ cp simutrans110 r4359-stock
$ cd r4359-stock/svn/trunk
$ make clean
$ make
$ strip sim
$ cp sim ~/r4359-stock/simutrans/sim-unpatched

Now, let's build a patched version. This should be compatible with the Debian version, and incompatible with a manual install.
$ sudo apt-get install libssl-dev
$ cp simutrans110 r4359-patched
$ cp Desktop/debian_patches_sha1-replacement.diff r4359-patched/svn/trunk
$ cd r4359-patched/svn/trunk

  --- Apply the patch ---
$ rm utils/sha1.*
$ patch Makefile debian_patches_sha1-replacement.diff 
$ patch utils/checksum.h debian_patches_sha1-replacement.diff
$ nano utils/sha1.cc
$ nano utils/sha1.h

$ make clean
$ make
$ strip sim
$ cp sim ~/r4359-stock/simutrans/sim-patched

Finally, we test.

Ubuntu 11.10's package install of Simutrans 110.0.1 can join a game served by sim-patched, but not a game served by sim-unpatched.

A manually-installed version of 110.0.1 is, as expected, the reverse. It can join a game served by sim-unpatched, but not a game served by sim-patched.