openSUSE:One Click Install specification
One click installation of packages
Use case
- Allow the user to install package(s) from (a) repositor(y|ies) (he|she) may or may not have in (his|her) system repositories.
Scope
- In scope is automating the process of the package manager adding repositories and installing packages.
- In scope is presenting the user with sufficient information to understand the automated process.
- Out of scope is any package management details such as package dependencies.
Requirements
- Action must be triggered with a one click.
- Should be possible to include trigger on web page
- Should be possible to include trigger on physical media for ISVs
- Security (user should confirm adding of sources)
- Should be possible to override auto-detection of repository type.
- Should be possible to include multiple mirrors
- Should be possible to have multiple translations of strings.
- Should be possible to have one button/file to click on to install the product(s) for any version of the distribution.
- Files should not need to be very big (translations optional etc) so download time is negligible.
- It should be possible to specify how to resolve common conflicts (e.g. compiz/beryl)
Dependencies
- No good way to unique identify repositories (url? hash? id? )
Proposed Standard
Specification
# # RELAX NG Schema for Metapackage Specification # # Derived from the XSD Schema found at # http://en.opensuse.org/Standards/One_Click_Install # # Author: Thomas Schraitle <thomas DOT schraitle AT suse.de> # namespace rng = "http://relaxng.org/ns/structure/1.0" datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" default namespace ps = "http://opensuse.org/Standards/One_Click_Install" start = y.metapackage div { c.lang.attrib = ## A natural language attribute lang { xsd:language } # c._any.attrib = ## Any attribute from any namespace attribute * { text } c.architecture.attrib = ## ??? attribute architecture { text } c.recommended.attrib = ## Is this repository recommended? attribute recommended { xsd:boolean } c.type.attrib = ## ??? attribute type { text } c.mirrorableURL = text c.translateableString = text } div { # metapackage y.metapackage = ## The root element element metapackage { y.metapackage.attlist, y.group+ } y.metapackage.attlist = c._any.attrib* } div { # group y.group = ## Groups repositories element group { y.group.attlist, y.name?, y.summary?, y.description?, y.remainsubscribed?, y.repositories, y.software } y.group.recommended.attrib = c.recommended.attrib y.group.distversion.attrib = ## The version of the grouped repository attribute distversion { text } y.group.attlist = y.group.recommended.attrib? & y.group.distversion.attrib? } div { # name y.name = ## The name of a group, repository or software element name { y.name.attlist, text } y.name.attlist = empty } div { # summary y.summary = ## A summary of a group, repository or software element summary { y.summary.attlist, c.translateableString } y.summary.attlist = c.lang.attrib? } div { # description y.description = ## A description of a group, repository or software element description { y.description.attlist, c.translateableString } y.description.attlist = c.lang.attrib? } div { # remainSubscribed y.remainsubscribed = ## Should the user remain subscribed to these repository? element remainSubscribed { y.remainsubscribed.attlist, xsd:boolean } y.remainsubscribed.attlist = empty } div { # repositories y.repositories = ## A list of required repositories for this installation element repositories { y.repositories.attlist, y.repository* } y.repositories.attlist = empty } div { # repository y.repository = ## A repository with name, summary, description and url element repository { y.repository.attlist, y.name, y.summary+, y.description+, y.url+ } y.repository.recommended.attrib = c.recommended.attrib y.repository.format.attrib = ## The format of the repository attribute format { text } y.repository.producturi.attrib = ## ??? attribute producturi { text } y.repository.attlist = y.repository.recommended.attrib? & y.repository.format.attrib? & y.repository.producturi.attrib? } div { # software y.software = ## A list of software items to install element software { y.software.attlist, y.item* } y.software.attlist = empty } div { # item y.item = ## A software item to install element item { y.item.attlist, y.name, y.summary+, y.description+ } y.item.action.attrib = ## ??? attribute action { text } y.item.architecture.attrib = c.architecture.attrib y.item.recommended.attrib = c.recommended.attrib y.item.type.attrib = c.type.attrib y.item.attlist = y.item.action.attrib? & y.item.architecture.attrib? & y.item.recommended.attrib? & y.item.type.attrib? } div { # url y.url = ## An URL pointing to a repository element url { y.url.attlist, c.mirrorableURL } y.url.score.attrib = ## ??? attribute score { xsd:integer } y.url.location.attrib = ## ??? attribute location { text } y.url.attlist = y.url.score.attrib? & y.url.location.attrib? }
Example
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://opensuse.org/Standards/One_Click_Install" xmlns:os="http://opensuse.org/Standards/One_Click_Install" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:complexType name="softwareitem"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="summary" type="os:translatableString" minOccurs="1" maxOccurs="unbounded"/> <xs:element name="description" type="os:translatableString" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="type" type="xs:string" default="package"/> <xs:attribute name="recommended" type="xs:boolean" default="true"/> <xs:attribute name="architectures" type="xs:string" default="all"/> <xs:attribute name="action" type="xs:string" default="install"/> </xs:complexType> <xs:complexType name="repository"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="summary" type="os:translatableString" minOccurs="1" maxOccurs="unbounded"/> <xs:element name="description" type="os:translatableString" minOccurs="1" maxOccurs="unbounded"/> <xs:element name="url" type="os:mirrorableURL" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="recommended" type="xs:boolean" default="true"/> <xs:attribute name="format" type="xs:string" default="auto"/> <xs:attribute name="producturi" type="xs:string" default="/"/> </xs:complexType> <xs:complexType name="translatableString"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="lang" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:complexType name="mirrorableURL"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="score" type="xs:integer" default="10" /> <xs:attribute name="location" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:complexType name="group"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="summary" type="os:translatableString" minOccurs="0" maxOccurs="1"/> <xs:element name="description" type="os:translatableString" minOccurs="0" maxOccurs="1"/> <xs:element name="remainSubscribed" type="xs:boolean" minOccurs="0" maxOccurs="1"/> <xs:element name="repositories"> <xs:complexType> <xs:sequence> <xs:element name="repository" minOccurs="0" maxOccurs="unbounded" type="os:repository"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="software"> <xs:complexType> <xs:sequence> <xs:element name="item" minOccurs="0" maxOccurs="unbounded" type="os:softwareitem"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="recommended" type="xs:boolean" default="true"/> <xs:attribute name="distversion" type="xs:string"/> </xs:complexType> <xs:element name="metapackage"> <xs:complexType> <xs:sequence> <xs:element name="group" type="os:group" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Sample instance:
<metapackage xmlns:os="http://opensuse.org/Standards/One_Click_Install" xmlns="http://opensuse.org/Standards/One_Click_Install"> <group distversion="openSUSE Factory"> <name>ymp name</name> <summary>ymp summary</summary> <description>ymp description, visible on welcome page</description> <repositories> <repository recommended="true" format="yast"> <name>Main Repository</name> <summary>This is the main openSUSE catalogue</summary> <summary lang="en_US">This is the main openSUSE catalog</summary> <description>This is the main openSUSE package repository containing blah blah blah</description> <description lang="de">Insert German Here</description> <url>http://download.opensuse.org/distribution/SL-OSS-factory/inst-source</url> <url score="5" location="ie">http://ftp.heanet.ie/mirrors/ftp.opensuse.org/opensuse/distribution/SL-OSS-factory/inst-source</url> </repository> <repository recommended="false"> <name>Some Other Repo</name> <summary>Blah Blah</summary> <description>blah blah blah</description> <url>http://example.com</url> </repository> </repositories> <products> <product> <name>MyFavouritePackage</name> <summary>This is my favourite package</summary> <summary lang="en_US">This is my favorite package</summary> <description>Blah blah blah</description> </product> <product type="pattern"> <name>SomePattern</name> <summary>Demo other resolveable</summary> <description>Blah blah blah</description> </product> </products> </group> <group distversion="openSUSE 10.2"> <repositories> <repository> <name>Main Repository</name> <summary>This is the main openSUSE catalogue</summary> <description>This is the main openSUSE package repository containing blah blah blah</description> <url>http://ftp.heanet.ie/mirrors/ftp.opensuse.org/opensuse/distribution/10.2/repo/oss/</url> </repository> </repositories> <software> <item> <name>MyFavouritePackage</name> <summary>This is my favourite package</summary> <summary lang="en_US">This is my favorite package</summary> <description>Blah blah blah</description> </item> </software> </group> </metapackage>
Implementations
A partial implementation was introduced in the betas of openSuse 10.3.