| 141 | } |
| 142 | |
| 143 | func New(options Options) Agent { |
| 144 | if options.Filesystem == nil { |
| 145 | options.Filesystem = afero.NewOsFs() |
| 146 | } |
| 147 | if options.TempDir == "" { |
| 148 | options.TempDir = os.TempDir() |
| 149 | } |
| 150 | if options.LogDir == "" { |
| 151 | if options.TempDir != os.TempDir() { |
| 152 | options.Logger.Debug(context.Background(), "log dir not set, using temp dir", slog.F("temp_dir", options.TempDir)) |
| 153 | } else { |
| 154 | options.Logger.Debug(context.Background(), "using log dir", slog.F("log_dir", options.LogDir)) |
| 155 | } |
| 156 | options.LogDir = options.TempDir |
| 157 | } |
| 158 | if options.ScriptDataDir == "" { |
| 159 | if options.TempDir != os.TempDir() { |
| 160 | options.Logger.Debug(context.Background(), "script data dir not set, using temp dir", slog.F("temp_dir", options.TempDir)) |
| 161 | } else { |
| 162 | options.Logger.Debug(context.Background(), "using script data dir", slog.F("script_data_dir", options.ScriptDataDir)) |
| 163 | } |
| 164 | options.ScriptDataDir = options.TempDir |
| 165 | } |
| 166 | if options.ReportMetadataInterval == 0 { |
| 167 | options.ReportMetadataInterval = time.Second |
| 168 | } |
| 169 | if options.ServiceBannerRefreshInterval == 0 { |
| 170 | options.ServiceBannerRefreshInterval = 2 * time.Minute |
| 171 | } |
| 172 | |
| 173 | if options.Clock == nil { |
| 174 | options.Clock = quartz.NewReal() |
| 175 | } |
| 176 | |
| 177 | prometheusRegistry := options.PrometheusRegistry |
| 178 | if prometheusRegistry == nil { |
| 179 | prometheusRegistry = prometheus.NewRegistry() |
| 180 | } |
| 181 | |
| 182 | if options.Execer == nil { |
| 183 | options.Execer = agentexec.DefaultExecer |
| 184 | } |
| 185 | |
| 186 | if options.ListeningPortsGetter == nil { |
| 187 | options.ListeningPortsGetter = &osListeningPortsGetter{ |
| 188 | cacheDuration: 1 * time.Second, |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | hardCtx, hardCancel := context.WithCancel(context.Background()) |
| 193 | gracefulCtx, gracefulCancel := context.WithCancel(hardCtx) |
| 194 | a := &agent{ |
| 195 | clock: options.Clock, |
| 196 | tailnetListenPort: options.TailnetListenPort, |
| 197 | reconnectingPTYTimeout: options.ReconnectingPTYTimeout, |
| 198 | logger: options.Logger, |
| 199 | gracefulCtx: gracefulCtx, |
| 200 | gracefulCancel: gracefulCancel, |