Skip to content

Commit 0aafb0d

Browse files
authored
feat(pkg/board): add is board set (#627)
1 parent 00a672c commit 0aafb0d

File tree

5 files changed

+140
-8
lines changed

5 files changed

+140
-8
lines changed

adbd.Dockerfile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
FROM debian:trixie
22

33
RUN apt-get update \
4-
&& apt-get install -y --no-install-recommends adbd file openssh-server \
4+
&& apt-get install -y --no-install-recommends adbd file ssh sudo \
55
&& apt-get clean \
66
&& rm -rf /var/lib/apt/lists/*
77

8-
RUN useradd -m -s /bin/bash arduino && \
9-
echo "arduino:arduino" | chpasswd
10-
RUN mkdir /home/arduino/ArduinoApps && \
11-
chown arduino:arduino /home/arduino/ArduinoApps
8+
RUN useradd -m --create-home --shell /bin/bash --user-group --groups sudo arduino && \
9+
echo "arduino:arduino" | chpasswd && \
10+
mkdir /home/arduino/ArduinoApps && \
11+
chown -R arduino:arduino /home/arduino/ArduinoApps
1212

1313
WORKDIR /home/arduino
1414
EXPOSE 22
1515

16-
CMD ["/bin/sh", "-c", "/usr/sbin/sshd -D & adbd"]
16+
CMD ["/bin/sh", "-c", "/usr/sbin/sshd -D & su arduino -c adbd"]

cmd/arduino-app-cli/board/board.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"path"
7+
"strconv"
78

89
"github.com/spf13/cobra"
910

@@ -111,16 +112,28 @@ func newBoardListCmd() *cobra.Command {
111112
RunE: func(cmd *cobra.Command, args []string) error {
112113
boards := cmd.Context().Value(boardsListKey).([]board.Board)
113114
for _, b := range boards {
114-
var address string
115+
116+
var address, configured string
115117
switch b.Protocol {
116118
case board.SerialProtocol, board.LocalProtocol:
117119
address = b.Serial
120+
121+
if conn, err := b.GetConnection(); err != nil {
122+
return fmt.Errorf("failed to connect to board %s: %w", b.BoardName, err)
123+
} else {
124+
if s, err := board.IsUserPasswordSet(conn); err != nil {
125+
return fmt.Errorf("failed to check if user password is set: %w", err)
126+
} else {
127+
configured = "- Configured: " + strconv.FormatBool(s)
128+
}
129+
}
118130
case board.NetworkProtocol:
119131
address = b.Address
120132
default:
121133
panic("unreachable")
122134
}
123-
feedback.Printf("%s (%s) - Connection: %s [%s]\n", b.BoardName, b.CustomName, b.Protocol, address)
135+
136+
feedback.Printf("%s (%s) - Connection: %s [%s] %s\n", b.BoardName, b.CustomName, b.Protocol, address, configured)
124137
}
125138
return nil
126139
},

pkg/board/board.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,25 @@ func GetCustomName(ctx context.Context, conn remote.RemoteConn) (string, error)
222222
return string(bytes.TrimSpace(out)), nil
223223
}
224224

225+
func IsUserPasswordSet(conn remote.RemoteShell) (bool, error) {
226+
cmd := conn.GetCmd("chage", "-l", "arduino")
227+
228+
w, out, _, closer, err := cmd.Interactive()
229+
if err != nil {
230+
return false, fmt.Errorf("failed to check password: %w", err)
231+
}
232+
w.Close() // we don't need to write anything
233+
234+
isUserSet, err := remote.ParseChage(out)
235+
if err != nil {
236+
return false, err
237+
}
238+
if err := closer(); err != nil {
239+
return false, err
240+
}
241+
return isUserSet, nil
242+
}
243+
225244
func getSerial(conn remote.RemoteConn) (string, error) {
226245
f, err := conn.ReadFile(SerialPath)
227246
if err != nil {

pkg/board/remote/parser.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package remote
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"io"
7+
"strings"
8+
)
9+
10+
func ParseChage(r io.Reader) (bool, error) {
11+
scanner := bufio.NewScanner(r)
12+
for scanner.Scan() {
13+
line := scanner.Text()
14+
if strings.HasPrefix(line, "Last password change") {
15+
parts := strings.SplitN(line, ":", 2)
16+
if len(parts) < 2 {
17+
return false, fmt.Errorf("unexpected output from chage command: %s", line)
18+
}
19+
value := strings.TrimSpace(parts[1])
20+
return value != "password must be changed", nil
21+
}
22+
}
23+
if err := scanner.Err(); err != nil {
24+
return false, err
25+
}
26+
return false, fmt.Errorf("unexpected output from chage command")
27+
}

pkg/board/remote/parser_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package remote
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestParseChage(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
input string
15+
want bool
16+
wantErr bool
17+
}{
18+
{
19+
name: "user set",
20+
input: `
21+
Last password change : Jun 30, 2025
22+
Password expires : never
23+
Password inactive : never
24+
Account expires : never
25+
Minimum number of days between password change : 0
26+
Maximum number of days between password change : 99999
27+
Number of days of warning before password expires : 7`,
28+
want: true,
29+
},
30+
{
31+
name: "user not set",
32+
input: `
33+
Last password change : password must be changed
34+
Password expires : password must be changed
35+
Password inactive : password must be changed
36+
Account expires : never
37+
Minimum number of days between password change : 0
38+
Maximum number of days between password change : 99999
39+
Number of days of warning before password expires : 7`,
40+
want: false,
41+
},
42+
{
43+
name: "malformed input",
44+
input: `
45+
Last password change - Jun 30, 2025
46+
Password expires : never
47+
`,
48+
wantErr: true,
49+
},
50+
{
51+
name: "empty input",
52+
input: "",
53+
wantErr: true,
54+
},
55+
{
56+
name: "no relevant line",
57+
input: "something else",
58+
wantErr: true,
59+
},
60+
}
61+
62+
for _, tt := range tests {
63+
t.Run(tt.name, func(t *testing.T) {
64+
got, err := ParseChage(strings.NewReader(tt.input))
65+
if tt.wantErr {
66+
require.Error(t, err)
67+
} else {
68+
require.NoError(t, err)
69+
assert.Equal(t, tt.want, got)
70+
}
71+
})
72+
}
73+
}

0 commit comments

Comments
 (0)