unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* WSDD Service Module
@ 2022-01-19  9:29 Simon Streit
  2022-01-24 15:46 ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Simon Streit @ 2022-01-19  9:29 UTC (permalink / raw)
  To: guix-devel

Hello!

I've been preparing WSDD [1] for Guix.  This is a Web Service Discovery
Daemon that replaces host discovery through SMBv1.  SMBv1 has been
disabled in Samba and Windows for some time now for security reasons.
Hence WSDD is a drop in replacement for host discovery.

I've packaged wsdd already, and while preparing this post I noticed that the
version is already outdated too.  That's next on the list now.

Unfortunately while preparing its service, there is this one part that
I'm having trouble trying to get working:
--8<---------------cut here---------------start------------->8---
#$(if interface
      #~(for-each (lambda (arg)
                    (display (string-append "--interface" arg))
                    ;; (format #t "--interface ~a " (list->string arg))
                    )
                  #$(interface))
      '())
--8<---------------cut here---------------end--------------->8---

Which is the main intention for this post: I'd really appreciate a little
hint on how to solve this small problem.  Everything else looks okay.

The documentation for this service module has not been completed yet.
I'm still working on it.  Once it is done I'll submit a patch.  This is
part of my ongoing work on working with samba.

The service declaration can be found at [2] and [3] is the package
itself.


Thanks in advance!
Simon


[1] https://github.com/christgau/wsdd
[2] https://git.steel-is-real.com/siguix/tree/siguix/services/wsdd.scm?h=wip-wsdd&id=f125d84ef57a555b389d7bafa54b7352bf8faa74
[3] https://git.steel-is-real.com/siguix/tree/siguix/packages/wsdd.scm?h=wip-wsdd


^ permalink raw reply	[flat|nested] 6+ messages in thread

* WSDD Service Module
@ 2022-01-21 11:51 Simon Streit
  0 siblings, 0 replies; 6+ messages in thread
From: Simon Streit @ 2022-01-21 11:51 UTC (permalink / raw)
  To: guix-devel

Hello!

I've been preparing WSDD [1] for Guix.  This is a Web Service Discovery
Daemon that replaces host discovery through SMBv1.  SMBv1 has been
disabled in Samba and Windows for some time now for security reasons.
Hence WSDD is a drop in replacement for host discovery.

I've packaged wsdd already, and while preparing this post I noticed that the
version is already outdated too.  That's next on the list now.

Unfortunately while preparing its service, there is this one part that
I'm having trouble trying to get working:
--8<---------------cut here---------------start------------->8---
#$(if interface
      #~(for-each (lambda (arg)
                    (display (string-append "--interface" arg))
                    ;; (format #t "--interface ~a " (list->string arg))
                    )
                  #$(interface))
      '())
--8<---------------cut here---------------end--------------->8---

Which is the main intention for this post: I'd really appreciate a little
hint on how to solve this small problem.  Everything else looks okay.

The documentation for this service module has not been completed yet.
I'm still working on it.  Once it is done I'll submit a patch.  This is
part of my ongoing work with samba.

The service declaration can be found at [2] and [3] is the package
itself.


Thanks in advance!
Simon


[1] https://github.com/christgau/wsdd
[2] https://git.steel-is-real.com/siguix/tree/siguix/services/wsdd.scm?h=wip-wsdd&id=f125d84ef57a555b389d7bafa54b7352bf8faa74
[3] https://git.steel-is-real.com/siguix/tree/siguix/packages/wsdd.scm?h=wip-wsdd


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: WSDD Service Module
  2022-01-19  9:29 Simon Streit
@ 2022-01-24 15:46 ` Ludovic Courtès
  2022-01-25 12:56   ` Simon Streit
       [not found]   ` <ygu8rv4ouls.fsf@netpanic.org>
  0 siblings, 2 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-01-24 15:46 UTC (permalink / raw)
  To: Simon Streit; +Cc: guix-devel

Hi,

Simon Streit <simon@netpanic.org> skribis:

> Unfortunately while preparing its service, there is this one part that
> I'm having trouble trying to get working:
>
> #$(if interface
>       #~(for-each (lambda (arg)
>                     (display (string-append "--interface" arg))
>                     ;; (format #t "--interface ~a " (list->string arg))
>                     )
>                   #$(interface))
>       '())
>
> Which is the main intention for this post: I'd really appreciate a little
> hint on how to solve this small problem.  Everything else looks okay.

My understanding is that you intend the ‘interface’ field to be either
#f or a string, is that right?

When you write:

  (interface)

that means: “call the procedure bound to ‘interface’, passing it zero
arguments”.  However, if ‘interface’ is a string, you cannot call it, so
you get a wrong-type-to-apply error.

Likewise, ‘for-each’ expects its second argument to be a list.  But
here, ‘interface’ is supposedly a string, not a list, so if you do:

  (for-each (lambda …) interface)

you’ll get a wrong-type-argument error.

HTH!

Ludo’.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: WSDD Service Module
  2022-01-24 15:46 ` Ludovic Courtès
