Skip to content

Instantly share code, notes, and snippets.

@baetheus
Last active October 8, 2019 21:10
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save baetheus/9bb5ba6b9d9d980e37d5 to your computer and use it in GitHub Desktop.
Save baetheus/9bb5ba6b9d9d980e37d5 to your computer and use it in GitHub Desktop.

Run Netatalk in a SmartOS zone

This guide is based on this blog post: http://blog.smartcore.net.au/blazingly-fast-afp-on-a-smartos-zone/.

Import image and create virtual machine

Find the latest image, in this case 4166f6d6-ea5f-11e4-addd-8351b159d9b6 (15.1.0), or 24648664-e50c-11e4-be23-0349d0a5f3cf (14.4.1) if you need Long Term Support (LTS).

# imgadm avail | grep base-64
c02a2044-c1bd-11e4-bd8c-dfc1db8b0182  base-64-lts             14.4.0      smartos  2015-03-03T15:55:44Z
24648664-e50c-11e4-be23-0349d0a5f3cf  base-64-lts             14.4.1      smartos  2015-04-17T14:15:04Z
4166f6d6-ea5f-11e4-addd-8351b159d9b6  base-64                 15.1.0      smartos  2015-04-24T08:52:36Z

Import image.

# imgadm import 4166f6d6-ea5f-11e4-addd-8351b159d9b6
Importing 4166f6d6-ea5f-11e4-addd-8351b159d9b6 (base-64@15.1.0) from "https://images.joyent.com"
Gather image 4166f6d6-ea5f-11e4-addd-8351b159d9b6 ancestry
Must download and install 1 image (124.3 MiB)
[...]
Downloaded image 4166f6d6-ea5f-11e4-addd-8351b159d9b6 (124.3 MiB)
[...]
Imported image 4166f6d6-ea5f-11e4-addd-8351b159d9b6 (base-64@15.1.0)

Create virtual machine from the imported image.

# vmadm create << EOL
{
  "alias": "netatalk",
  "hostname": "netatalk",
  "brand": "joyent",
  "image_uuid": "4166f6d6-ea5f-11e4-addd-8351b159d9b6",
  "max_physical_memory": 512,
  "max_locked_memory": 512,
  "max_swap": 1024,
  "quota": 4,
  "filesystems": [
    { "type": "lofs", "source": "/tank/data", "target": "/tank/data" },
    { "type": "lofs", "source": "/tank/archive", "target": "/tank/archive" }
  ],
  "nics": [
    { "nic_tag": "admin", "ip": "10.0.2.1", "netmask": "255.255.0.0", "gateway": "10.0.0.1" }
  ],
  "resolvers": ["8.8.8.8", "8.8.4.4"]
}
EOL
Successfully created VM <uuid>

Login to the newly created virtual machine.

# zlogin <uuid>
[Connected to zone '<uuid>' pts/2]
   __        .                   .
 _|  |_      | .-. .  . .-. :--. |-
|_    _|     ;|   ||  |(.-' |  | |
  |__|   `--'  `-' `;-| `-' '  ' `-'
                   /  ; Instance (base-64 15.1.0)
                   `-'  https://docs.joyent.com/images/smartos/base

Install and configure Netatalk

Set the timezone.

# vim /etc/default/init
TZ=Europe/Stockholm

Update the pkgin package manager.

# pkgin up
reading local summary...
processing local summary...
updating database: 100%
pkg_summary.bz2                                                           100% 1981KB 990.5KB/s   1.5MB/s   00:02    
processing remote summary (http://pkgsrc.joyent.com/packages/SmartOS/2015Q1/x86_64/All)...
updating database: 100%

Install compiler, build tools and cryptographic dependencies.

# pkgin in gcc47 gmake libevent libgcrypt openssl

Download and extract the latest version of Netatalk. This guide uses version 3.1.7. You can find the latest version on this page: http://sourceforge.net/projects/netatalk/files/netatalk/.

# cd ~
# wget http://sourceforge.net/projects/netatalk/files/netatalk/3.1.7/netatalk-3.1.7.tar.gz
# tar xfvz netatalk-3.1.7.tar.gz
# cd netatalk-3.1.7

Configure Netatalk before building.

# ./configure --with-ssl-dir=/opt/local --with-libevent-header=/opt/local --with-libevent-lib=/opt/local --with-libgcrypt --with-bdb=/opt/local --with-init-style=solaris --with-init-dir=/var/svc/manifest/network/ --without-pam --prefix=/opt/local

Create a symbolic link, else compilation will fail.

# ln -s /opt/local/lib /opt/local/lib/64

Build Netatalk.

# make && make install

Configure Netatalk. mimic model sets the icon displayed in Finder. For available options see file: /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist.

# vim /opt/local/etc/afp.conf
[Global]
server name = NAS
log file = /var/log/netatalk.log
uam list = uams_dhx.so,uams_dhx2.so
mimic model = RackMac

[Tank]
path = /tank/data
valid users = user
rwlist = user

[Archive]
path = /tank/archive
valid users = user
rwlist = user

Create user and group and set permissions

Add group.

# groupadd nas

Add user and set password.

# useradd -g nas user
# passwd user

Change ownership of datasets.

# chown -R user:nas /tank/data
# chown -R user:nas /tank/archive

Start services

# svcadm enable svc:/network/dns/multicast:default
# svcadm enable svc:/network/netatalk:default

To do

Add Time Machine support.

I found I needed to add “time machine = yes� to the share section of the netatalk config file to get Time Machine to recognise the share as a valid backup Destination.
Works great with that tweak!
R.
@baetheus
Copy link
Author

This process can now be skipped entirely. In a minimal-64 15.2.0 zone you can:

pkgin in netatalk-3.1.7
mkdir -p /var/db/netatalk/CNID

Using the following /opt/local/etc/netatalk/afp.conf:

[Global]
log file = /var/log/netatalk.log
server name = capsule
uam list = uams_guest.so,uams_dhx.so,uams_dhx2.so
mimic model = TimeCapsule6,116
guest account = capsule

[capsule]
path = /storage/capsule
time machine = yes

And the following smf manifest:

<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='export'>
  <service name='network/netatalk' type='service' version='0'>
    <create_default_instance enabled='false'/>
    <single_instance/>
    <dependency name='network' grouping='require_all' restart_on='error' type='service'>
      <service_fmri value='svc:/milestone/network:default'/>
    </dependency>
    <dependency name='filesystem' grouping='require_all' restart_on='error' type='service'>
      <service_fmri value='svc:/system/filesystem/local'/>
    </dependency>
    <dependency name='mdns' grouping='optional_all' restart_on='error' type='service'>
      <service_fmri value='svc:/network/dns/multicast'/>
    </dependency>
    <method_context/>
    <exec_method name='start' type='method' exec='/opt/local/libexec/netatalk/netatalk' timeout_seconds='60'/>
    <exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
    <property_group name='startd' type='framework'>
      <propval name='duration' type='astring' value='contract'/>
      <propval name='ignore_error' type='astring' value='core,signal'/>
    </property_group>
    <property_group name='application' type='application'>
      <propval name='config_file' type='astring' value='/opt/local/etc/netatalk/afp.conf'/>
    </property_group>
    <stability value='Evolving'/>
    <template>
      <common_name>
        <loctext xml:lang='C'>Netatalk AFP Server</loctext>
      </common_name>
    </template>
  </service>
</service_bundle>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment