Initial commit
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..d46aeb0
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,9 @@
+
+=============
+aptly-formula
+=============
+
+0.0.1
+-----
+
+- Initial commit to Community formula form
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cc41a65
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+
+   Copyright (c) 2013 Salt Stack Formulas
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..baee1fe
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,91 @@
+=====
+Aptly
+=====
+
+Install and configure Aptly server and client.
+
+Available states
+================
+
+.. contents::
+    :local:
+
+``aptly.server``
+----------------
+
+Setup aptly server
+
+``aptly.publisher``
+-------------------
+
+Setup aptly publisher
+
+Available metadata
+==================
+
+.. contents::
+    :local:
+
+``metadata.aptly.server.single``
+--------------------------------
+
+Setup basic server
+
+
+``metadata.aptly.client.publisher``
+-----------------------------------
+
+Setup aptly publisher client
+
+Configuration parameters
+========================
+
+
+Example reclass
+===============
+
+Basic Aptly server with no repos or mirrors.
+
+.. code-block:: yaml
+
+     classes:
+     - service.aptly.server.single
+     parameters:
+        aptly:
+          server:
+            enabled: true
+            secure: true
+            gpg_keypair_id: A76882D3
+            gpg_passphrase:
+            gpg_public_key: |
+              -----BEGIN PGP PUBLIC KEY BLOCK-----
+              Version: GnuPG v1
+              ...
+            gpg_private_key: |
+              -----BEGIN PGP PRIVATE KEY BLOCK-----
+              Version: GnuPG v1
+              ...
+
+Example pillar
+==============
+
+.. code-block:: yaml
+
+     aptly:
+       server:
+         enabled: true
+         repo:
+           myrepo:
+             distribution: trusty
+             component: main
+             architectures: amd64
+             comment: "Custom components"
+             publisher:
+               component: mycomponent
+               distributions:
+                 - nightly/trusty
+
+Read more
+=========
+
+* http://www.aptly.info/doc/configuration/
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..3b04cfb
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.2
diff --git a/aptly/files/aptly-publisher.yaml b/aptly/files/aptly-publisher.yaml
new file mode 100644
index 0000000..1a8c7b3
--- /dev/null
+++ b/aptly/files/aptly-publisher.yaml
@@ -0,0 +1,24 @@
+{%- from "aptly/map.jinja" import server with context %}
+{%- if server.repo %}
+repo:
+{%- for repo_name, repo in server.repo.iteritems() %}
+  {{ repo_name }}:
+    component: {{ repo.publisher.component }}
+    distributions:
+      {%- for distribution in repo.publisher.distributions %}
+      - {{ distribution }}
+      {%- endfor %}
+{%- endfor %}
+{%- endif %}
+
+{%- if server.mirror %}
+mirror:
+{%- for mirror_name, mirror in server.mirror.iteritems() %}
+  {{ mirror_name }}:
+    component: {{ mirror.publisher.component }}
+    distributions:
+      {%- for distribution in mirror.publisher.distributions %}
+      - {{ distribution }}
+      {%- endfor %}
+{%- endfor %}
+{%- endif %}
diff --git a/aptly/files/aptly.conf b/aptly/files/aptly.conf
new file mode 100644
index 0000000..71c206f
--- /dev/null
+++ b/aptly/files/aptly.conf
@@ -0,0 +1,20 @@
+{%- from "aptly/map.jinja" import server with context %}
+{
+  "rootDir": "{{ server.root_dir }}",
+  "downloadConcurrency": 4,
+  "architectures": [ "amd64" ],
+  "dependencyFollowSuggests": false,
+  "dependencyFollowRecommends": false,
+  "dependencyFollowAllVariants": false,
+  "dependencyFollowSource": false,
+  {%- if server.secure %}
+  "gpgDisableSign": false,
+  "gpgDisableVerify": false,
+  {%- else %}
+  "gpgDisableSign": true,
+  "gpgDisableVerify": true,
+  {%- endif %}
+  "downloadSourcePackages": false,
+  "ppaDistributorID": "ubuntu",
+  "ppaCodename": ""
+}
diff --git a/aptly/files/aptly_mirror_update.sh b/aptly/files/aptly_mirror_update.sh
new file mode 100755
index 0000000..e61e7a4
--- /dev/null
+++ b/aptly/files/aptly_mirror_update.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+SCRIPT=$(basename $0)
+MAXTRIES=3
+VERBOSE=0
+SNAPSHOT=0
+
+log_info() {
+	logger -p user.info -t ${SCRIPT} "$*"
+	[ $VERBOSE -eq 1 ] && echo "[INFO] $*"
+}
+
+log_error() {
+	logger -p user.error -t ${SCRIPT} "$*"
+	echo "[ERROR] $*" >&2
+}
+
+if [[ "$*" == *--verbose* || "$*" == *-v* ]]; then
+	VERBOSE=1
+fi
+
+if [[ "$*" == *--snapshot* || "$*" == *-s* ]]; then
+	SNAPSHOT=1
+fi
+
+MIRRORS=$(aptly mirror list --raw 2>&1)
+if [[ $? -ne 0 ]]; then
+	log_error "$MIRRORS"
+	exit 1
+fi
+
+for mirror in $MIRRORS; do
+	try=0
+	retval=666
+
+	while [[ $retval -ne 0 && $try -lt $MAXTRIES ]]; do
+		log_info "Starting update of mirror ${mirror}"
+		if [[ $VERBOSE -eq 0 ]]; then
+			out=$(aptly mirror update -force=true ${mirror} >/dev/null 2>&1)
+		else
+			aptly mirror update -force=true ${mirror}
+		fi
+
+		retval=$?
+
+		if [[ $retval -ne 0 ]]; then
+			try=$[ $try + 1 ]
+			log_error "Failed to update mirror ${mirror}, try=${try}"
+			[ ! -z "$out" ] && log_error "${out}"
+		else
+			log_info "Synced mirror ${mirror}"
+			if [[ $SNAPSHOT -eq 1 ]]; then
+				snapshot_name="${mirror}-$(date +%s)"
+				if [[ $VERBOSE -eq 0 ]]; then
+					out=$(aptly snapshot create ${snapshot_name} from mirror ${mirror} >/dev/null 2>&1)
+				else
+					aptly snapshot create ${snapshot_name} from mirror ${mirror}
+				fi
+
+				retval=$?
+				if [[ $retval -ne 0 ]]; then
+					log_error "Failed to create snapshot ${snapshot_name} from mirror ${mirror}"
+					[ ! -z "$out" ] && log_error "$out"
+				else
+					log_info "Created snapshot ${snapshot_name} from mirror ${mirror}"
+				fi
+			fi
+			break
+		fi
+	done
+done
diff --git a/aptly/files/default-aptly-api b/aptly/files/default-aptly-api
new file mode 100644
index 0000000..aa1c292
--- /dev/null
+++ b/aptly/files/default-aptly-api
@@ -0,0 +1,3 @@
+{%- from "aptly/map.jinja" import api with context %}
+LISTEN_HOST={{ api.bind.host }}
+LISTEN_PORT={{ api.bind.port }}
diff --git a/aptly/files/init.d/aptly-api b/aptly/files/init.d/aptly-api
new file mode 100755
index 0000000..4065e31
--- /dev/null
+++ b/aptly/files/init.d/aptly-api
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+### BEGIN INIT INFO
+# Provides:		aptly-api
+# Required-Start:	$remote_fs $syslog
+# Required-Stop:	$remote_fs $syslog
+# Default-Start:	2 3 4 5
+# Default-Stop:
+# Short-Description:	Aptly API server
+### END INIT INFO
+
+set -e
+
+# /etc/init.d/aptly-api: start and stop Aptly API
+
+[ -f /etc/default/aptly-api ] && . /etc/default/aptly-api
+
+. /lib/lsb/init-functions
+
+COMMAND=${COMMAND:-"/usr/bin/aptly"}
+COMMAND_ARGS=${COMMAND_ARGS:-"api serve"}
+LISTEN_HOST=${LISTEN_HOST:-"127.0.0.1"}
+LISTEN_PORT=${LISTEN_PORT:-"8080"}
+
+APTLY_USER=${APTLY_USER:-aptly}
+PIDFILE=${PIDFILE:-/var/run/aptly-api.pid}
+
+function check_running() {
+	start-stop-daemon -T --pidfile ${PIDFILE}
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		log_end_msg 1 || true
+		exit $ret
+	fi
+}
+
+function start() {
+	# Get slave.jar from master
+	if start-stop-daemon -c ${APTLY_USER} --background --start --quiet \
+		--oknodo -m --pidfile ${PIDFILE} --exec ${COMMAND} -- ${COMMAND_ARGS} \
+		-listen=${LISTEN_HOST}:${LISTEN_PORT}; then
+		log_end_msg 0 || true
+	else
+		log_end_msg 1 || true
+	fi
+}
+
+function stop() {
+	if start-stop-daemon --stop --quiet --oknodo --pidfile ${PIDFILE}; then
+		log_end_msg 0 || true
+	else
+		log_end_msg 1 || true
+	fi
+}
+
+case "$1" in
+	start)
+		log_daemon_msg "Starting Aptly API" "aptly-api" || true
+		start
+		;;
+	stop)
+		log_daemon_msg "Stopping Aptly API" "aptly-api" || true
+		stop
+		;;
+	status)
+		status_of_proc -p ${PIDFILE} ${COMMAND} aptly-api && exit 0 || exit $?
+		;;
+	restart)
+		log_daemon_msg "Restarting Aptly API" "aptly-api" || true
+		stop
+		start
+		;;
+
+	*)
+		log_action_msg "Usage: /etc/init.d/aptly-api {start|stop|restart|status}" || true
+		exit 1
+		;;
+esac
+
+exit 0
diff --git a/aptly/files/nginx.conf b/aptly/files/nginx.conf
new file mode 100644
index 0000000..426b1a6
--- /dev/null
+++ b/aptly/files/nginx.conf
@@ -0,0 +1,11 @@
+{%- set site = salt['pillar.get']('nginx:server:site:'+site_name) %}
+{%- from "aptly/map.jinja" import server with context %}
+
+server {
+  {%- include "nginx/files/_name.conf" %}
+  {%- include "nginx/files/_log.conf" %}
+  root {{ server.root_dir }}/public;
+  location / {
+    autoindex on;
+  }
+}
diff --git a/aptly/init.sls b/aptly/init.sls
new file mode 100644
index 0000000..94d4796
--- /dev/null
+++ b/aptly/init.sls
@@ -0,0 +1,11 @@
+
+include:
+{%- if pillar.aptly.server is defined %}
+- aptly.server
+{%- endif %}
+{%- if pillar.aptly.api is defined %}
+- aptly.server.api
+{%- endif %}
+{%- if pillar.aptly.publisher is defined %}
+- aptly.publisher
+{%- endif %}
diff --git a/aptly/map.jinja b/aptly/map.jinja
new file mode 100644
index 0000000..402bfaf
--- /dev/null
+++ b/aptly/map.jinja
@@ -0,0 +1,15 @@
+
+{%- set server = salt['grains.filter_by']({
+  'Debian': {
+    'pkgs': ['aptly', 'bzip2'],
+    'home_dir': '/var/lib/aptly',
+    'root_dir': '/srv/aptly',
+    'secure': True,
+    'repo': {},
+    'gpg_keypair_id': '',
+    'gpg_passphrase': ''
+  },
+}, merge=salt['pillar.get']('aptly:server')) %}
+
+{%- set api=salt['pillar.get']('aptly:api') %}
+{%- set publisher=salt['pillar.get']('aptly:publisher') %}
diff --git a/aptly/publisher.sls b/aptly/publisher.sls
new file mode 100644
index 0000000..e0404a1
--- /dev/null
+++ b/aptly/publisher.sls
@@ -0,0 +1,17 @@
+{%- from "aptly/map.jinja" import publisher with context %}
+{%- if publisher.enabled %}
+
+publisher_packages:
+  pkg.latest:
+  - names: ['python-aptly']
+
+publisher_yaml:
+  file.managed:
+  - name: /etc/aptly-publisher.yaml
+  - source: salt://aptly/files/aptly-publisher.yaml
+  - template: jinja
+  - user: root
+  - group: root
+  - mode: 664
+
+{% endif %}
diff --git a/aptly/server/api.sls b/aptly/server/api.sls
new file mode 100644
index 0000000..64337e4
--- /dev/null
+++ b/aptly/server/api.sls
@@ -0,0 +1,36 @@
+{%- from "aptly/map.jinja" import api with context %}
+{%- if api.enabled %}
+
+include:
+  - aptly.server
+
+aptly_api_init_script:
+  file.managed:
+    - name: /etc/init.d/aptly-api
+    - source: salt://aptly/files/init.d/aptly-api
+    - user: root
+    - group: root
+    - mode: 755
+    - template: jinja
+    - require:
+      - pkg: aptly_packages
+
+aptly_api_config:
+  file.managed:
+    - name: /etc/default/aptly-api
+    - source: salt://aptly/files/default-aptly-api
+    - user: root
+    - group: root
+    - mode: 644
+    - template: jinja
+
+aptly_api_service:
+  service.running:
+  - name: aptly-api
+  - watch:
+    - file: aptly_api_init_script
+    - file: aptly_api_config
+    - file: aptly_conf
+    - pkg: aptly_packages
+
+{%- endif %}
diff --git a/aptly/server/init.sls b/aptly/server/init.sls
new file mode 100644
index 0000000..41c8446
--- /dev/null
+++ b/aptly/server/init.sls
@@ -0,0 +1,129 @@
+{%- from "aptly/map.jinja" import server with context %}
+{%- if server.enabled %}
+
+{% set gpgprivfile = '{}/.gnupg/secret.gpg'.format(server.home_dir) %}
+{% set gpgpubfile = '{}/public/public.gpg'.format(server.root_dir) %}
+
+include:
+- aptly.server.repos
+- aptly.server.mirrors
+
+aptly_packages:
+  pkg.installed:
+  - names: {{ server.pkgs }}
+  - refresh: true
+
+aptly_user:
+  user.present:
+  - name: aptly
+  - shell: /bin/bash
+  - home: {{ server.home_dir }}
+  - require:
+    - pkg: aptly_packages
+
+aptly_home_dir:
+  file.directory:
+  - name: {{ server.home_dir }}
+  - user: aptly
+  - group: aptly
+  - mode: 755
+  - require:
+    - user: aptly_user
+
+aptly_root_dir:
+  file.directory:
+  - name: {{ server.root_dir }}
+  - user: aptly
+  - group: aptly
+  - mode: 755
+  - require:
+    - user: aptly_user
+
+aptly_pub_dir:
+  file.directory:
+  - name: {{ server.root_dir }}/public
+  - user: aptly
+  - group: aptly
+  - require:
+    - file: aptly_home_dir
+
+aptly_conf:
+  file.managed:
+  - name: {{ server.home_dir }}/.aptly.conf
+  - source: salt://aptly/files/aptly.conf
+  - template: jinja
+  - user: aptly
+  - group: aptly
+  - mode: 664
+  - require:
+    - file: aptly_pub_dir
+
+aptly_mirror_update_script:
+  file.managed:
+  - name: /usr/local/bin/aptly_mirror_update.sh
+  - source: salt://aptly/files/aptly_mirror_update.sh
+  - user: root
+  - group: root
+  - mode: 755
+
+{%- if server.secure %}
+
+aptly_gpg_key_dir:
+  file.directory:
+  - name: {{ server.home_dir }}/.gnupg
+  - user: aptly
+  - group: aptly
+  - mode: 700
+  - require:
+    - file: aptly_home_dir
+
+
+gpg_priv_key:
+  file.managed:
+  - name: {{ gpgprivfile }}
+  - contents_pillar: aptly:server:gpg_private_key
+  - user: aptly
+  - group: aptly
+  - mode: 600
+  - require:
+    - file: aptly_gpg_key_dir
+
+gpg_pub_key:
+  file.managed:
+  - name: {{ gpgpubfile }}
+  - contents_pillar: aptly:server:gpg_public_key
+  - user: aptly
+  - group: aptly
+  - mode: 644
+  - require:
+    - file: aptly_gpg_key_dir
+
+import_gpg_pub_key:
+  cmd.run:
+  - name: gpg --no-tty --import {{ gpgpubfile }}
+  - user: aptly
+  - unless: gpg --no-tty --list-keys | grep '{{ server.gpg_keypair_id }}'
+  - require:
+    - file: aptly_gpg_key_dir
+
+import_gpg_priv_key:
+  cmd.run:
+  - name: gpg --no-tty --allow-secret-key-import --import {{ gpgprivfile }}
+  - user: aptly
+  - unless: gpg --no-tty --list-secret-keys | grep '{{ server.gpg_keypair_id }}'
+  - require:
+    - file: aptly_gpg_key_dir
+
+{%- endif %}
+
+{#
+  FIXME: Hack to be able to use aptly commands when API server is running
+  https://github.com/smira/aptly/issues/234
+
+aptly_clean_lock:
+  file.absent:
+    - name: /srv/aptly/db/LOCK
+#}
+
+{%- endif %}
+
diff --git a/aptly/server/mirrors.sls b/aptly/server/mirrors.sls
new file mode 100644
index 0000000..c147231
--- /dev/null
+++ b/aptly/server/mirrors.sls
@@ -0,0 +1,84 @@
+{%- from "aptly/map.jinja" import server with context %}
+
+{%- if server.mirror_update.enabled %}
+
+aptly_mirror_update_cron:
+  cron.present:
+  - name: service aptly-api stop;sleep 5;su aptly -c '/usr/local/bin/aptly_mirror_update.sh -s';service aptly-api start
+  - identifier: aptly_mirror_update
+  - hour: "{{ server.mirror_update.hour }}"
+  - minute: "{{ server.mirror_update.minute }}"
+  - user: root
+  - require:
+    - file: aptly_mirror_update_script
+    - user: aptly_user
+
+cron_path:
+  cron.env_present:
+    - name: PATH
+    - value: "/bin:/sbin:/usr/bin:/usr/sbin"
+
+{%- else %}
+
+aptly_mirror_update_cron:
+  cron.absent:
+  - identifier: aptly_mirror_update
+  - user: root
+
+{% endif %}
+
+
+{%- if server.mirror is defined %}
+
+{%- for mirror_name, mirror in server.mirror.iteritems() %}
+
+{%- for gpgkey in server.mirror[mirror_name].gpgkeys %}
+
+gpg_add_keys_{{ mirror_name }}_{{ gpgkey }}:
+  cmd.run:
+  - name: gpg --no-tty --no-default-keyring --keyring trustedkeys.gpg --keyserver keys.gnupg.net --recv-keys {{ gpgkey }}
+  - user: aptly
+  - unless: gpg --no-tty --no-default-keyring --keyring trustedkeys.gpg --list-public-keys {{gpgkey}}
+
+{%- endfor %}
+
+{%- if server.mirror[mirror_name].snapshots is defined %}
+{%- for snapshot in server.mirror[mirror_name].snapshots %}
+
+aptly_addsnapshot_{{ mirror_name }}_{{ snapshot }}:
+  cmd.run:
+  - name: aptly snapshot create {{ snapshot }} from mirror {{ mirror_name }}
+  - user: aptly
+  - unless: aptly snapshot show {{ snapshot }}
+  - require:
+    - cmd: aptly_{{ mirror_name }}_update
+
+{%- endfor %}
+{%- endif %}
+
+
+aptly_{{ mirror_name }}_mirror:
+  cmd.run:
+  - name: aptly mirror create -architectures={{ mirror.architectures }} {{ mirror_name }} {{ mirror.source }} {{ mirror.distribution }} {{ mirror.components }}
+  - user: aptly
+  - unless: aptly mirror show {{ mirror_name }}
+
+{%- if mirror.update is defined and mirror.update == True %}
+aptly_{{ mirror_name }}_update:
+  cmd.run:
+  - name: aptly mirror update {{ mirror_name }}
+  - user: aptly
+  - require:
+    - cmd: aptly_{{ mirror_name }}_mirror
+{%- endif %}
+
+{%- if server.mirror[mirror_name].publish is defined %}
+aptly_publish_{{ server.mirror[mirror_name].publish }}_snapshot:
+  cmd.run:
+  - name: aptly publish snapshot -batch=true -gpg-key='{{ server.gpg_keypair_id }}' -passphrase='{{ server.gpg_passphrase }}' {{ server.mirror[mirror_name].publish }}
+  - user: aptly
+{% endif %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/aptly/server/repos.sls b/aptly/server/repos.sls
new file mode 100644
index 0000000..981508d
--- /dev/null
+++ b/aptly/server/repos.sls
@@ -0,0 +1,40 @@
+{%- from "aptly/map.jinja" import server with context %}
+
+{%- for repo_name, repo in server.repo.iteritems() %}
+
+aptly_{{ repo_name }}_repo_create:
+  cmd.run:
+  - name: aptly repo create -distribution="{{ repo.distribution }}" -component="{{ repo.component }}" -architectures="{{ repo.architectures }}" -comment="{{ repo.comment }}" {{ repo_name }}
+  - unless: aptly repo show {{ repo_name }}
+  - user: aptly
+  - require:
+    - file: aptly_conf
+
+{%- if repo.pkg_dir is defined and repo.pkg_dir %}
+
+pkgdir:
+  file.directory:
+  - name: {{ repo.pkg_dir }}
+  - user: aptly
+  - group: aptly
+  - makedirs: true
+
+aptly_{{ repo_name }}_pkgs_add:
+  cmd.run:
+  - name: aptly repo add {{ repo_name }} {{ repo.pkg_dir }}
+  - user: aptly
+  - require:
+    - cmd: aptly_{{ repo_name }}_repo_create
+    - file: pkgdir
+
+{%- endif %}
+
+{%- if repo.publish is defined and repo.publish == True %}
+aptly_{{ repo_name }}_repo_publish:
+  cmd.run:
+  - name: aptly publish repo -batch=true -gpg-key='{{ server.gpg_keypair_id }}' -passphrase='{{ server.gpg_passphrase }}' {{ repo_name }}
+  - user: aptly
+  - unless: aptly publish update -batch=true -gpg-key='{{ server.gpg_keypair_id }}' -passphrase='{{ server.gpg_passphrase }}' {{ repo.distribution }}
+{%- endif %}
+
+{%- endfor %}
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..ffa375d
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,11 @@
+salt-formula-aptly (0.2) trusty; urgency=medium
+
+  * First public release
+
+ -- Filip Pytloun <filip.pytloun@tcpcloud.eu>  Tue, 06 Oct 2015 16:38:36 +0200
+
+salt-formula-aptly (0.1) trusty; urgency=medium
+
+  * Initial release
+
+ -- Filip Pytloun <filip.pytloun@tcpcloud.eu>  Thu, 13 Aug 2015 23:23:41 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..101a26d
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,15 @@
+Source: salt-formula-aptly
+Maintainer: Filip Pytloun <filip.pytloun@tcpcloud.eu>
+Section: admin
+Priority: optional
+Build-Depends: debhelper (>= 9)
+Standards-Version: 3.9.6
+Homepage: http://www.tcpcloud.eu
+Vcs-Browser: https://github.com/tcpcloud/salt-formula-aptly
+Vcs-Git: https://github.com/tcpcloud/salt-formula-aptly.git
+
+Package: salt-formula-aptly
+Architecture: all
+Depends: ${misc:Depends}, salt-master, reclass
+Description: Aptly Salt formula
+ Install and configure Aptly server and relay.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..ff79276
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,15 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: salt-formula-aptly
+Upstream-Contact: Filip Pytloun <filip.pytloun@tcpcloud.eu>
+Source: https://github.com/tcpcloud/salt-formula-aptly
+
+Files: *
+Copyright: 2014-2015 tcp cloud
+License: Apache-2.0
+  Copyright (C) 2014-2015 tcp cloud
+  .
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  .
+  On a Debian system you can find a copy of this license in
+  /usr/share/common-licenses/Apache-2.0.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..d585829
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,3 @@
+README.rst
+CHANGELOG.rst
+VERSION
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..a686926
--- /dev/null
+++ b/debian/install
@@ -0,0 +1,2 @@
+aptly/*             /usr/share/salt-formulas/env/aptly/
+metadata/service/*  /usr/share/salt-formulas/reclass/service/aptly/
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..abde6ef
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,5 @@
+#!/usr/bin/make -f
+
+%:
+	dh $@
+
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/metadata/service/client/publisher.yml b/metadata/service/client/publisher.yml
new file mode 100644
index 0000000..99096fd
--- /dev/null
+++ b/metadata/service/client/publisher.yml
@@ -0,0 +1,6 @@
+applications:
+- aptly.publisher
+parameters:
+  aptly:
+    publisher:
+      enabled: true
diff --git a/metadata/service/server/single.yml b/metadata/service/server/single.yml
new file mode 100644
index 0000000..d38d34e
--- /dev/null
+++ b/metadata/service/server/single.yml
@@ -0,0 +1,18 @@
+applications:
+- aptly
+parameters:
+  aptly:
+    server:
+      enabled: true
+      gpg_passphrase: ${_param:aptly_gpg_passphrase}
+      mirror_update:
+        enabled: true
+        hour: '*/12'
+        minute: 0
+    api:
+      enabled: true
+      bind:
+        host: 127.0.0.1
+        port: 8080
+    publisher:
+      enabled: true