@ 2022-01-25 12:56   ` Simon Streit
       [not found]   ` <ygu8rv4ouls.fsf@netpanic.org>
  1 sibling, 0 replies; 6+ messages in thread
From: Simon Streit @ 2022-01-25 12:56 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 2319 bytes --]


Hello, thanks for your reply.

Ludovic Courtès <ludo@gnu.org> writes:
> My understanding is that you intend the ‘interface’ field to be either
> #f or a string, is that right?

I think it rather be a list of strings, since wsdd takes the list of
interfaces to listen to.  So it should expand to --interface eth0
--interface eth1, etc.

> When you write:
>
>   (interface)
>
> that means: “call the procedure bound to ‘interface’, passing it zero
> arguments”.  However, if ‘interface’ is a string, you cannot call it, so
> you get a wrong-type-to-apply error.
>
> Likewise, ‘for-each’ expects its second argument to be a list.  But
> here, ‘interface’ is supposedly a string, not a list, so if you do:
>
>   (for-each (lambda …) interface)
>
> you’ll get a wrong-type-argument error.

So I changed it, that interface is usually an empty list now, and with
for-each I'd like to have it expanded.  Good thing is, I've gotten at
least a step further, but only after hard coding the list as an argument
in the for-each expression.  So it should work?  It still doesn't.  And
I still don't understand how it is somehow not passed as a list
properly.

