gildegoma / chef-android-sdk

Development repository for Android SDK Chef Cookbook
https://supermarket.chef.io/cookbooks/android-sdk
Apache License 2.0
26 stars 29 forks source link

Cache platform zips downloaded via `android update` command #19

Closed patcon closed 9 years ago

patcon commented 10 years ago

Inconveniently, the android update command immediately deletes any zips that it downloads into its temp/ directory, and it offers no caching functionality. I've experimented a bit with an approach that watches the temp directory for new zip files, and changes the user's owner to root. If you have first changed the temp dir's group to "root", and set the sticky bit on that dir, then the regular user (and the android command) won't be able to delete the zip after downloading. We can then move the zips into a cache somewhere.

These two articles contain the details needed:

Thinking that if we can set up a daemon service running a watcher via inotifywait, we can change the owner of the zip and make sure that all zips stay there.

Anyhow, this isn't super pressing for me right now, but wanted to get the technique in an issue in case anyone else was interested in caching later

patcon commented 10 years ago

Anyhow, ended up sketching it out. Thoughts? Could forgo the init script service and maybe use the inotifywait--daemon option, but that didn't seem proper, since I can't easily kill it after the chef run (could maybe write some custom start/stop actions and fake a service resource, I suppose).

Also, haven't investigated fully, but found this PoC cookbook after putting most of this together: https://github.com/spheromak/chef-inotify

# templates/android-sdk-download-monitor.erb

# Ref: https://github.com/fhd/init-script-template/blob/master/template

#!/bin/sh
### BEGIN INIT INFO
# Provides:          
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

dir="<%= android_setup_root %>"
user="root"
cmd="inotifywait --monitor temp/ --event create --event moved_to | while read path action file; do chown root $path/$file; done"

name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"

get_pid() {
    cat "$pid_file"    
}

is_running() {
    [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1
}

case "$1" in
    start)
    if is_running; then
        echo "Already started"
    else
        echo "Starting $name"
        cd "$dir"
        sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
        echo $! > "$pid_file"
        if ! is_running; then
            echo "Unable to start, see $stdout_log and $stderr_log"
            exit 1
        fi
    fi
    ;;
    stop)
    if is_running; then
        echo -n "Stopping $name.."
        kill `get_pid`
        for i in {1..10}
        do
            if ! is_running; then
                break
            fi

            echo -n "."
            sleep 1
        done
        echo

        if is_running; then
            echo "Not stopped; may still be shutting down or shutdown may have failed"
            exit 1
        else
            echo "Stopped"
            if [ -f "$pid_file" ]; then
                rm "$pid_file"
            fi
        fi
    else
        echo "Not running"
    fi
    ;;
    restart)
    $0 stop
    if is_running; then
        echo "Unable to stop, will not attempt to start"
        exit 1
    fi
    $0 start
    ;;
    status)
    if is_running; then
        echo "Running"
    else
        echo "Stopped"
        exit 1
    fi
    ;;
    *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
    ;;
esac

exit 0
# insert into recipes/default.rb

directory "#{setup_root}/#{node['android-sdk']['name']}-#{node['android-sdk']['version']}/temp" do
  owner "root"
  # group should default to user running, ie. "vagrant"
  mode "1775"
end

package "inotify-tools"

service_name = "android-sdk-download-monitor"

service service_name do
  supports :start => true, :stop => true, :restart => true, :status => true
  action :nothing
  subscribes :reload, "template[/etc/init.d/#{service_name}]", :immediately
end

template "/etc/init.d/#{service_name}" do
  mode "0644"
  source "#{service_name}.erb"
  variables({
    :android_setup_root => "#{setup_root}/#{node['android-sdk']['name']}-#{node['android-sdk']['version']}"
  })
end

# Copy all android sdk zips from chef cache, if present

# Run existing cookbook segment that installs via `android update sdk blah`

# Copy any new zips to chef cache (vagrant-cachier will cache this, for example)
patcon commented 10 years ago

Hm. Tested it out and it generally works, but feels very messy with how I got it working. Since the whole point is to keep them in a sync'd folder that persists between vagrant runs, we need to use FileUtils.cp_r to move the files to and from $ANDROID_HOME/temp before and after the android update sdk commands. This is required because we can't cache the temp directory directly, since sticky bits and advanced perms aren't allowed for shared directories, and they're critical to preventing the android command from removing the zips.

Anyhow, I've abandonned this for now, as it was too much work when all I really need to do is ensure a fast and reliable connection :)

patcon commented 10 years ago

Oh hey, seems the better option is to parse repository-10.xml and manually download into a cache dir, then unzip into appropriate places. Not worth fudging with the android sdk command imho

gildegoma commented 9 years ago

@patcon Sorry for lack of response during all this time.

I'm closing this, as I think that such kind of caching feature should better be solved in an other place, ideally in official google's android tooling. Adding and maintaining this kind of feature looks a lot of effort in comparison of the "network bandwidth/patience effort" of living without file caching.

Please feel free to provide further arguments (I always can re-open it ;-)