aptgetinstallprotocol

Revision 20 as of 2006-03-23 23:39:56

Clear message

Apt-Get Install Protocol

Summary

It would be nice if you could click on a url in a web page (apt-get-instal://foo) and trigger package install using apt-get from the systems set repository list

Rationale

At the momment the forum and wiki is full of cut and paste this command 'sudo foo foo foo'. New linux users have no idea what these commands do and so could be considered a security risk (sudo rm -R-f /). As well as the obvious fact that they actully have to open a terminal window.

Its that or

  • click system
  • click administration
  • click synaptic
  • search for package 'foo'
  • right click on package and select install
  • click Apply

Saying click this link apt-get-install://foo is a lot nicer and cleaner

NOTE : Add applications is a great start but it only covers a small part of the ubuntu packages

Use cases

  • Wiki howto gives instructions on how to apt-get packages
  • Forum users give instructions on how to apt-get packages
  • Email grandma an apt-get-install link to enable her to install that bridge game she wants
  • Bert fresh from switching from that 'other OS' is used to installing applications from web pages, he has never used a cli and dosnt want too.

Scope

  • Will only ap-get install packages in the existing repo lists does not cover adding new repositires
  • Keep It Simple, protocol only allows simple 'install' any thing else is advanced user and can still be done through CLI
  • Should allow a list of packages to be installed ie apt-install://foo foobar foobar2
  • apt-get install is the only command to be 'web enabled'

Design

  • Check if sudo avalible for user and alert error message if not
  • Should prompt for sudo
  • Should display a nice progress bar
  • If package is not avalible in the current sources repositories an alert should state so.
  • If package is already installed an alert should say so
  • Deside on a protocol 'name'
  • * apt://

  • * apt-get://
  • * aptget://
  • * apt-get-install://

Implementation

Gnome has the ability to add protocols, easy ubuntu already demonstrates a method for tying into synaptic so the user gets a progress bar for download and install.

Klik already does something similar to trigger cmg creation

Linspire's Click-N-Run does some thing similar as well

Resources

working prototype version

# Create the dir
echo "Create Directory :: $HOME/.app-get-install"
mkdir $HOME/.app-get-install 2>/dev/null

# Create Schema File
echo "Create gconf schema"
cat > $HOME/.app-get-install/app-get-install.schema <<EOF
<gconfschemafile>
    <schemalist>
        <schema>
            <key>/schemas/desktop/gnome/url-handlers/apt-get-install/enabled</key>
            <applyto>/desktop/gnome/url-handlers/apt-get-install/enabled</applyto>
            <owner>gnome</owner>
            <type>bool</type>
            <default>true</default>
            <locale name="C">
                <short>Whether the specified command should handle "apt-get-install" URLs</short>
                <long>True if the command specified in the "command" key should handle "apt-get-install" URLs.</long>
            </locale>
        </schema>

        <schema>
            <key>/schemas/desktop/gnome/url-handlers/apt-get-install/needs_terminal</key>
            <applyto>/desktop/gnome/url-handlers/apt-get-install/needs_terminal</applyto>
            <owner>gnome</owner>
            <type>bool</type>
            <default>false</default>
            <locale name="C">
                <short>Run the command in a terminal</short>
                <long>True if the command used to handle this type of URL should be run in a terminal.</long>
            </locale>
        </schema>

        <schema>
            <key>/schemas/desktop/gnome/url-handlers/apt-get-install/command</key>
            <applyto>/desktop/gnome/url-handlers/apt-get-install/command</applyto>
            <owner>gnome</owner>
            <type>string</type>
            <default>$HOME/.app-get-install/apt-get-install-protocol %s</default>
            <locale name="C">
                <short>The handler for "apt-get-install" URLs</short>
                <long>Easy Web Install For apt-get</long>
            </locale>
        </schema>

    </schemalist>
</gconfschemafile>
EOF

# Import into users Gconf
echo "Import gonf schema"
env GCONF_CONFIG_SOURCE="" gconftool-2 --makefile-install-rule $HOME/.app-get-install/app-get-install.schema 2>/dev/null >/dev/null

# Create handler script
echo "Create protocol handler"
cat > $HOME/.app-get-install/apt-get-install-protocol <<EOF
#!/bin/bash
PROTOCOL="apt-get-install"
INSTALL_SCRIPT="python $HOME/.app-get-install/app-get-install-synaptic.py"

# Need to make sure $@ is safe before issueing this command??
PACKAGES=\`echo "\$@" | sed s@\\\$PROTOCOL:\\/\\/@@\`
gnome-sudo --always-ask-password --message="Please enter your password to install the following software package(s) :

\$PACKAGES" "\$INSTALL_SCRIPT \$PACKAGES"
EOF

# Make handler script exectable
echo "Make handler script executable"
chmod +x $HOME/.app-get-install/apt-get-install-protocol

echo "Create synaptic controller script"
cat > $HOME/.app-get-install/app-get-install-synaptic.py << EOF
#!/usr/bin/env python
"""
        This file installs using synaptic

        TODO: 
                - Allow a temp sources.list for install
                - 
        
"""
import os, sys, re, subprocess, time

# Class from easyubuntu project
class PackageManager:
    
    def __init__(self):
        """ Call Synaptic with different configuration options """
        self.manager = ["/usr/sbin/synaptic", "--hide-main-window", 
                        "--non-interactive"#, 
                        #"-o=dir::etc=./conf", 
                        #"-o=dir::etc::sourcelist=sources.list"
                        ]

    def package_exists(self, PackageName = None):
        # Check if pacakge is in selected repos
        cmd = "apt-cache search --names-only ^%s$" % PackageName
        for file in os.popen(cmd).readlines():    
                return True
        return False

    def update(self):
        """ Get the last packages list from repositories
        """
        self.manager.append("--update-at-startup")
        retcode = subprocess.Popen(self.manager).wait()
        print "Synaptic exited with return code = ",retcode

    def install(self, Packages = None):
        
        # Need a way to find if package exists in repos.....
        self.manager.append("--set-selections")
        f = os.popen(" ".join(self.manager), "w")
        for s in Packages:
            f.write("%s                 install\n" % s)
        
        f.close()

def init(PackageList):

                p = PackageManager()

                # only allow char ( a-z 0-9 - _) any others?? will this work? multi lang?
                reUrlCheck = re.compile( '[^a-zA-Z0-9\-\_]')             
                result = reUrlCheck.search( "".join( PackageList ) )

                if result:
                        print "Error Exiting, Invalid charecter(s) found in package name"
                        return 
                        
                p.install(Packages = PackageList)

if __name__ == "__main__":
        
        # Drop the first item and past the rest to init
        if len(sys.argv) > 1:
                init( sys.argv[1:] )
        else:
                # No packages where given exit
                print "Error Exiting, Please enter a package name to install"
EOF

# Create Demo File
cat > $HOME/.app-get-install/demo.html << EOF
<h1>Proof of concept, demo of basic apt-get-install protocol</h1>
<p>You should now be able to install application by cliking the below links</p>
<ul>
        <li><a href="apt-get-install://bluefish">Install Bluefish</a></li>
        <li><a href="apt-get-install://banshee">Install Banshee</a></li>
        <li><a href="apt-get-install://muine">Install Muine</a></li>
</ul>
EOF

echo "Open demo page"
# Open the demo file
gnome-open $HOME/.app-get-install/demo.html

Comments

  • ArwynHainsworth: apt-get is not a protocol it's an application. Mixing them up would be bad design. What you want is something like ThirdPartyApt. It would provide the same function as what you have outlined above, but not break the protocol/application logic.

  • KillerKiwi : ThirdPartyApt is similar but is for installing packages from differnt repos(hence the file+format), this only covers existing repos and allows people to easily create links without creating a file (think wiki/forum posts). I'd be happy with ThirdPartyApt as well but I dont think it will be accepted because of the percived security issues.

  • ArwynHainsworth: I agree that ThirdPartyApt has security issues, but they are resolvable (see comments in ThirdPartyApt). That approch (file+mimetype) however is better than implementing a CLI for apt-get in the Location bar of a web browser...

  • KillerKiwi : My only issue with ThirdPartyApt is that you 'have' to create a file, if that could be simplified out some how i would be a happy camper. If a file was created for every package in the repo and avalible to be linked to ie http://install.ubuntu.com/ubuntu/dists/dapper/foo.apt (Making a domain/path up here) that would be close, although it wouldn't help for packages in thired party repos that have been added.

  • ArwynHainsworth: That is what dynamic scripts are for. http://fake.ubuntu.com/aptfilegenerator.pl?package=mplayer (also not real). Result is an auto-generated apt file to install mplayer.