One thing I noticed, after hard coding the argument, the procedure is
not properly expanded in the constructor.  How come?  This is the output
in the service file:
--8<---------------cut here---------------start------------->8---
(make-forkexec-constructor
 (list "/gnu/store/6jpn21wnnyz59ii634hfbk34yy48nxrq-wsdd-0.6.4/bin/wsdd" "--hoplimit" "1" for-each
       (lambda
           (arg)
         (format #t "--interface ~s "
                 (arg)))
       (interface)
       "--workgroup" "WORKGROUP")
 #:user "wsdd" #:group "wsdd" #:log-file "/var/log/wsdd.log")
--8<---------------cut here---------------end--------------->8---

My for-each procedure and list works in my REPL, but it fails in Guix.
It might have to do with me trying to get on with
make-forkexec-constructor.  So this constructor needs a list of strings?
I put interfaces into a let*, and would call it in the constructor.
Unfortunately this results into an invalid G-expression.


Thanks for you help.  It is taking its time to get comfortable with
Guile.

I've attached the current state of the service too.


[-- Attachment #2: wsdd.scm --]
[-- Type: application/octet-stream, Size: 8140 bytes --]

(define-module (services samba)

  #:use-module (gnu packages)
  #:use-module (gnu packages base)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages samba)

  #:use-module (gnu services)
  #:use-module (gnu services configuration)
  #:use-module (gnu services shepherd)
  #:use-module (gnu services base)
  #:use-module (gnu system shadow)

  #:use-module (guix gexp)
  #:use-module (guix packages)
  #:use-module (guix modules)
  #:use-module (guix records)

  #:use-module (ice-9 format)
  #:use-module (ice-9 match)
  #:use-module (ice-9 textual-ports)
  #:use-module (srfi srfi-1)

  #:export (wsdd-service
            wsdd-service-type
            wsdd-configuration
            wsdd-configuration?
            wsdd-configuration-package
            wsdd-configuration-ipv4only?
            wsdd-configuration-ipv6only?
            wsdd-configuration-chroot
            wsdd-configuration-hoplimit
            wsdd-configuration-interface
            wsdd-configuration-uuid-device
            wsdd-configuration-domain
            wsdd-configuration-hostname
            wsdd-configuration-preserve-case?
            wsdd-configuration-workgroup))

\f
;;;
;;; WSDD
;;;

(define-record-type* <wsdd-configuration>
  wsdd-configuration
  make-wsdd-configuration
  wsdd-configuration?
  (package               wsdd-configuration-package
                         (default wsdd))
  (ipv4only?             wsdd-configuration-ipv4only?
                         (default #f))
  (ipv6only?             wsdd-configuration-ipv6only?
                         (default #f))
  (chroot                wsdd-configuration-chroot
                         (default #f))
  (hoplimit              wsdd-configuration-hoplimit
                         (default 1))
  (interface             wsdd-configuration-interface
                         (default '()))
  (uuid-device           wsdd-configuration-uuid-device
                         (default #f))
  (domain                wsdd-configuration-domain
                         (default #f))
  (hostname              wsdd-configuration-hostname
                         (default #f))
  (preserve-case?        wsdd-configuration-preserve-case?
                         (default #f))
  (workgroup             wsdd-configuration-workgroup
                         (default "WORKGROUP")))

(define wsdd-accounts
  (list
   (user-group (name "wsdd"))
   (user-account (name "wsdd")
                 (group "wsdd")
                 (comment "Web Service Discovery user")
                 (home-directory "/var/empty")
                 (shell (file-append shadow "/sbin/nologin")))))

(define wsdd-shepherd-service
  (match-lambda
    (($ <wsdd-configuration> package
                             ipv4only?
                             ipv6only?
                             chroot
                             hoplimit
                             interface
                             uuid-device
                             domain
                             hostname
                             preserve-case?
                             workgroup
                             )
     (let* ((interfaces (for-each (lambda (interface)
                                    ;; (display (string-append "--interface" interface))
                                    (format #t "--interface ~s " interface))
                                  '("eth0" "eth1"))))
       (list (shepherd-service
              (documentation "Run a Web Service Discovery service")
              (provision '(wsdd))
              (requirement '(networking))
              (start #~(make-forkexec-constructor
                        (list #$(file-append package "/bin/wsdd")
                              #$@(if ipv4only?
                                     #~("--ipv4only")
                                     '())
                              #$@(if ipv6only?
                                     #~("--ipv6only")
                                     '())
                              #$@(if chroot
                                     #~("--chroot" #$chroot)
                                     '())
                              #$@(if hoplimit
                                     #~("--hoplimit" #$(number->string hoplimit))
                                     '())

                              ;; FIXME, this results into wrong type applied.
                              ;; #$(if interface
                              ;;       (for-each (lambda (interface)
                              ;;                   (display (string-append "--interface" interface))
                              ;;                   ;; (format #t "--interface ~a " interface)
                              ;;                   )
                              ;;                 '("eth1" "eth2")))

                              ;; this one is fine, but the for-each
                              ;; expression is not expanded and is
                              ;; kept in place in the service unit.
                              ;; See end of this file.
                              #$@(if interface
                                     #~(for-each (lambda (interface)
                                                 ;; (display (string-append "--interface" interface))
                                                 (format #t "--interface ~s " interface
                                                         ;; (list->string arg)
                                                         ))
                                               '("eth0" "eth1"))
                                     '())

                              ;; #$interfaces

                              ;; #$@(if interface
                              ;;        #~(for-each (lambda (interface)
                              ;;                      ;; (display (string-append "--interface" interface))
                              ;;                      (format #t "--interface ~s " interface))
                              ;;                    '("eth0" "eth1"))
                              ;;        '())

                              ;; #$(for-each (lambda (interface)
                              ;;               (display (string-append "--interface" interface))
                              ;;               ;; (format #f "--interface ~s " interface
                              ;;               ;;         ;; (list->string arg)
                              ;;               ;;         )
                              ;;               )
                              ;;             '("eth0" "eth1"))

                              ;; #$@(if interface ;to be replaced by procedure above
                              ;;        #~("--interface" #$interface)
                              ;;        '())

                              #$@(if uuid-device
                                     #~("--uuid" #$uuid-device)
                                     '())
                              #$@(if domain
                                     #~("--domain" #$domain)
                                     '())
                              #$@(if hostname
                                     #~("--hostname" #$hostname)
                                     '())
                              #$@(if preserve-case?
                                     #~("--preserve-case")
                                     '())
                              #$@(if workgroup
                                     #~("--workgroup" #$workgroup)
                                     '()))
                        #:user "wsdd"
                        #:group "wsdd"
                        #:log-file "/var/log/wsdd.log"))
              (stop #~(make-kill-destructor))))))))

(define wsdd-service-type
  (service-type
   (name 'wsdd)
   (description "Web Service Discovery Daemon")
   (extensions
    (list (service-extension shepherd-root-service-type
                             wsdd-shepherd-service)
          (service-extension account-service-type
                             (const wsdd-accounts))))
   (default-value (wsdd-configuration))))

[-- Attachment #3: Type: text/plain, Size: 21 bytes --]



Kind regards
Simon

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: WSDD Service Module
       [not found]   ` <ygu8rv4ouls.fsf@netpanic.org>
@ 2022-01-25 13:56     ` Ludovic Courtès
  2022-01-25 19:10       ` Simon Streit
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2022-01-25 13:56 UTC (permalink / raw)
  To: Simon Streit; +Cc: Guix Devel

Hi,

(+Cc: guix-devel.)

Simon Streit <simon@netpanic.org> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:
>> My understanding is that you intend the ‘interface’ field to be either
>> #f or a string, is that right?
>
> I think it rather be a list of strings,

Then I recommend calling it ‘interfaces’ (plural).

>> When you write:
>>
>>   (interface)
>>
>> that means: “call the procedure bound to ‘interface’, passing it zero
>> arguments”.  However, if ‘interface’ is a string, you cannot call it, so
>> you get a wrong-type-to-apply error.
>>
>> Likewise, ‘for-each’ expects its second argument to be a list.  But
>> here, ‘interface’ is supposedly a string, not a list, so if you do:
>>
>>   (for-each (lambda …) interface)
>>
>> you’ll get a wrong-type-argument error.
>
> So I changed it, that interface is usually an empty list now, and with
> for-each I'd like to have it expanded.  Good thing is, I've gotten at
> least a step further, but only after hard coding the list as an argument
> in the for-each expression.  So it should work?  It still doesn't.  And
> I still don't understand how it is somehow not passed as a list
> properly.  
>
> One thing I noticed, after hard coding the argument, the procedure is
> not properly expanded in the constructor.  How come?  This is the output
> in the service file:
>
> (make-forkexec-constructor
>  (list "/gnu/store/6jpn21wnnyz59ii634hfbk34yy48nxrq-wsdd-0.6.4/bin/wsdd" "--hoplimit" "1" for-each
>        (lambda
>            (arg)
>          (format #t "--interface ~s "
>                  (arg)))
>        (interface)
>        "--workgroup" "WORKGROUP")
>  #:user "wsdd" #:group "wsdd" #:log-file "/var/log/wsdd.log")

This reads “(interface)”, meaning that (1) ‘interface’ must be a
procedure, since you’re calling it, and (2) ‘interface’ must be bound
(the variable must be defined there).

However, ‘interface’ is unbound here.  You probably meant to write,
within your gexp:

  #~(make-forkexec-constructor
      … #$@(map (lambda …) interfaces)
      …)

which would expand to:

  (make-forkexec-constructor
    … "--interface=eth0" "--interface=eth1"
    …)

The #$@ bit (‘ungexp-splicing’) means that the (map …) bit executes
beforehand and that its results is staged in that generated shepherd
file.

HTH,
Ludo’.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: WSDD Service Module
  2022-01-25 13:56     ` Ludovic Courtès
@ 2022-01-25 19:10       ` Simon Streit
  0 siblings, 0 replies; 6+ messages in thread
From: Simon Streit @ 2022-01-25 19:10 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Guix Devel

Ludovic Courtès <ludo@gnu.org> writes:

> (+Cc: guix-devel.)

Hope I get it right this time.

> Then I recommend calling it ‘interfaces’ (plural).

Will do.

>   #~(make-forkexec-constructor
>       … #$@(map (lambda …) interfaces)
>       …)
>
> which would expand to:
>
>   (make-forkexec-constructor
>     … "--interface=eth0" "--interface=eth1"
>     …)

Yes this makes more sense, and it works too!  I got too focused
on trying to use for-each.

Time to complete this service.


Thanks a lot!
Simon


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-01-25 19:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-21 11:51 WSDD Service Module Simon Streit
  -- strict thread matches above, loose matches on Subject: below --
2022-01-19  9:29 Simon Streit
2022-01-24 15:46 ` Ludovic Courtès
2022-01-25 12:56   ` Simon Streit
     [not found]   ` <ygu8rv4ouls.fsf@netpanic.org>
2022-01-25 13:56     ` Ludovic Courtès
2022-01-25 19:10       ` Simon Streit

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).